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 return MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
127 static int wbsoft_start(struct ieee80211_hw *dev)
129 struct wbsoft_priv *priv = dev->priv;
131 priv->enabled = true;
136 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
138 struct wb35_reg *reg = &pHwData->reg;
140 if (pHwData->SurpriseRemove)
143 if (radio_off) { /* disable Baseband receive off */
144 pHwData->CurrentRadioSw = 1; /* off */
145 reg->M24_MacControl &= 0xffffffbf;
147 pHwData->CurrentRadioSw = 0; /* on */
148 reg->M24_MacControl |= 0x00000040;
150 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
153 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
155 struct wb35_reg *reg = &pHwData->reg;
157 if (pHwData->SurpriseRemove)
160 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
162 RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */
163 pHwData->Channel = channel.ChanNo;
164 pHwData->band = channel.band;
165 #ifdef _PE_STATE_DUMP_
166 printk("Set channel is %d, band =%d\n", pHwData->Channel,
169 reg->M28_MacControl &= ~0xff; /* Clean channel information field */
170 reg->M28_MacControl |= channel.ChanNo;
171 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
173 sizeof(struct chan_info));
176 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
178 hal_set_current_channel_ex(pHwData, channel);
181 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
183 struct wb35_reg *reg = &pHwData->reg;
185 if (pHwData->SurpriseRemove)
188 reg->M00_MacControl &= ~0x02000000; /* The HW value */
191 reg->M00_MacControl |= 0x02000000; /* The HW value */
193 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
196 /* For wep key error detection, we need to accept broadcast packets to be received temporary. */
197 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
199 struct wb35_reg *reg = &pHwData->reg;
201 if (pHwData->SurpriseRemove)
205 reg->M00_MacControl |= 0x00400000;
206 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
208 reg->M00_MacControl &= ~0x00400000;
209 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
213 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
215 struct wb35_reg *reg = &pHwData->reg;
217 if (pHwData->SurpriseRemove)
220 reg->M00_MacControl &= ~0x01000000; /* The HW value */
222 reg->M00_MacControl |= 0x01000000; /* The HW value */
223 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
226 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
228 struct wb35_reg *reg = &pHwData->reg;
230 if (pHwData->SurpriseRemove)
233 if (!enable) /* Due to SME and MLME are not suitable for 35 */
236 reg->M00_MacControl &= ~0x04000000; /* The HW value */
238 reg->M00_MacControl |= 0x04000000; /* The HW value */
240 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
243 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
245 struct wbsoft_priv *priv = dev->priv;
248 printk("wbsoft_config called\n");
250 /* Should use channel_num, or something, as that is already pre-translated */
254 hal_set_current_channel(&priv->sHwData, ch);
255 hal_set_accept_broadcast(&priv->sHwData, 1);
256 hal_set_accept_promiscuous(&priv->sHwData, 1);
257 hal_set_accept_multicast(&priv->sHwData, 1);
258 hal_set_accept_beacon(&priv->sHwData, 1);
259 hal_set_radio_mode(&priv->sHwData, 0);
264 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
266 printk("wbsoft_get_tsf called\n");
270 static const struct ieee80211_ops wbsoft_ops = {
272 .start = wbsoft_start,
274 .add_interface = wbsoft_add_interface,
275 .remove_interface = wbsoft_remove_interface,
276 .config = wbsoft_config,
277 .prepare_multicast = wbsoft_prepare_multicast,
278 .configure_filter = wbsoft_configure_filter,
279 .get_stats = wbsoft_get_stats,
280 .get_tsf = wbsoft_get_tsf,
283 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
287 if (pHwData->SurpriseRemove)
290 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
292 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
293 ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
295 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
298 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
300 if (pHwData->SurpriseRemove)
303 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
306 static void hal_stop(struct hw_data *pHwData)
308 struct wb35_reg *reg = &pHwData->reg;
310 pHwData->Wb35Rx.rx_halt = 1;
311 Wb35Rx_stop(pHwData);
313 pHwData->Wb35Tx.tx_halt = 1;
314 Wb35Tx_stop(pHwData);
316 reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */
317 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
320 static unsigned char hal_idle(struct hw_data *pHwData)
322 struct wb35_reg *reg = &pHwData->reg;
323 struct wb_usb *pWbUsb = &pHwData->WbUsb;
325 if (!pHwData->SurpriseRemove
326 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
332 u8 hal_get_antenna_number(struct hw_data *pHwData)
334 struct wb35_reg *reg = &pHwData->reg;
336 if ((reg->BB2C & BIT(11)) == 0)
342 /* 0 : radio on; 1: radio off */
343 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
345 struct wb35_reg *reg = &pHwData->reg;
347 if (pHwData->SurpriseRemove)
350 /* read the bit16 of register U1B0 */
351 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
352 if ((reg->U1B0 & 0x00010000)) {
353 pHwData->CurrentRadioHw = 1;
356 pHwData->CurrentRadioHw = 0;
361 static u8 LED_GRAY[20] = {
362 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
365 static u8 LED_GRAY2[30] = {
366 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
367 0, 15, 14, 13, 12, 11, 10, 9, 8
370 static void hal_led_control(unsigned long data)
372 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
373 struct hw_data *pHwData = &adapter->sHwData;
374 struct wb35_reg *reg = &pHwData->reg;
375 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
376 u32 TimeInterval = 500, ltmp, ltmp2;
379 if (pHwData->SurpriseRemove)
382 if (pHwData->LED_control) {
383 ltmp2 = pHwData->LED_control & 0xff;
384 if (ltmp2 == 5) { /* 5 is WPS mode */
386 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
388 case 1: /* [0.2 On][0.1 Off]... */
389 pHwData->LED_Blinking %= 3;
390 ltmp = 0x1010; /* Led 1 & 0 Green and Red */
391 if (pHwData->LED_Blinking == 2) /* Turn off */
394 case 2: /* [0.1 On][0.1 Off]... */
395 pHwData->LED_Blinking %= 2;
396 ltmp = 0x0010; /* Led 0 red color */
397 if (pHwData->LED_Blinking) /* Turn off */
400 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]... */
401 pHwData->LED_Blinking %= 15;
402 ltmp = 0x0010; /* Led 0 red color */
403 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) /* Turn off 0.6 sec */
406 case 4: /* [300 On][ off ] */
407 ltmp = 0x1000; /* Led 1 Green color */
408 if (pHwData->LED_Blinking >= 3000)
409 ltmp = 0; /* led maybe on after 300sec * 32bit counter overlap. */
412 pHwData->LED_Blinking++;
414 reg->U1BC_LEDConfigure = ltmp;
415 if (LEDSet != 7) { /* Only 111 mode has 2 LEDs on PCB. */
416 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; /* Copy LED result to each LED control register */
417 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
419 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
421 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) { /* If radio off */
422 if (reg->U1BC_LEDConfigure & 0x1010) {
423 reg->U1BC_LEDConfigure &= ~0x1010;
424 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
428 case 4: /* [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
429 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
430 /* Blinking if scanning is on progress */
431 if (pHwData->LED_Scanning) {
432 if (pHwData->LED_Blinking == 0) {
433 reg->U1BC_LEDConfigure |= 0x10;
434 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
435 pHwData->LED_Blinking = 1;
438 reg->U1BC_LEDConfigure &= ~0x10;
439 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
440 pHwData->LED_Blinking = 0;
445 if (reg->U1BC_LEDConfigure & 0x10) {
446 reg->U1BC_LEDConfigure &= ~0x10;
447 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
452 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
453 reg->U1BC_LEDConfigure |= 0x10;
454 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
458 case 6: /* [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
459 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
460 /* Blinking if scanning is on progress */
461 if (pHwData->LED_Scanning) {
462 if (pHwData->LED_Blinking == 0) {
463 reg->U1BC_LEDConfigure &= ~0xf;
464 reg->U1BC_LEDConfigure |= 0x10;
465 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
466 pHwData->LED_Blinking = 1;
469 reg->U1BC_LEDConfigure &= ~0x1f;
470 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
471 pHwData->LED_Blinking = 0;
475 /* Gray blinking if in disconnect state and not scanning */
476 ltmp = reg->U1BC_LEDConfigure;
477 reg->U1BC_LEDConfigure &= ~0x1f;
478 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
479 reg->U1BC_LEDConfigure |= 0x10;
480 reg->U1BC_LEDConfigure |=
481 LED_GRAY2[(pHwData->LED_Blinking % 30)];
483 pHwData->LED_Blinking++;
484 if (reg->U1BC_LEDConfigure != ltmp)
485 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
490 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
491 reg->U1BC_LEDConfigure |= 0x10;
492 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
496 case 5: /* [101] Only 1 Led be placed on PCB and use LED_1 for showing */
497 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
498 /* Blinking if scanning is on progress */
499 if (pHwData->LED_Scanning) {
500 if (pHwData->LED_Blinking == 0) {
501 reg->U1BC_LEDConfigure |= 0x1000;
502 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
503 pHwData->LED_Blinking = 1;
506 reg->U1BC_LEDConfigure &= ~0x1000;
507 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
508 pHwData->LED_Blinking = 0;
513 if (reg->U1BC_LEDConfigure & 0x1000) {
514 reg->U1BC_LEDConfigure &= ~0x1000;
515 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
519 /* Is transmitting/receiving ?? */
520 if ((adapter->RxByteCount !=
521 pHwData->RxByteCountLast)
522 || (adapter->TxByteCount !=
523 pHwData->TxByteCountLast)) {
524 if ((reg->U1BC_LEDConfigure & 0x3000) !=
526 reg->U1BC_LEDConfigure |= 0x3000;
527 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
529 /* Update variable */
530 pHwData->RxByteCountLast =
531 adapter->RxByteCount;
532 pHwData->TxByteCountLast =
533 adapter->TxByteCount;
536 /* Turn On LED_1 and blinking if transmitting/receiving */
537 if ((reg->U1BC_LEDConfigure & 0x3000) !=
539 reg->U1BC_LEDConfigure &=
541 reg->U1BC_LEDConfigure |=
543 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
548 default: /* Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active */
549 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
550 reg->U1BC_LEDConfigure |= 0x3000; /* LED_1 is always on and event enable */
551 Wb35Reg_Write(pHwData, 0x03bc,
552 reg->U1BC_LEDConfigure);
555 if (pHwData->LED_Blinking) {
557 reg->U1BC_LEDConfigure &= ~0x0f;
558 reg->U1BC_LEDConfigure |= 0x10;
559 reg->U1BC_LEDConfigure |=
560 LED_GRAY[(pHwData->LED_Blinking - 1) % 20];
561 Wb35Reg_Write(pHwData, 0x03bc,
562 reg->U1BC_LEDConfigure);
564 pHwData->LED_Blinking += 2;
565 if (pHwData->LED_Blinking < 40)
568 pHwData->LED_Blinking = 0; /* Stop blinking */
569 reg->U1BC_LEDConfigure &= ~0x0f;
570 Wb35Reg_Write(pHwData, 0x03bc,
571 reg->U1BC_LEDConfigure);
576 if (pHwData->LED_LinkOn) {
577 if (!(reg->U1BC_LEDConfigure & 0x10)) { /* Check the LED_0 */
578 /* Try to turn ON LED_0 after gray blinking */
579 reg->U1BC_LEDConfigure |= 0x10;
580 pHwData->LED_Blinking = 1; /* Start blinking */
584 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
585 reg->U1BC_LEDConfigure &= ~0x10;
586 Wb35Reg_Write(pHwData, 0x03bc,
587 reg->U1BC_LEDConfigure);
593 /* Active send null packet to avoid AP disconnect */
594 if (pHwData->LED_LinkOn) {
595 pHwData->NullPacketCount += TimeInterval;
596 if (pHwData->NullPacketCount >=
597 DEFAULT_NULL_PACKET_COUNT) {
598 pHwData->NullPacketCount = 0;
603 pHwData->time_count += TimeInterval;
604 Wb35Tx_CurrentTime(adapter, pHwData->time_count);
605 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
606 add_timer(&pHwData->LEDTimer);
609 static int hal_init_hardware(struct ieee80211_hw *hw)
611 struct wbsoft_priv *priv = hw->priv;
612 struct hw_data *pHwData = &priv->sHwData;
615 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
616 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
618 if (!Wb35Reg_initial(pHwData))
619 goto error_reg_destroy;
621 if (!Wb35Tx_initial(pHwData))
622 goto error_tx_destroy;
624 if (!Wb35Rx_initial(pHwData))
625 goto error_rx_destroy;
627 init_timer(&pHwData->LEDTimer);
628 pHwData->LEDTimer.function = hal_led_control;
629 pHwData->LEDTimer.data = (unsigned long)priv;
630 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
631 add_timer(&pHwData->LEDTimer);
633 SoftwareSet = hal_software_set(pHwData);
636 /* Try to make sure the EEPROM contain */
638 if (SoftwareSet != 0x82)
643 Wb35Tx_EP2VM_start(priv);
648 Wb35Rx_destroy(pHwData);
650 Wb35Tx_destroy(pHwData);
652 Wb35Reg_destroy(pHwData);
654 pHwData->SurpriseRemove = 1;
658 static int wb35_hw_init(struct ieee80211_hw *hw)
660 struct wbsoft_priv *priv = hw->priv;
661 struct hw_data *pHwData = &priv->sHwData;
668 pHwData->phy_type = RF_DECIDE_BY_INF;
670 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
671 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
673 priv->sLocalPara.region_INF = REGION_AUTO;
674 priv->sLocalPara.TxRateMode = RATE_AUTO;
675 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG;
676 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
677 priv->sLocalPara.bPreambleMode = AUTO_MODE;
678 priv->sLocalPara.bWepKeyError = false;
679 priv->sLocalPara.bToSelfPacketReceived = false;
680 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
682 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
684 err = hal_init_hardware(hw);
688 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
689 if (EEPROM_region != REGION_AUTO)
690 priv->sLocalPara.region = EEPROM_region;
692 if (priv->sLocalPara.region_INF != REGION_AUTO)
693 priv->sLocalPara.region = priv->sLocalPara.region_INF;
695 priv->sLocalPara.region = REGION_USA; /* default setting */
701 * If no user-defined address in the registry, use the address
702 * "burned" on the NIC instead.
704 pMacAddr = priv->sLocalPara.ThisMacAddress;
705 pMacAddr2 = priv->sLocalPara.PermanentAddress;
707 /* Reading ethernet address from EEPROM */
708 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
709 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
710 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
712 /* Set the user define MAC address */
713 hal_set_ethernet_address(pHwData,
714 priv->sLocalPara.ThisMacAddress);
717 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
718 #ifdef _PE_STATE_DUMP_
719 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
721 hal_get_hw_radio_off(pHwData);
723 /* Waiting for HAL setting OK */
724 while (!hal_idle(pHwData))
729 HwRadioOff = hal_get_hw_radio_off(pHwData);
730 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
732 hal_set_radio_mode(pHwData,
733 (unsigned char)(priv->sLocalPara.RadioOffStatus.
735 || priv->sLocalPara.RadioOffStatus.
738 /* Notify hal that the driver is ready now. */
739 hal_driver_init_OK(pHwData) = 1;
745 static int wb35_probe(struct usb_interface *intf,
746 const struct usb_device_id *id_table)
748 struct usb_device *udev = interface_to_usbdev(intf);
749 struct usb_endpoint_descriptor *endpoint;
750 struct usb_host_interface *interface;
751 struct ieee80211_hw *dev;
752 struct wbsoft_priv *priv;
753 struct wb_usb *pWbUsb;
759 /* Check the device if it already be opened */
760 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
762 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
763 0x0, 0x400, <mp, 4, HZ * 100);
769 /* Is already initialized? */
770 ltmp = cpu_to_le32(ltmp);
776 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
784 pWbUsb = &priv->sHwData.WbUsb;
787 interface = intf->cur_altsetting;
788 endpoint = &interface->endpoint[0].desc;
790 if (endpoint[2].wMaxPacketSize == 512) {
791 printk("[w35und] Working on USB 2.0\n");
795 err = wb35_hw_init(dev);
799 SET_IEEE80211_DEV(dev, &udev->dev);
801 struct hw_data *pHwData = &priv->sHwData;
802 unsigned char dev_addr[MAX_ADDR_LEN];
803 hal_get_permanent_address(pHwData, dev_addr);
804 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
807 dev->extra_tx_headroom = 12; /* FIXME */
808 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
809 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
811 dev->channel_change_time = 1000;
812 dev->max_signal = 100;
815 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
817 err = ieee80211_register_hw(dev);
821 usb_set_intfdata(intf, dev);
826 ieee80211_free_hw(dev);
832 static void hal_halt(struct hw_data *pHwData)
834 del_timer_sync(&pHwData->LEDTimer);
835 /* XXX: Wait for Timer DPC exit. */
837 Wb35Rx_destroy(pHwData);
838 Wb35Tx_destroy(pHwData);
839 Wb35Reg_destroy(pHwData);
842 static void wb35_hw_halt(struct wbsoft_priv *adapter)
844 Mds_Destroy(adapter);
846 /* Turn off Rx and Tx hardware ability */
847 hal_stop(&adapter->sHwData);
848 #ifdef _PE_USB_INI_DUMP_
849 printk("[w35und] Hal_stop O.K.\n");
851 /* Waiting Irp completed */
854 hal_halt(&adapter->sHwData);
857 static void wb35_disconnect(struct usb_interface *intf)
859 struct ieee80211_hw *hw = usb_get_intfdata(intf);
860 struct wbsoft_priv *priv = hw->priv;
864 ieee80211_stop_queues(hw);
865 ieee80211_unregister_hw(hw);
866 ieee80211_free_hw(hw);
868 usb_set_intfdata(intf, NULL);
869 usb_put_dev(interface_to_usbdev(intf));
872 static struct usb_driver wb35_driver = {
874 .id_table = wb35_table,
876 .disconnect = wb35_disconnect,
879 static int __init wb35_init(void)
881 return usb_register(&wb35_driver);
884 static void __exit wb35_exit(void)
886 usb_deregister(&wb35_driver);
889 module_init(wb35_init);
890 module_exit(wb35_exit);