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