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>
17 #include "mlmetxrx_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) },
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)
58 if (pHwData->SurpriseRemove)
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);
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__);
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,
106 unsigned int new_flags;
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 if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
125 priv->sMlmeFrame.wNumTxMMPDUDiscarded++;
126 return NETDEV_TX_BUSY;
129 priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
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++;
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.
146 static int wbsoft_start(struct ieee80211_hw *dev)
148 struct wbsoft_priv *priv = dev->priv;
150 priv->enabled = true;
155 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
157 struct wb35_reg *reg = &pHwData->reg;
159 if (pHwData->SurpriseRemove)
162 if (radio_off) { /* disable Baseband receive off */
163 pHwData->CurrentRadioSw = 1; /* off */
164 reg->M24_MacControl &= 0xffffffbf;
166 pHwData->CurrentRadioSw = 0; /* on */
167 reg->M24_MacControl |= 0x00000040;
169 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
172 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
174 struct wb35_reg *reg = &pHwData->reg;
176 if (pHwData->SurpriseRemove)
179 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
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,
188 reg->M28_MacControl &= ~0xff; /* Clean channel information field */
189 reg->M28_MacControl |= channel.ChanNo;
190 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
192 sizeof(struct chan_info));
195 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
197 hal_set_current_channel_ex(pHwData, channel);
200 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
202 struct wb35_reg *reg = &pHwData->reg;
204 if (pHwData->SurpriseRemove)
207 reg->M00_MacControl &= ~0x02000000; /* The HW value */
210 reg->M00_MacControl |= 0x02000000; /* The HW value */
212 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
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)
218 struct wb35_reg *reg = &pHwData->reg;
220 if (pHwData->SurpriseRemove)
224 reg->M00_MacControl |= 0x00400000;
225 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
227 reg->M00_MacControl &= ~0x00400000;
228 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
232 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
234 struct wb35_reg *reg = &pHwData->reg;
236 if (pHwData->SurpriseRemove)
239 reg->M00_MacControl &= ~0x01000000; /* The HW value */
241 reg->M00_MacControl |= 0x01000000; /* The HW value */
242 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
245 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
247 struct wb35_reg *reg = &pHwData->reg;
249 if (pHwData->SurpriseRemove)
252 if (!enable) /* Due to SME and MLME are not suitable for 35 */
255 reg->M00_MacControl &= ~0x04000000; /* The HW value */
257 reg->M00_MacControl |= 0x04000000; /* The HW value */
259 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
262 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
264 struct wbsoft_priv *priv = dev->priv;
267 printk("wbsoft_config called\n");
269 /* Should use channel_num, or something, as that is already pre-translated */
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);
283 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
285 printk("wbsoft_get_tsf called\n");
289 static const struct ieee80211_ops wbsoft_ops = {
291 .start = wbsoft_start,
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,
302 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
306 if (pHwData->SurpriseRemove)
309 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
311 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
312 ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
314 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
317 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
319 if (pHwData->SurpriseRemove)
322 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
325 static void hal_stop(struct hw_data *pHwData)
327 struct wb35_reg *reg = &pHwData->reg;
329 pHwData->Wb35Rx.rx_halt = 1;
330 Wb35Rx_stop(pHwData);
332 pHwData->Wb35Tx.tx_halt = 1;
333 Wb35Tx_stop(pHwData);
335 reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */
336 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
339 static unsigned char hal_idle(struct hw_data *pHwData)
341 struct wb35_reg *reg = &pHwData->reg;
342 struct wb_usb *pWbUsb = &pHwData->WbUsb;
344 if (!pHwData->SurpriseRemove
345 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
351 u8 hal_get_antenna_number(struct hw_data *pHwData)
353 struct wb35_reg *reg = &pHwData->reg;
355 if ((reg->BB2C & BIT(11)) == 0)
361 /* 0 : radio on; 1: radio off */
362 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
364 struct wb35_reg *reg = &pHwData->reg;
366 if (pHwData->SurpriseRemove)
369 /* read the bit16 of register U1B0 */
370 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
371 if ((reg->U1B0 & 0x00010000)) {
372 pHwData->CurrentRadioHw = 1;
375 pHwData->CurrentRadioHw = 0;
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
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
389 static void hal_led_control(unsigned long data)
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;
398 if (pHwData->SurpriseRemove)
401 if (pHwData->LED_control) {
402 ltmp2 = pHwData->LED_control & 0xff;
403 if (ltmp2 == 5) { /* 5 is WPS mode */
405 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
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 */
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 */
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 */
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. */
431 pHwData->LED_Blinking++;
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;
438 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
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);
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;
457 reg->U1BC_LEDConfigure &= ~0x10;
458 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
459 pHwData->LED_Blinking = 0;
464 if (reg->U1BC_LEDConfigure & 0x10) {
465 reg->U1BC_LEDConfigure &= ~0x10;
466 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
471 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
472 reg->U1BC_LEDConfigure |= 0x10;
473 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
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;
488 reg->U1BC_LEDConfigure &= ~0x1f;
489 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
490 pHwData->LED_Blinking = 0;
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)];
502 pHwData->LED_Blinking++;
503 if (reg->U1BC_LEDConfigure != ltmp)
504 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
509 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
510 reg->U1BC_LEDConfigure |= 0x10;
511 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
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;
525 reg->U1BC_LEDConfigure &= ~0x1000;
526 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
527 pHwData->LED_Blinking = 0;
532 if (reg->U1BC_LEDConfigure & 0x1000) {
533 reg->U1BC_LEDConfigure &= ~0x1000;
534 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
538 /* Is transmitting/receiving ?? */
539 if ((adapter->RxByteCount !=
540 pHwData->RxByteCountLast)
541 || (adapter->TxByteCount !=
542 pHwData->TxByteCountLast)) {
543 if ((reg->U1BC_LEDConfigure & 0x3000) !=
545 reg->U1BC_LEDConfigure |= 0x3000;
546 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
548 /* Update variable */
549 pHwData->RxByteCountLast =
550 adapter->RxByteCount;
551 pHwData->TxByteCountLast =
552 adapter->TxByteCount;
555 /* Turn On LED_1 and blinking if transmitting/receiving */
556 if ((reg->U1BC_LEDConfigure & 0x3000) !=
558 reg->U1BC_LEDConfigure &=
560 reg->U1BC_LEDConfigure |=
562 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
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);
574 if (pHwData->LED_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);
583 pHwData->LED_Blinking += 2;
584 if (pHwData->LED_Blinking < 40)
587 pHwData->LED_Blinking = 0; /* Stop blinking */
588 reg->U1BC_LEDConfigure &= ~0x0f;
589 Wb35Reg_Write(pHwData, 0x03bc,
590 reg->U1BC_LEDConfigure);
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 */
603 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
604 reg->U1BC_LEDConfigure &= ~0x10;
605 Wb35Reg_Write(pHwData, 0x03bc,
606 reg->U1BC_LEDConfigure);
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;
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);
628 static int hal_init_hardware(struct ieee80211_hw *hw)
630 struct wbsoft_priv *priv = hw->priv;
631 struct hw_data *pHwData = &priv->sHwData;
634 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
635 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
637 if (!Wb35Reg_initial(pHwData))
638 goto error_reg_destroy;
640 if (!Wb35Tx_initial(pHwData))
641 goto error_tx_destroy;
643 if (!Wb35Rx_initial(pHwData))
644 goto error_rx_destroy;
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);
652 SoftwareSet = hal_software_set(pHwData);
655 /* Try to make sure the EEPROM contain */
657 if (SoftwareSet != 0x82)
662 Wb35Tx_EP2VM_start(priv);
667 Wb35Rx_destroy(pHwData);
669 Wb35Tx_destroy(pHwData);
671 Wb35Reg_destroy(pHwData);
673 pHwData->SurpriseRemove = 1;
677 static int wb35_hw_init(struct ieee80211_hw *hw)
679 struct wbsoft_priv *priv = hw->priv;
680 struct hw_data *pHwData = &priv->sHwData;
687 pHwData->phy_type = RF_DECIDE_BY_INF;
689 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
690 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
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 */
701 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
703 err = hal_init_hardware(hw);
707 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
708 if (EEPROM_region != REGION_AUTO)
709 priv->sLocalPara.region = EEPROM_region;
711 if (priv->sLocalPara.region_INF != REGION_AUTO)
712 priv->sLocalPara.region = priv->sLocalPara.region_INF;
714 priv->sLocalPara.region = REGION_USA; /* default setting */
720 * If no user-defined address in the registry, use the address
721 * "burned" on the NIC instead.
723 pMacAddr = priv->sLocalPara.ThisMacAddress;
724 pMacAddr2 = priv->sLocalPara.PermanentAddress;
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);
731 /* Set the user define MAC address */
732 hal_set_ethernet_address(pHwData,
733 priv->sLocalPara.ThisMacAddress);
736 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
737 #ifdef _PE_STATE_DUMP_
738 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
740 hal_get_hw_radio_off(pHwData);
742 /* Waiting for HAL setting OK */
743 while (!hal_idle(pHwData))
748 HwRadioOff = hal_get_hw_radio_off(pHwData);
749 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
751 hal_set_radio_mode(pHwData,
752 (unsigned char)(priv->sLocalPara.RadioOffStatus.
754 || priv->sLocalPara.RadioOffStatus.
757 /* Notify hal that the driver is ready now. */
758 hal_driver_init_OK(pHwData) = 1;
764 static int wb35_probe(struct usb_interface *intf,
765 const struct usb_device_id *id_table)
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;
778 /* Check the device if it already be opened */
779 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
781 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
782 0x0, 0x400, <mp, 4, HZ * 100);
788 /* Is already initialized? */
789 ltmp = cpu_to_le32(ltmp);
795 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
803 pWbUsb = &priv->sHwData.WbUsb;
806 interface = intf->cur_altsetting;
807 endpoint = &interface->endpoint[0].desc;
809 if (endpoint[2].wMaxPacketSize == 512) {
810 printk("[w35und] Working on USB 2.0\n");
814 err = wb35_hw_init(dev);
818 SET_IEEE80211_DEV(dev, &udev->dev);
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);
826 dev->extra_tx_headroom = 12; /* FIXME */
827 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
828 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
830 dev->channel_change_time = 1000;
831 dev->max_signal = 100;
834 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
836 err = ieee80211_register_hw(dev);
840 usb_set_intfdata(intf, dev);
845 ieee80211_free_hw(dev);
851 static void hal_halt(struct hw_data *pHwData)
853 del_timer_sync(&pHwData->LEDTimer);
854 /* XXX: Wait for Timer DPC exit. */
856 Wb35Rx_destroy(pHwData);
857 Wb35Tx_destroy(pHwData);
858 Wb35Reg_destroy(pHwData);
861 static void wb35_hw_halt(struct wbsoft_priv *adapter)
863 Mds_Destroy(adapter);
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");
870 /* Waiting Irp completed */
873 hal_halt(&adapter->sHwData);
876 static void wb35_disconnect(struct usb_interface *intf)
878 struct ieee80211_hw *hw = usb_get_intfdata(intf);
879 struct wbsoft_priv *priv = hw->priv;
883 ieee80211_stop_queues(hw);
884 ieee80211_unregister_hw(hw);
885 ieee80211_free_hw(hw);
887 usb_set_intfdata(intf, NULL);
888 usb_put_dev(interface_to_usbdev(intf));
891 static struct usb_driver wb35_driver = {
893 .id_table = wb35_table,
895 .disconnect = wb35_disconnect,
898 static int __init wb35_init(void)
900 return usb_register(&wb35_driver);
903 static void __exit wb35_exit(void)
905 usb_deregister(&wb35_driver);
908 module_init(wb35_init);
909 module_exit(wb35_exit);