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