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