omap4: l2x0: enable instruction and data prefetching
[pandora-kernel.git] / drivers / staging / winbond / wbusb.c
1 /*
2  * Copyright 2008 Pavel Machek <pavel@ucw.cz>
3  *
4  * Distribute under GPLv2.
5  *
6  * The original driver was written by:
7  *     Jeff Lee <YY_Lee@issc.com.tw>
8  *
9  * and was adapted to the 2.6 kernel by:
10  *     Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>
11  */
12 #include <net/mac80211.h>
13 #include <linux/usb.h>
14
15 #include "core.h"
16 #include "mds_f.h"
17 #include "mlmetxrx_f.h"
18 #include "mto.h"
19 #include "wbhal_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         if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
125                 priv->sMlmeFrame.wNumTxMMPDUDiscarded++;
126                 return NETDEV_TX_BUSY;
127         }
128
129         priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
130
131         priv->sMlmeFrame.pMMPDU         = skb->data;
132         priv->sMlmeFrame.DataType       = FRAME_TYPE_802_11_MANAGEMENT;
133         priv->sMlmeFrame.len            = skb->len;
134         priv->sMlmeFrame.wNumTxMMPDU++;
135
136         /*
137          * H/W will enter power save by set the register. S/W don't send null
138          * frame with PWRMgt bit enbled to enter power save now.
139          */
140
141         Mds_Tx(priv);
142
143         return NETDEV_TX_OK;
144 }
145
146 static int wbsoft_start(struct ieee80211_hw *dev)
147 {
148         struct wbsoft_priv *priv = dev->priv;
149
150         priv->enabled = true;
151
152         return 0;
153 }
154
155 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
156 {
157         struct wb35_reg *reg = &pHwData->reg;
158
159         if (pHwData->SurpriseRemove)
160                 return;
161
162         if (radio_off) {        /* disable Baseband receive off */
163                 pHwData->CurrentRadioSw = 1;    /* off */
164                 reg->M24_MacControl &= 0xffffffbf;
165         } else {
166                 pHwData->CurrentRadioSw = 0;    /* on */
167                 reg->M24_MacControl |= 0x00000040;
168         }
169         Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
170 }
171
172 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
173 {
174         struct wb35_reg *reg = &pHwData->reg;
175
176         if (pHwData->SurpriseRemove)
177                 return;
178
179         printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
180
181         RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */
182         pHwData->Channel = channel.ChanNo;
183         pHwData->band = channel.band;
184 #ifdef _PE_STATE_DUMP_
185         printk("Set channel is %d, band =%d\n", pHwData->Channel,
186                pHwData->band);
187 #endif
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                 /* Active send null packet to avoid AP disconnect */
613                 if (pHwData->LED_LinkOn) {
614                         pHwData->NullPacketCount += TimeInterval;
615                         if (pHwData->NullPacketCount >=
616                             DEFAULT_NULL_PACKET_COUNT) {
617                                 pHwData->NullPacketCount = 0;
618                         }
619                 }
620         }
621
622         pHwData->time_count += TimeInterval;
623         Wb35Tx_CurrentTime(adapter, pHwData->time_count);
624         pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
625         add_timer(&pHwData->LEDTimer);
626 }
627
628 static int hal_init_hardware(struct ieee80211_hw *hw)
629 {
630         struct wbsoft_priv *priv = hw->priv;
631         struct hw_data *pHwData = &priv->sHwData;
632         u16 SoftwareSet;
633
634         pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
635         pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
636
637         if (!Wb35Reg_initial(pHwData))
638                 goto error_reg_destroy;
639
640         if (!Wb35Tx_initial(pHwData))
641                 goto error_tx_destroy;
642
643         if (!Wb35Rx_initial(pHwData))
644                 goto error_rx_destroy;
645
646         init_timer(&pHwData->LEDTimer);
647         pHwData->LEDTimer.function = hal_led_control;
648         pHwData->LEDTimer.data = (unsigned long)priv;
649         pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
650         add_timer(&pHwData->LEDTimer);
651
652         SoftwareSet = hal_software_set(pHwData);
653
654 #ifdef Vendor2
655         /* Try to make sure the EEPROM contain */
656         SoftwareSet >>= 8;
657         if (SoftwareSet != 0x82)
658                 return false;
659 #endif
660
661         Wb35Rx_start(hw);
662         Wb35Tx_EP2VM_start(priv);
663
664         return 0;
665
666 error_rx_destroy:
667         Wb35Rx_destroy(pHwData);
668 error_tx_destroy:
669         Wb35Tx_destroy(pHwData);
670 error_reg_destroy:
671         Wb35Reg_destroy(pHwData);
672
673         pHwData->SurpriseRemove = 1;
674         return -EINVAL;
675 }
676
677 static int wb35_hw_init(struct ieee80211_hw *hw)
678 {
679         struct wbsoft_priv *priv = hw->priv;
680         struct hw_data *pHwData = &priv->sHwData;
681         u8 EEPROM_region;
682         u8 HwRadioOff;
683         u8 *pMacAddr2;
684         u8 *pMacAddr;
685         int err;
686
687         pHwData->phy_type = RF_DECIDE_BY_INF;
688
689         priv->Mds.TxRTSThreshold                = DEFAULT_RTSThreshold;
690         priv->Mds.TxFragmentThreshold           = DEFAULT_FRAGMENT_THRESHOLD;
691
692         priv->sLocalPara.region_INF             = REGION_AUTO;
693         priv->sLocalPara.TxRateMode             = RATE_AUTO;
694         priv->sLocalPara.bMacOperationMode      = MODE_802_11_BG;
695         priv->sLocalPara.MTUsize                = MAX_ETHERNET_PACKET_SIZE;
696         priv->sLocalPara.bPreambleMode          = AUTO_MODE;
697         priv->sLocalPara.bWepKeyError           = false;
698         priv->sLocalPara.bToSelfPacketReceived  = false;
699         priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
700
701         priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
702
703         err = hal_init_hardware(hw);
704         if (err)
705                 goto error;
706
707         EEPROM_region = hal_get_region_from_EEPROM(pHwData);
708         if (EEPROM_region != REGION_AUTO)
709                 priv->sLocalPara.region = EEPROM_region;
710         else {
711                 if (priv->sLocalPara.region_INF != REGION_AUTO)
712                         priv->sLocalPara.region = priv->sLocalPara.region_INF;
713                 else
714                         priv->sLocalPara.region = REGION_USA;   /* default setting */
715         }
716
717         Mds_initial(priv);
718
719         /*
720          * If no user-defined address in the registry, use the address
721          * "burned" on the NIC instead.
722          */
723         pMacAddr = priv->sLocalPara.ThisMacAddress;
724         pMacAddr2 = priv->sLocalPara.PermanentAddress;
725
726         /* Reading ethernet address from EEPROM */
727         hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
728         if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
729                 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
730         else {
731                 /* Set the user define MAC address */
732                 hal_set_ethernet_address(pHwData,
733                                          priv->sLocalPara.ThisMacAddress);
734         }
735
736         priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
737 #ifdef _PE_STATE_DUMP_
738         printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
739 #endif
740         hal_get_hw_radio_off(pHwData);
741
742         /* Waiting for HAL setting OK */
743         while (!hal_idle(pHwData))
744                 msleep(10);
745
746         MTO_Init(priv);
747
748         HwRadioOff = hal_get_hw_radio_off(pHwData);
749         priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
750
751         hal_set_radio_mode(pHwData,
752                            (unsigned char)(priv->sLocalPara.RadioOffStatus.
753                                            boSwRadioOff
754                                            || priv->sLocalPara.RadioOffStatus.
755                                            boHwRadioOff));
756
757         /* Notify hal that the driver is ready now. */
758         hal_driver_init_OK(pHwData) = 1;
759
760 error:
761         return err;
762 }
763
764 static int wb35_probe(struct usb_interface *intf,
765                       const struct usb_device_id *id_table)
766 {
767         struct usb_device *udev = interface_to_usbdev(intf);
768         struct usb_endpoint_descriptor *endpoint;
769         struct usb_host_interface *interface;
770         struct ieee80211_hw *dev;
771         struct wbsoft_priv *priv;
772         struct wb_usb *pWbUsb;
773         int nr, err;
774         u32 ltmp;
775
776         usb_get_dev(udev);
777
778         /* Check the device if it already be opened */
779         nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
780                              0x01,
781                              USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
782                              0x0, 0x400, &ltmp, 4, HZ * 100);
783         if (nr < 0) {
784                 err = nr;
785                 goto error;
786         }
787
788         /* Is already initialized? */
789         ltmp = cpu_to_le32(ltmp);
790         if (ltmp) {
791                 err = -EBUSY;
792                 goto error;
793         }
794
795         dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
796         if (!dev) {
797                 err = -ENOMEM;
798                 goto error;
799         }
800
801         priv = dev->priv;
802
803         pWbUsb = &priv->sHwData.WbUsb;
804         pWbUsb->udev = udev;
805
806         interface = intf->cur_altsetting;
807         endpoint = &interface->endpoint[0].desc;
808
809         if (endpoint[2].wMaxPacketSize == 512) {
810                 printk("[w35und] Working on USB 2.0\n");
811                 pWbUsb->IsUsb20 = 1;
812         }
813
814         err = wb35_hw_init(dev);
815         if (err)
816                 goto error_free_hw;
817
818         SET_IEEE80211_DEV(dev, &udev->dev);
819         {
820                 struct hw_data *pHwData = &priv->sHwData;
821                 unsigned char dev_addr[MAX_ADDR_LEN];
822                 hal_get_permanent_address(pHwData, dev_addr);
823                 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
824         }
825
826         dev->extra_tx_headroom = 12;    /* FIXME */
827         dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
828         dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
829
830         dev->channel_change_time = 1000;
831         dev->max_signal = 100;
832         dev->queues = 1;
833
834         dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
835
836         err = ieee80211_register_hw(dev);
837         if (err)
838                 goto error_free_hw;
839
840         usb_set_intfdata(intf, dev);
841
842         return 0;
843
844 error_free_hw:
845         ieee80211_free_hw(dev);
846 error:
847         usb_put_dev(udev);
848         return err;
849 }
850
851 static void hal_halt(struct hw_data *pHwData)
852 {
853         del_timer_sync(&pHwData->LEDTimer);
854         /* XXX: Wait for Timer DPC exit. */
855         msleep(100);
856         Wb35Rx_destroy(pHwData);
857         Wb35Tx_destroy(pHwData);
858         Wb35Reg_destroy(pHwData);
859 }
860
861 static void wb35_hw_halt(struct wbsoft_priv *adapter)
862 {
863         Mds_Destroy(adapter);
864
865         /* Turn off Rx and Tx hardware ability */
866         hal_stop(&adapter->sHwData);
867 #ifdef _PE_USB_INI_DUMP_
868         printk("[w35und] Hal_stop O.K.\n");
869 #endif
870         /* Waiting Irp completed */
871         msleep(100);
872
873         hal_halt(&adapter->sHwData);
874 }
875
876 static void wb35_disconnect(struct usb_interface *intf)
877 {
878         struct ieee80211_hw *hw = usb_get_intfdata(intf);
879         struct wbsoft_priv *priv = hw->priv;
880
881         wb35_hw_halt(priv);
882
883         ieee80211_stop_queues(hw);
884         ieee80211_unregister_hw(hw);
885         ieee80211_free_hw(hw);
886
887         usb_set_intfdata(intf, NULL);
888         usb_put_dev(interface_to_usbdev(intf));
889 }
890
891 static struct usb_driver wb35_driver = {
892         .name           = "w35und",
893         .id_table       = wb35_table,
894         .probe          = wb35_probe,
895         .disconnect     = wb35_disconnect,
896 };
897
898 static int __init wb35_init(void)
899 {
900         return usb_register(&wb35_driver);
901 }
902
903 static void __exit wb35_exit(void)
904 {
905         usb_deregister(&wb35_driver);
906 }
907
908 module_init(wb35_init);
909 module_exit(wb35_exit);