rk: revert 20f3d0b+v3.0.66 to v3.0
[firefly-linux-kernel-4.4.55.git] / drivers / staging / winbond / wbusb.c
1 /*
2  * Copyright 2008 Pavel Machek <pavel@ucw.cz>
3  *
4  * Distribute under GPLv2.
5  *
6  * The original driver was written by:
7  *     Jeff Lee <YY_Lee@issc.com.tw>
8  *
9  * and was adapted to the 2.6 kernel by:
10  *     Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>
11  */
12 #include <net/mac80211.h>
13 #include <linux/usb.h>
14
15 #include "core.h"
16 #include "mds_f.h"
17 #include "mto.h"
18 #include "wbhal.h"
19 #include "wb35reg_f.h"
20 #include "wb35tx_f.h"
21 #include "wb35rx_f.h"
22
23 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
24 MODULE_LICENSE("GPL");
25 MODULE_VERSION("0.1");
26
27 static const struct usb_device_id wb35_table[] __devinitconst = {
28         { USB_DEVICE(0x0416, 0x0035) },
29         { USB_DEVICE(0x18E8, 0x6201) },
30         { USB_DEVICE(0x18E8, 0x6206) },
31         { USB_DEVICE(0x18E8, 0x6217) },
32         { USB_DEVICE(0x18E8, 0x6230) },
33         { USB_DEVICE(0x18E8, 0x6233) },
34         { USB_DEVICE(0x1131, 0x2035) },
35         { 0, }
36 };
37
38 MODULE_DEVICE_TABLE(usb, wb35_table);
39
40 static struct ieee80211_rate wbsoft_rates[] = {
41         { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
42 };
43
44 static struct ieee80211_channel wbsoft_channels[] = {
45         { .center_freq = 2412 },
46 };
47
48 static struct ieee80211_supported_band wbsoft_band_2GHz = {
49         .channels       = wbsoft_channels,
50         .n_channels     = ARRAY_SIZE(wbsoft_channels),
51         .bitrates       = wbsoft_rates,
52         .n_bitrates     = ARRAY_SIZE(wbsoft_rates),
53 };
54
55 static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
56 {
57         u32 tmp;
58
59         if (pHwData->SurpriseRemove)
60                 return;
61
62         pHwData->BeaconPeriod = beacon_period;
63         tmp = pHwData->BeaconPeriod << 16;
64         tmp |= pHwData->ProbeDelay;
65         Wb35Reg_Write(pHwData, 0x0848, tmp);
66 }
67
68 static int wbsoft_add_interface(struct ieee80211_hw *dev,
69                                 struct ieee80211_vif *vif)
70 {
71         struct wbsoft_priv *priv = dev->priv;
72
73         hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
74
75         return 0;
76 }
77
78 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
79                                     struct ieee80211_vif *vif)
80 {
81         printk("wbsoft_remove interface called\n");
82 }
83
84 static void wbsoft_stop(struct ieee80211_hw *hw)
85 {
86         printk(KERN_INFO "%s called\n", __func__);
87 }
88
89 static int wbsoft_get_stats(struct ieee80211_hw *hw,
90                             struct ieee80211_low_level_stats *stats)
91 {
92         printk(KERN_INFO "%s called\n", __func__);
93         return 0;
94 }
95
96 static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw,
97                                     struct netdev_hw_addr_list *mc_list)
98 {
99         return netdev_hw_addr_list_count(mc_list);
100 }
101
102 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
103                                     unsigned int changed_flags,
104                                     unsigned int *total_flags,
105                                     u64 multicast)
106 {
107         unsigned int new_flags;
108
109         new_flags = 0;
110
111         if (*total_flags & FIF_PROMISC_IN_BSS)
112                 new_flags |= FIF_PROMISC_IN_BSS;
113         else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32))
114                 new_flags |= FIF_ALLMULTI;
115
116         dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
117
118         *total_flags = new_flags;
119 }
120
121 static void wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
122 {
123         struct wbsoft_priv *priv = dev->priv;
124
125         if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
126                 priv->sMlmeFrame.wNumTxMMPDUDiscarded++;
127                 kfree_skb(skb);
128                 return;
129         }
130
131         priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
132
133         priv->sMlmeFrame.pMMPDU         = skb->data;
134         priv->sMlmeFrame.DataType       = FRAME_TYPE_802_11_MANAGEMENT;
135         priv->sMlmeFrame.len            = skb->len;
136         priv->sMlmeFrame.wNumTxMMPDU++;
137
138         /*
139          * H/W will enter power save by set the register. S/W don't send null
140          * frame with PWRMgt bit enbled to enter power save now.
141          */
142
143         Mds_Tx(priv);
144 }
145
146 static int wbsoft_start(struct ieee80211_hw *dev)
147 {
148         struct wbsoft_priv *priv = dev->priv;
149
150         priv->enabled = true;
151
152         return 0;
153 }
154
155 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
156 {
157         struct wb35_reg *reg = &pHwData->reg;
158
159         if (pHwData->SurpriseRemove)
160                 return;
161
162         if (radio_off) {        /* disable Baseband receive off */
163                 pHwData->CurrentRadioSw = 1;    /* off */
164                 reg->M24_MacControl &= 0xffffffbf;
165         } else {
166                 pHwData->CurrentRadioSw = 0;    /* on */
167                 reg->M24_MacControl |= 0x00000040;
168         }
169         Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
170 }
171
172 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
173 {
174         struct wb35_reg *reg = &pHwData->reg;
175
176         if (pHwData->SurpriseRemove)
177                 return;
178
179         printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
180
181         RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */
182         pHwData->Channel = channel.ChanNo;
183         pHwData->band = channel.band;
184         pr_debug("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
185         reg->M28_MacControl &= ~0xff;   /* Clean channel information field */
186         reg->M28_MacControl |= channel.ChanNo;
187         Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
188                                        (s8 *) &channel,
189                                        sizeof(struct chan_info));
190 }
191
192 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
193 {
194         hal_set_current_channel_ex(pHwData, channel);
195 }
196
197 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
198 {
199         struct wb35_reg *reg = &pHwData->reg;
200
201         if (pHwData->SurpriseRemove)
202                 return;
203
204         reg->M00_MacControl &= ~0x02000000;     /* The HW value */
205
206         if (enable)
207                 reg->M00_MacControl |= 0x02000000;      /* The HW value */
208
209         Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
210 }
211
212 /* For wep key error detection, we need to accept broadcast packets to be received temporary. */
213 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
214 {
215         struct wb35_reg *reg = &pHwData->reg;
216
217         if (pHwData->SurpriseRemove)
218                 return;
219
220         if (enable) {
221                 reg->M00_MacControl |= 0x00400000;
222                 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
223         } else {
224                 reg->M00_MacControl &= ~0x00400000;
225                 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
226         }
227 }
228
229 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
230 {
231         struct wb35_reg *reg = &pHwData->reg;
232
233         if (pHwData->SurpriseRemove)
234                 return;
235
236         reg->M00_MacControl &= ~0x01000000;     /* The HW value */
237         if (enable)
238                 reg->M00_MacControl |= 0x01000000;      /* The HW value */
239         Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
240 }
241
242 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
243 {
244         struct wb35_reg *reg = &pHwData->reg;
245
246         if (pHwData->SurpriseRemove)
247                 return;
248
249         if (!enable)    /* Due to SME and MLME are not suitable for 35 */
250                 return;
251
252         reg->M00_MacControl &= ~0x04000000;     /* The HW value */
253         if (enable)
254                 reg->M00_MacControl |= 0x04000000;      /* The HW value */
255
256         Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
257 }
258
259 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
260 {
261         struct wbsoft_priv *priv = dev->priv;
262         struct chan_info ch;
263
264         printk("wbsoft_config called\n");
265
266         /* Should use channel_num, or something, as that is already pre-translated */
267         ch.band = 1;
268         ch.ChanNo = 1;
269
270         hal_set_current_channel(&priv->sHwData, ch);
271         hal_set_accept_broadcast(&priv->sHwData, 1);
272         hal_set_accept_promiscuous(&priv->sHwData, 1);
273         hal_set_accept_multicast(&priv->sHwData, 1);
274         hal_set_accept_beacon(&priv->sHwData, 1);
275         hal_set_radio_mode(&priv->sHwData, 0);
276
277         return 0;
278 }
279
280 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
281 {
282         printk("wbsoft_get_tsf called\n");
283         return 0;
284 }
285
286 static const struct ieee80211_ops wbsoft_ops = {
287         .tx                     = wbsoft_tx,
288         .start                  = wbsoft_start,
289         .stop                   = wbsoft_stop,
290         .add_interface          = wbsoft_add_interface,
291         .remove_interface       = wbsoft_remove_interface,
292         .config                 = wbsoft_config,
293         .prepare_multicast      = wbsoft_prepare_multicast,
294         .configure_filter       = wbsoft_configure_filter,
295         .get_stats              = wbsoft_get_stats,
296         .get_tsf                = wbsoft_get_tsf,
297 };
298
299 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
300 {
301         u32 ltmp[2];
302
303         if (pHwData->SurpriseRemove)
304                 return;
305
306         memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
307
308         ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
309         ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
310
311         Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
312 }
313
314 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
315 {
316         if (pHwData->SurpriseRemove)
317                 return;
318
319         memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
320 }
321
322 static void hal_stop(struct hw_data *pHwData)
323 {
324         struct wb35_reg *reg = &pHwData->reg;
325
326         pHwData->Wb35Rx.rx_halt = 1;
327         Wb35Rx_stop(pHwData);
328
329         pHwData->Wb35Tx.tx_halt = 1;
330         Wb35Tx_stop(pHwData);
331
332         reg->D00_DmaControl &= ~0xc0000000;     /* Tx Off, Rx Off */
333         Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
334 }
335
336 static unsigned char hal_idle(struct hw_data *pHwData)
337 {
338         struct wb35_reg *reg = &pHwData->reg;
339
340         if (!pHwData->SurpriseRemove && reg->EP0vm_state != VM_STOP)
341                 return false;
342
343         return true;
344 }
345
346 u8 hal_get_antenna_number(struct hw_data *pHwData)
347 {
348         struct wb35_reg *reg = &pHwData->reg;
349
350         if ((reg->BB2C & BIT(11)) == 0)
351                 return 0;
352         else
353                 return 1;
354 }
355
356 /* 0 : radio on; 1: radio off */
357 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
358 {
359         struct wb35_reg *reg = &pHwData->reg;
360
361         if (pHwData->SurpriseRemove)
362                 return 1;
363
364         /* read the bit16 of register U1B0 */
365         Wb35Reg_Read(pHwData, 0x3b0, &reg->U1B0);
366         if ((reg->U1B0 & 0x00010000)) {
367                 pHwData->CurrentRadioHw = 1;
368                 return 1;
369         } else {
370                 pHwData->CurrentRadioHw = 0;
371                 return 0;
372         }
373 }
374
375 static u8 LED_GRAY[20] = {
376         0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
377 };
378
379 static u8 LED_GRAY2[30] = {
380         7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
381         0, 15, 14, 13, 12, 11, 10, 9, 8
382 };
383
384 static void hal_led_control(unsigned long data)
385 {
386         struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
387         struct hw_data *pHwData = &adapter->sHwData;
388         struct wb35_reg *reg = &pHwData->reg;
389         u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
390         u32 TimeInterval = 500, ltmp, ltmp2;
391         ltmp = 0;
392
393         if (pHwData->SurpriseRemove)
394                 return;
395
396         if (pHwData->LED_control) {
397                 ltmp2 = pHwData->LED_control & 0xff;
398                 if (ltmp2 == 5) { /* 5 is WPS mode */
399                         TimeInterval = 100;
400                         ltmp2 = (pHwData->LED_control >> 8) & 0xff;
401                         switch (ltmp2) {
402                         case 1: /* [0.2 On][0.1 Off]... */
403                                 pHwData->LED_Blinking %= 3;
404                                 ltmp = 0x1010;  /* Led 1 & 0 Green and Red */
405                                 if (pHwData->LED_Blinking == 2) /* Turn off */
406                                         ltmp = 0;
407                                 break;
408                         case 2: /* [0.1 On][0.1 Off]... */
409                                 pHwData->LED_Blinking %= 2;
410                                 ltmp = 0x0010;  /* Led 0 red color */
411                                 if (pHwData->LED_Blinking) /* Turn off */
412                                         ltmp = 0;
413                                 break;
414                         case 3: /* [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]... */
415                                 pHwData->LED_Blinking %= 15;
416                                 ltmp = 0x0010;  /* Led 0 red color */
417                                 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) /* Turn off 0.6 sec */
418                                         ltmp = 0;
419                                 break;
420                         case 4: /* [300 On][ off ] */
421                                 ltmp = 0x1000;  /* Led 1 Green color */
422                                 if (pHwData->LED_Blinking >= 3000)
423                                         ltmp = 0; /* led maybe on after 300sec * 32bit counter overlap. */
424                                 break;
425                         }
426                         pHwData->LED_Blinking++;
427
428                         reg->U1BC_LEDConfigure = ltmp;
429                         if (LEDSet != 7) { /* Only 111 mode has 2 LEDs on PCB. */
430                                 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; /* Copy LED result to each LED control register */
431                                 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
432                         }
433                         Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
434                 }
435         } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) { /* If radio off */
436                 if (reg->U1BC_LEDConfigure & 0x1010) {
437                         reg->U1BC_LEDConfigure &= ~0x1010;
438                         Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
439                 }
440         } else {
441                 switch (LEDSet) {
442                 case 4: /* [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
443                         if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
444                                 /* Blinking if scanning is on progress */
445                                 if (pHwData->LED_Scanning) {
446                                         if (pHwData->LED_Blinking == 0) {
447                                                 reg->U1BC_LEDConfigure |= 0x10;
448                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
449                                                 pHwData->LED_Blinking = 1;
450                                                 TimeInterval = 300;
451                                         } else {
452                                                 reg->U1BC_LEDConfigure &= ~0x10;
453                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
454                                                 pHwData->LED_Blinking = 0;
455                                                 TimeInterval = 300;
456                                         }
457                                 } else {
458                                         /* Turn Off LED_0 */
459                                         if (reg->U1BC_LEDConfigure & 0x10) {
460                                                 reg->U1BC_LEDConfigure &= ~0x10;
461                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
462                                         }
463                                 }
464                         } else {
465                                 /* Turn On LED_0 */
466                                 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
467                                         reg->U1BC_LEDConfigure |= 0x10;
468                                         Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
469                                 }
470                         }
471                         break;
472                 case 6: /* [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
473                         if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
474                                 /* Blinking if scanning is on progress */
475                                 if (pHwData->LED_Scanning) {
476                                         if (pHwData->LED_Blinking == 0) {
477                                                 reg->U1BC_LEDConfigure &= ~0xf;
478                                                 reg->U1BC_LEDConfigure |= 0x10;
479                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
480                                                 pHwData->LED_Blinking = 1;
481                                                 TimeInterval = 300;
482                                         } else {
483                                                 reg->U1BC_LEDConfigure &= ~0x1f;
484                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
485                                                 pHwData->LED_Blinking = 0;
486                                                 TimeInterval = 300;
487                                         }
488                                 } else {
489                                         /* Gray blinking if in disconnect state and not scanning */
490                                         ltmp = reg->U1BC_LEDConfigure;
491                                         reg->U1BC_LEDConfigure &= ~0x1f;
492                                         if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
493                                                 reg->U1BC_LEDConfigure |= 0x10;
494                                                 reg->U1BC_LEDConfigure |=
495                                                     LED_GRAY2[(pHwData->LED_Blinking % 30)];
496                                         }
497                                         pHwData->LED_Blinking++;
498                                         if (reg->U1BC_LEDConfigure != ltmp)
499                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
500                                         TimeInterval = 100;
501                                 }
502                         } else {
503                                 /* Turn On LED_0 */
504                                 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
505                                         reg->U1BC_LEDConfigure |= 0x10;
506                                         Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
507                                 }
508                         }
509                         break;
510                 case 5: /* [101] Only 1 Led be placed on PCB and use LED_1 for showing */
511                         if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
512                                 /* Blinking if scanning is on progress */
513                                 if (pHwData->LED_Scanning) {
514                                         if (pHwData->LED_Blinking == 0) {
515                                                 reg->U1BC_LEDConfigure |= 0x1000;
516                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
517                                                 pHwData->LED_Blinking = 1;
518                                                 TimeInterval = 300;
519                                         } else {
520                                                 reg->U1BC_LEDConfigure &= ~0x1000;
521                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
522                                                 pHwData->LED_Blinking = 0;
523                                                 TimeInterval = 300;
524                                         }
525                                 } else {
526                                         /* Turn Off LED_1 */
527                                         if (reg->U1BC_LEDConfigure & 0x1000) {
528                                                 reg->U1BC_LEDConfigure &= ~0x1000;
529                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
530                                         }
531                                 }
532                         } else {
533                                 /* Is transmitting/receiving ?? */
534                                 if ((adapter->RxByteCount !=
535                                      pHwData->RxByteCountLast)
536                                     || (adapter->TxByteCount !=
537                                         pHwData->TxByteCountLast)) {
538                                         if ((reg->U1BC_LEDConfigure & 0x3000) !=
539                                             0x3000) {
540                                                 reg->U1BC_LEDConfigure |= 0x3000;
541                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
542                                         }
543                                         /* Update variable */
544                                         pHwData->RxByteCountLast =
545                                             adapter->RxByteCount;
546                                         pHwData->TxByteCountLast =
547                                             adapter->TxByteCount;
548                                         TimeInterval = 200;
549                                 } else {
550                                         /* Turn On LED_1 and blinking if transmitting/receiving */
551                                         if ((reg->U1BC_LEDConfigure & 0x3000) !=
552                                             0x1000) {
553                                                 reg->U1BC_LEDConfigure &=
554                                                     ~0x3000;
555                                                 reg->U1BC_LEDConfigure |=
556                                                     0x1000;
557                                                 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
558                                         }
559                                 }
560                         }
561                         break;
562                 default: /* Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active */
563                         if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
564                                 reg->U1BC_LEDConfigure |= 0x3000;       /* LED_1 is always on and event enable */
565                                 Wb35Reg_Write(pHwData, 0x03bc,
566                                               reg->U1BC_LEDConfigure);
567                         }
568
569                         if (pHwData->LED_Blinking) {
570                                 /* Gray blinking */
571                                 reg->U1BC_LEDConfigure &= ~0x0f;
572                                 reg->U1BC_LEDConfigure |= 0x10;
573                                 reg->U1BC_LEDConfigure |=
574                                     LED_GRAY[(pHwData->LED_Blinking - 1) % 20];
575                                 Wb35Reg_Write(pHwData, 0x03bc,
576                                               reg->U1BC_LEDConfigure);
577
578                                 pHwData->LED_Blinking += 2;
579                                 if (pHwData->LED_Blinking < 40)
580                                         TimeInterval = 100;
581                                 else {
582                                         pHwData->LED_Blinking = 0; /* Stop blinking */
583                                         reg->U1BC_LEDConfigure &= ~0x0f;
584                                         Wb35Reg_Write(pHwData, 0x03bc,
585                                                       reg->U1BC_LEDConfigure);
586                                 }
587                                 break;
588                         }
589
590                         if (pHwData->LED_LinkOn) {
591                                 if (!(reg->U1BC_LEDConfigure & 0x10)) { /* Check the LED_0 */
592                                         /* Try to turn ON LED_0 after gray blinking */
593                                         reg->U1BC_LEDConfigure |= 0x10;
594                                         pHwData->LED_Blinking = 1; /* Start blinking */
595                                         TimeInterval = 50;
596                                 }
597                         } else {
598                                 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
599                                         reg->U1BC_LEDConfigure &= ~0x10;
600                                         Wb35Reg_Write(pHwData, 0x03bc,
601                                                       reg->U1BC_LEDConfigure);
602                                 }
603                         }
604                         break;
605                 }
606         }
607
608         pHwData->time_count += TimeInterval;
609         Wb35Tx_CurrentTime(adapter, pHwData->time_count);
610         pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
611         add_timer(&pHwData->LEDTimer);
612 }
613
614 static int hal_init_hardware(struct ieee80211_hw *hw)
615 {
616         struct wbsoft_priv *priv = hw->priv;
617         struct hw_data *pHwData = &priv->sHwData;
618         u16 SoftwareSet;
619
620         pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
621         pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
622
623         if (!Wb35Reg_initial(pHwData))
624                 goto error_reg_destroy;
625
626         if (!Wb35Tx_initial(pHwData))
627                 goto error_tx_destroy;
628
629         if (!Wb35Rx_initial(pHwData))
630                 goto error_rx_destroy;
631
632         init_timer(&pHwData->LEDTimer);
633         pHwData->LEDTimer.function = hal_led_control;
634         pHwData->LEDTimer.data = (unsigned long)priv;
635         pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
636         add_timer(&pHwData->LEDTimer);
637
638         SoftwareSet = hal_software_set(pHwData);
639
640         Wb35Rx_start(hw);
641         Wb35Tx_EP2VM_start(priv);
642
643         return 0;
644
645 error_rx_destroy:
646         Wb35Rx_destroy(pHwData);
647 error_tx_destroy:
648         Wb35Tx_destroy(pHwData);
649 error_reg_destroy:
650         Wb35Reg_destroy(pHwData);
651
652         pHwData->SurpriseRemove = 1;
653         return -EINVAL;
654 }
655
656 static int wb35_hw_init(struct ieee80211_hw *hw)
657 {
658         struct wbsoft_priv *priv = hw->priv;
659         struct hw_data *pHwData = &priv->sHwData;
660         u8 EEPROM_region;
661         u8 HwRadioOff;
662         u8 *pMacAddr2;
663         u8 *pMacAddr;
664         int err;
665
666         pHwData->phy_type = RF_DECIDE_BY_INF;
667
668         priv->Mds.TxRTSThreshold                = DEFAULT_RTSThreshold;
669         priv->Mds.TxFragmentThreshold           = DEFAULT_FRAGMENT_THRESHOLD;
670
671         priv->sLocalPara.region_INF             = REGION_AUTO;
672         priv->sLocalPara.TxRateMode             = RATE_AUTO;
673         priv->sLocalPara.bMacOperationMode      = MODE_802_11_BG;
674         priv->sLocalPara.MTUsize                = MAX_ETHERNET_PACKET_SIZE;
675         priv->sLocalPara.bPreambleMode          = AUTO_MODE;
676         priv->sLocalPara.bWepKeyError           = false;
677         priv->sLocalPara.bToSelfPacketReceived  = false;
678         priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
679
680         priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
681
682         err = hal_init_hardware(hw);
683         if (err)
684                 goto error;
685
686         EEPROM_region = hal_get_region_from_EEPROM(pHwData);
687         if (EEPROM_region != REGION_AUTO)
688                 priv->sLocalPara.region = EEPROM_region;
689         else {
690                 if (priv->sLocalPara.region_INF != REGION_AUTO)
691                         priv->sLocalPara.region = priv->sLocalPara.region_INF;
692                 else
693                         priv->sLocalPara.region = REGION_USA;   /* default setting */
694         }
695
696         Mds_initial(priv);
697
698         /*
699          * If no user-defined address in the registry, use the address
700          * "burned" on the NIC instead.
701          */
702         pMacAddr = priv->sLocalPara.ThisMacAddress;
703         pMacAddr2 = priv->sLocalPara.PermanentAddress;
704
705         /* Reading ethernet address from EEPROM */
706         hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
707         if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
708                 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
709         else {
710                 /* Set the user define MAC address */
711                 hal_set_ethernet_address(pHwData,
712                                          priv->sLocalPara.ThisMacAddress);
713         }
714
715         priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
716         pr_debug("Driver init, antenna no = %d\n", priv->sLocalPara.bAntennaNo);
717         hal_get_hw_radio_off(pHwData);
718
719         /* Waiting for HAL setting OK */
720         while (!hal_idle(pHwData))
721                 msleep(10);
722
723         MTO_Init(priv);
724
725         HwRadioOff = hal_get_hw_radio_off(pHwData);
726         priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
727
728         hal_set_radio_mode(pHwData,
729                            (unsigned char)(priv->sLocalPara.RadioOffStatus.
730                                            boSwRadioOff
731                                            || priv->sLocalPara.RadioOffStatus.
732                                            boHwRadioOff));
733
734         /* Notify hal that the driver is ready now. */
735         hal_driver_init_OK(pHwData) = 1;
736
737 error:
738         return err;
739 }
740
741 static int wb35_probe(struct usb_interface *intf,
742                       const struct usb_device_id *id_table)
743 {
744         struct usb_device *udev = interface_to_usbdev(intf);
745         struct usb_endpoint_descriptor *endpoint;
746         struct usb_host_interface *interface;
747         struct ieee80211_hw *dev;
748         struct wbsoft_priv *priv;
749         int nr, err;
750         u32 ltmp;
751
752         usb_get_dev(udev);
753
754         /* Check the device if it already be opened */
755         nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
756                              0x01,
757                              USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
758                              0x0, 0x400, &ltmp, 4, HZ * 100);
759         if (nr < 0) {
760                 err = nr;
761                 goto error;
762         }
763
764         /* Is already initialized? */
765         ltmp = cpu_to_le32(ltmp);
766         if (ltmp) {
767                 err = -EBUSY;
768                 goto error;
769         }
770
771         dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
772         if (!dev) {
773                 err = -ENOMEM;
774                 goto error;
775         }
776
777         priv = dev->priv;
778
779         priv->sHwData.udev = udev;
780
781         interface = intf->cur_altsetting;
782         endpoint = &interface->endpoint[0].desc;
783
784         if (endpoint[2].wMaxPacketSize == 512)
785                 printk("[w35und] Working on USB 2.0\n");
786
787         err = wb35_hw_init(dev);
788         if (err)
789                 goto error_free_hw;
790
791         SET_IEEE80211_DEV(dev, &udev->dev);
792         {
793                 struct hw_data *pHwData = &priv->sHwData;
794                 unsigned char dev_addr[MAX_ADDR_LEN];
795                 hal_get_permanent_address(pHwData, dev_addr);
796                 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
797         }
798
799         dev->extra_tx_headroom = 12;    /* FIXME */
800         dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
801         dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
802
803         dev->channel_change_time = 1000;
804         dev->max_signal = 100;
805         dev->queues = 1;
806
807         dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
808
809         err = ieee80211_register_hw(dev);
810         if (err)
811                 goto error_free_hw;
812
813         usb_set_intfdata(intf, dev);
814
815         return 0;
816
817 error_free_hw:
818         ieee80211_free_hw(dev);
819 error:
820         usb_put_dev(udev);
821         return err;
822 }
823
824 static void hal_halt(struct hw_data *pHwData)
825 {
826         del_timer_sync(&pHwData->LEDTimer);
827         /* XXX: Wait for Timer DPC exit. */
828         msleep(100);
829         Wb35Rx_destroy(pHwData);
830         Wb35Tx_destroy(pHwData);
831         Wb35Reg_destroy(pHwData);
832 }
833
834 static void wb35_hw_halt(struct wbsoft_priv *adapter)
835 {
836         /* Turn off Rx and Tx hardware ability */
837         hal_stop(&adapter->sHwData);
838         pr_debug("[w35und] Hal_stop O.K.\n");
839         /* Waiting Irp completed */
840         msleep(100);
841
842         hal_halt(&adapter->sHwData);
843 }
844
845 static void wb35_disconnect(struct usb_interface *intf)
846 {
847         struct ieee80211_hw *hw = usb_get_intfdata(intf);
848         struct wbsoft_priv *priv = hw->priv;
849
850         wb35_hw_halt(priv);
851
852         ieee80211_stop_queues(hw);
853         ieee80211_unregister_hw(hw);
854         ieee80211_free_hw(hw);
855
856         usb_set_intfdata(intf, NULL);
857         usb_put_dev(interface_to_usbdev(intf));
858 }
859
860 static struct usb_driver wb35_driver = {
861         .name           = "w35und",
862         .id_table       = wb35_table,
863         .probe          = wb35_probe,
864         .disconnect     = wb35_disconnect,
865 };
866
867 static int __init wb35_init(void)
868 {
869         return usb_register(&wb35_driver);
870 }
871
872 static void __exit wb35_exit(void)
873 {
874         usb_deregister(&wb35_driver);
875 }
876
877 module_init(wb35_init);
878 module_exit(wb35_exit);