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