GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / winbond / wbusb.c
blob9761ff9801bf3f811e92ce561261204c42b4566d
1 /*
2 * Copyright 2008 Pavel Machek <pavel@ucw.cz>
4 * Distribute under GPLv2.
6 * The original driver was written by:
7 * Jeff Lee <YY_Lee@issc.com.tw>
9 * and was adapted to the 2.6 kernel by:
10 * Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>
12 #include <net/mac80211.h>
13 #include <linux/usb.h>
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"
22 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
23 MODULE_LICENSE("GPL");
24 MODULE_VERSION("0.1");
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, }
37 MODULE_DEVICE_TABLE(usb, wb35_table);
39 static struct ieee80211_rate wbsoft_rates[] = {
40 { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
43 static struct ieee80211_channel wbsoft_channels[] = {
44 { .center_freq = 2412 },
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),
54 static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
56 u32 tmp;
58 if (pHwData->SurpriseRemove)
59 return;
61 pHwData->BeaconPeriod = beacon_period;
62 tmp = pHwData->BeaconPeriod << 16;
63 tmp |= pHwData->ProbeDelay;
64 Wb35Reg_Write(pHwData, 0x0848, tmp);
67 static int wbsoft_add_interface(struct ieee80211_hw *dev,
68 struct ieee80211_vif *vif)
70 struct wbsoft_priv *priv = dev->priv;
72 hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
74 return 0;
77 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78 struct ieee80211_vif *vif)
80 printk("wbsoft_remove interface called\n");
83 static void wbsoft_stop(struct ieee80211_hw *hw)
85 printk(KERN_INFO "%s called\n", __func__);
88 static int wbsoft_get_stats(struct ieee80211_hw *hw,
89 struct ieee80211_low_level_stats *stats)
91 printk(KERN_INFO "%s called\n", __func__);
92 return 0;
95 static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw,
96 struct netdev_hw_addr_list *mc_list)
98 return netdev_hw_addr_list_count(mc_list);
101 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
102 unsigned int changed_flags,
103 unsigned int *total_flags,
104 u64 multicast)
106 unsigned int new_flags;
108 new_flags = 0;
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;
115 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
117 *total_flags = new_flags;
120 static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
122 struct wbsoft_priv *priv = dev->priv;
124 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
126 return NETDEV_TX_OK;
129 static int wbsoft_start(struct ieee80211_hw *dev)
131 struct wbsoft_priv *priv = dev->priv;
133 priv->enabled = true;
135 return 0;
138 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
140 struct wb35_reg *reg = &pHwData->reg;
142 if (pHwData->SurpriseRemove)
143 return;
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;
152 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
155 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
157 struct wb35_reg *reg = &pHwData->reg;
159 if (pHwData->SurpriseRemove)
160 return;
162 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
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));
178 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
180 hal_set_current_channel_ex(pHwData, channel);
183 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
185 struct wb35_reg *reg = &pHwData->reg;
187 if (pHwData->SurpriseRemove)
188 return;
190 reg->M00_MacControl &= ~0x02000000; /* The HW value */
192 if (enable)
193 reg->M00_MacControl |= 0x02000000; /* The HW value */
195 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
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)
201 struct wb35_reg *reg = &pHwData->reg;
203 if (pHwData->SurpriseRemove)
204 return;
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);
215 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
217 struct wb35_reg *reg = &pHwData->reg;
219 if (pHwData->SurpriseRemove)
220 return;
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);
228 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
230 struct wb35_reg *reg = &pHwData->reg;
232 if (pHwData->SurpriseRemove)
233 return;
235 if (!enable) /* Due to SME and MLME are not suitable for 35 */
236 return;
238 reg->M00_MacControl &= ~0x04000000; /* The HW value */
239 if (enable)
240 reg->M00_MacControl |= 0x04000000; /* The HW value */
242 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
245 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
247 struct wbsoft_priv *priv = dev->priv;
248 struct chan_info ch;
250 printk("wbsoft_config called\n");
252 /* Should use channel_num, or something, as that is already pre-translated */
253 ch.band = 1;
254 ch.ChanNo = 1;
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);
263 return 0;
266 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
268 printk("wbsoft_get_tsf called\n");
269 return 0;
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,
285 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
287 u32 ltmp[2];
289 if (pHwData->SurpriseRemove)
290 return;
292 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
294 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
295 ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
297 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
300 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
302 if (pHwData->SurpriseRemove)
303 return;
305 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
308 static void hal_stop(struct hw_data *pHwData)
310 struct wb35_reg *reg = &pHwData->reg;
312 pHwData->Wb35Rx.rx_halt = 1;
313 Wb35Rx_stop(pHwData);
315 pHwData->Wb35Tx.tx_halt = 1;
316 Wb35Tx_stop(pHwData);
318 reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */
319 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
322 static unsigned char hal_idle(struct hw_data *pHwData)
324 struct wb35_reg *reg = &pHwData->reg;
325 struct wb_usb *pWbUsb = &pHwData->WbUsb;
327 if (!pHwData->SurpriseRemove
328 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
329 return false;
331 return true;
334 u8 hal_get_antenna_number(struct hw_data *pHwData)
336 struct wb35_reg *reg = &pHwData->reg;
338 if ((reg->BB2C & BIT(11)) == 0)
339 return 0;
340 else
341 return 1;
344 /* 0 : radio on; 1: radio off */
345 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
347 struct wb35_reg *reg = &pHwData->reg;
349 if (pHwData->SurpriseRemove)
350 return 1;
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;
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
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
372 static void hal_led_control(unsigned long data)
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;
381 if (pHwData->SurpriseRemove)
382 return;
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;
414 pHwData->LED_Blinking++;
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;
421 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
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);
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;
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 */
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 */
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;
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)];
485 pHwData->LED_Blinking++;
486 if (reg->U1BC_LEDConfigure != ltmp)
487 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
488 TimeInterval = 100;
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 */
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;
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 */
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 */
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 */
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);
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);
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);
575 break;
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;
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);
592 break;
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;
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);
611 static int hal_init_hardware(struct ieee80211_hw *hw)
613 struct wbsoft_priv *priv = hw->priv;
614 struct hw_data *pHwData = &priv->sHwData;
615 u16 SoftwareSet;
617 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
618 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
620 if (!Wb35Reg_initial(pHwData))
621 goto error_reg_destroy;
623 if (!Wb35Tx_initial(pHwData))
624 goto error_tx_destroy;
626 if (!Wb35Rx_initial(pHwData))
627 goto error_rx_destroy;
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);
635 SoftwareSet = hal_software_set(pHwData);
637 #ifdef Vendor2
638 /* Try to make sure the EEPROM contain */
639 SoftwareSet >>= 8;
640 if (SoftwareSet != 0x82)
641 return false;
642 #endif
644 Wb35Rx_start(hw);
645 Wb35Tx_EP2VM_start(priv);
647 return 0;
649 error_rx_destroy:
650 Wb35Rx_destroy(pHwData);
651 error_tx_destroy:
652 Wb35Tx_destroy(pHwData);
653 error_reg_destroy:
654 Wb35Reg_destroy(pHwData);
656 pHwData->SurpriseRemove = 1;
657 return -EINVAL;
660 static int wb35_hw_init(struct ieee80211_hw *hw)
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;
670 pHwData->phy_type = RF_DECIDE_BY_INF;
672 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
673 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
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 */
684 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
686 err = hal_init_hardware(hw);
687 if (err)
688 goto error;
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 */
700 Mds_initial(priv);
703 * If no user-defined address in the registry, use the address
704 * "burned" on the NIC instead.
706 pMacAddr = priv->sLocalPara.ThisMacAddress;
707 pMacAddr2 = priv->sLocalPara.PermanentAddress;
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);
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);
725 /* Waiting for HAL setting OK */
726 while (!hal_idle(pHwData))
727 msleep(10);
729 MTO_Init(priv);
731 HwRadioOff = hal_get_hw_radio_off(pHwData);
732 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
734 hal_set_radio_mode(pHwData,
735 (unsigned char)(priv->sLocalPara.RadioOffStatus.
736 boSwRadioOff
737 || priv->sLocalPara.RadioOffStatus.
738 boHwRadioOff));
740 /* Notify hal that the driver is ready now. */
741 hal_driver_init_OK(pHwData) = 1;
743 error:
744 return err;
747 static int wb35_probe(struct usb_interface *intf,
748 const struct usb_device_id *id_table)
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;
759 usb_get_dev(udev);
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;
771 /* Is already initialized? */
772 ltmp = cpu_to_le32(ltmp);
773 if (ltmp) {
774 err = -EBUSY;
775 goto error;
778 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
779 if (!dev) {
780 err = -ENOMEM;
781 goto error;
784 priv = dev->priv;
786 spin_lock_init(&priv->SpinLock);
788 pWbUsb = &priv->sHwData.WbUsb;
789 pWbUsb->udev = udev;
791 interface = intf->cur_altsetting;
792 endpoint = &interface->endpoint[0].desc;
794 if (endpoint[2].wMaxPacketSize == 512) {
795 printk("[w35und] Working on USB 2.0\n");
796 pWbUsb->IsUsb20 = 1;
799 err = wb35_hw_init(dev);
800 if (err)
801 goto error_free_hw;
803 SET_IEEE80211_DEV(dev, &udev->dev);
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);
811 dev->extra_tx_headroom = 12;
812 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
813 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
815 dev->channel_change_time = 1000;
816 dev->max_signal = 100;
817 dev->queues = 1;
819 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
821 err = ieee80211_register_hw(dev);
822 if (err)
823 goto error_free_hw;
825 usb_set_intfdata(intf, dev);
827 return 0;
829 error_free_hw:
830 ieee80211_free_hw(dev);
831 error:
832 usb_put_dev(udev);
833 return err;
836 static void hal_halt(struct hw_data *pHwData)
838 del_timer_sync(&pHwData->LEDTimer);
839 msleep(100);
840 Wb35Rx_destroy(pHwData);
841 Wb35Tx_destroy(pHwData);
842 Wb35Reg_destroy(pHwData);
845 static void wb35_hw_halt(struct wbsoft_priv *adapter)
847 Mds_Destroy(adapter);
849 /* Turn off Rx and Tx hardware ability */
850 hal_stop(&adapter->sHwData);
851 #ifdef _PE_USB_INI_DUMP_
852 printk("[w35und] Hal_stop O.K.\n");
853 #endif
854 /* Waiting Irp completed */
855 msleep(100);
857 hal_halt(&adapter->sHwData);
860 static void wb35_disconnect(struct usb_interface *intf)
862 struct ieee80211_hw *hw = usb_get_intfdata(intf);
863 struct wbsoft_priv *priv = hw->priv;
865 wb35_hw_halt(priv);
867 ieee80211_stop_queues(hw);
868 ieee80211_unregister_hw(hw);
869 ieee80211_free_hw(hw);
871 usb_set_intfdata(intf, NULL);
872 usb_put_dev(interface_to_usbdev(intf));
875 static struct usb_driver wb35_driver = {
876 .name = "w35und",
877 .id_table = wb35_table,
878 .probe = wb35_probe,
879 .disconnect = wb35_disconnect,
882 static int __init wb35_init(void)
884 return usb_register(&wb35_driver);
887 static void __exit wb35_exit(void)
889 usb_deregister(&wb35_driver);
892 module_init(wb35_init);
893 module_exit(wb35_exit);