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