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 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
129 static int wbsoft_start(struct ieee80211_hw *dev)
131 struct wbsoft_priv *priv = dev->priv;
133 priv->enabled = true;
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)
145 if (radio_off) { /* disable Baseband receive off */
146 pHwData->CurrentRadioSw = 1; /* off */
147 reg->M24_MacControl &= 0xffffffbf;
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)
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,
171 reg->M28_MacControl &= ~0xff; /* Clean channel information field */
172 reg->M28_MacControl |= channel.ChanNo;
173 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
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)
190 reg->M00_MacControl &= ~0x02000000; /* The HW value */
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)
207 reg->M00_MacControl |= 0x00400000;
208 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
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)
222 reg->M00_MacControl &= ~0x01000000; /* The HW value */
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)
235 if (!enable) /* Due to SME and MLME are not suitable for 35 */
238 reg->M00_MacControl &= ~0x04000000; /* The HW value */
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;
250 printk("wbsoft_config called\n");
252 /* Should use channel_num, or something, as that is already pre-translated */
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);
266 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
268 printk("wbsoft_get_tsf called\n");
272 static const struct ieee80211_ops wbsoft_ops = {
274 .start = wbsoft_start,
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)
289 if (pHwData->SurpriseRemove)
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)
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))
334 u8 hal_get_antenna_number(struct hw_data *pHwData)
336 struct wb35_reg *reg = &pHwData->reg;
338 if ((reg->BB2C & BIT(11)) == 0)
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)
352 /* read the bit16 of register U1B0 */
353 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
354 if ((reg->U1B0 & 0x00010000)) {
355 pHwData->CurrentRadioHw = 1;
358 pHwData->CurrentRadioHw = 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;
381 if (pHwData->SurpriseRemove)
384 if (pHwData->LED_control) {
385 ltmp2 = pHwData->LED_control & 0xff;
386 if (ltmp2 == 5) { /* 5 is WPS mode */
388 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
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 */
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 */
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 */
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. */
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);
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;
440 reg->U1BC_LEDConfigure &= ~0x10;
441 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
442 pHwData->LED_Blinking = 0;
447 if (reg->U1BC_LEDConfigure & 0x10) {
448 reg->U1BC_LEDConfigure &= ~0x10;
449 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
454 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
455 reg->U1BC_LEDConfigure |= 0x10;
456 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
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;
471 reg->U1BC_LEDConfigure &= ~0x1f;
472 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
473 pHwData->LED_Blinking = 0;
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 */
492 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
493 reg->U1BC_LEDConfigure |= 0x10;
494 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
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;
508 reg->U1BC_LEDConfigure &= ~0x1000;
509 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
510 pHwData->LED_Blinking = 0;
515 if (reg->U1BC_LEDConfigure & 0x1000) {
516 reg->U1BC_LEDConfigure &= ~0x1000;
517 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
521 /* Is transmitting/receiving ?? */
522 if ((adapter->RxByteCount !=
523 pHwData->RxByteCountLast)
524 || (adapter->TxByteCount !=
525 pHwData->TxByteCountLast)) {
526 if ((reg->U1BC_LEDConfigure & 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;
538 /* Turn On LED_1 and blinking if transmitting/receiving */
539 if ((reg->U1BC_LEDConfigure & 0x3000) !=
541 reg->U1BC_LEDConfigure &=
543 reg->U1BC_LEDConfigure |=
545 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
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) {
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)
570 pHwData->LED_Blinking = 0; /* Stop blinking */
571 reg->U1BC_LEDConfigure &= ~0x0f;
572 Wb35Reg_Write(pHwData, 0x03bc,
573 reg->U1BC_LEDConfigure);
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 */
586 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
587 reg->U1BC_LEDConfigure &= ~0x10;
588 Wb35Reg_Write(pHwData, 0x03bc,
589 reg->U1BC_LEDConfigure);
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;
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);
638 /* Try to make sure the EEPROM contain */
640 if (SoftwareSet != 0x82)
645 Wb35Tx_EP2VM_start(priv);
650 Wb35Rx_destroy(pHwData);
652 Wb35Tx_destroy(pHwData);
654 Wb35Reg_destroy(pHwData);
656 pHwData->SurpriseRemove = 1;
660 static int wb35_hw_init(struct ieee80211_hw *hw)
662 struct wbsoft_priv *priv = hw->priv;
663 struct hw_data *pHwData = &priv->sHwData;
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);
690 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
691 if (EEPROM_region != REGION_AUTO)
692 priv->sLocalPara.region = EEPROM_region;
694 if (priv->sLocalPara.region_INF != REGION_AUTO)
695 priv->sLocalPara.region = priv->sLocalPara.region_INF;
697 priv->sLocalPara.region = REGION_USA; /* default setting */
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);
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);
723 hal_get_hw_radio_off(pHwData);
725 /* Waiting for HAL setting OK */
726 while (!hal_idle(pHwData))
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.
737 || priv->sLocalPara.RadioOffStatus.
740 /* Notify hal that the driver is ready now. */
741 hal_driver_init_OK(pHwData) = 1;
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;
761 /* Check the device if it already be opened */
762 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
764 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
765 0x0, 0x400, <mp, 4, HZ * 100);
771 /* Is already initialized? */
772 ltmp = cpu_to_le32(ltmp);
778 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
786 spin_lock_init(&priv->SpinLock);
788 pWbUsb = &priv->sHwData.WbUsb;
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");
799 err = wb35_hw_init(dev);
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; /* FIXME */
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;
819 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
821 err = ieee80211_register_hw(dev);
825 usb_set_intfdata(intf, dev);
830 ieee80211_free_hw(dev);
836 static void hal_halt(struct hw_data *pHwData)
838 del_timer_sync(&pHwData->LEDTimer);
839 /* XXX: Wait for Timer DPC exit. */
841 Wb35Rx_destroy(pHwData);
842 Wb35Tx_destroy(pHwData);
843 Wb35Reg_destroy(pHwData);
846 static void wb35_hw_halt(struct wbsoft_priv *adapter)
848 Mds_Destroy(adapter);
850 /* Turn off Rx and Tx hardware ability */
851 hal_stop(&adapter->sHwData);
852 #ifdef _PE_USB_INI_DUMP_
853 printk("[w35und] Hal_stop O.K.\n");
855 /* Waiting Irp completed */
858 hal_halt(&adapter->sHwData);
861 static void wb35_disconnect(struct usb_interface *intf)
863 struct ieee80211_hw *hw = usb_get_intfdata(intf);
864 struct wbsoft_priv *priv = hw->priv;
868 ieee80211_stop_queues(hw);
869 ieee80211_unregister_hw(hw);
870 ieee80211_free_hw(hw);
872 usb_set_intfdata(intf, NULL);
873 usb_put_dev(interface_to_usbdev(intf));
876 static struct usb_driver wb35_driver = {
878 .id_table = wb35_table,
880 .disconnect = wb35_disconnect,
883 static int __init wb35_init(void)
885 return usb_register(&wb35_driver);
888 static void __exit wb35_exit(void)
890 usb_deregister(&wb35_driver);
893 module_init(wb35_init);
894 module_exit(wb35_exit);