2 * Copyright 2008 Pavel Machek <pavel@suse.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 struct usb_device_id wb35_table[] __devinitdata = {
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_if_init_conf *conf)
70 struct wbsoft_priv *priv = dev->priv;
72 hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
77 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78 struct ieee80211_if_init_conf *conf)
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 int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
96 struct ieee80211_tx_queue_stats *stats)
98 printk(KERN_INFO "%s called\n", __func__);
102 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
103 unsigned int changed_flags,
104 unsigned int *total_flags,
105 int mc_count, struct dev_mc_list *mclist)
107 unsigned int new_flags;
111 if (*total_flags & FIF_PROMISC_IN_BSS)
112 new_flags |= FIF_PROMISC_IN_BSS;
113 else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32))
114 new_flags |= FIF_ALLMULTI;
116 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
118 *total_flags = new_flags;
121 static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
123 struct wbsoft_priv *priv = dev->priv;
125 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
130 static int wbsoft_start(struct ieee80211_hw *dev)
132 struct wbsoft_priv *priv = dev->priv;
134 priv->enabled = true;
139 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
141 struct wb35_reg *reg = &pHwData->reg;
143 if (pHwData->SurpriseRemove)
146 if (radio_off) //disable Baseband receive off
148 pHwData->CurrentRadioSw = 1; // off
149 reg->M24_MacControl &= 0xffffffbf;
151 pHwData->CurrentRadioSw = 0; // on
152 reg->M24_MacControl |= 0x00000040;
154 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
158 hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
160 struct wb35_reg *reg = &pHwData->reg;
162 if (pHwData->SurpriseRemove)
165 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
167 RFSynthesizer_SwitchingChannel(pHwData, channel); // Switch channel
168 pHwData->Channel = channel.ChanNo;
169 pHwData->band = channel.band;
170 #ifdef _PE_STATE_DUMP_
171 printk("Set channel is %d, band =%d\n", pHwData->Channel,
174 reg->M28_MacControl &= ~0xff; // Clean channel information field
175 reg->M28_MacControl |= channel.ChanNo;
176 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
177 (s8 *) & channel, sizeof(ChanInfo));
180 static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
182 hal_set_current_channel_ex(pHwData, channel);
185 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
187 struct wb35_reg *reg = &pHwData->reg;
189 if (pHwData->SurpriseRemove)
192 reg->M00_MacControl &= ~0x02000000; //The HW value
195 reg->M00_MacControl |= 0x02000000; //The HW value
197 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
200 //for wep key error detection, we need to accept broadcast packets to be received temporary.
201 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
203 struct wb35_reg *reg = &pHwData->reg;
205 if (pHwData->SurpriseRemove)
208 reg->M00_MacControl |= 0x00400000;
209 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
211 reg->M00_MacControl &= ~0x00400000;
212 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
216 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
218 struct wb35_reg *reg = &pHwData->reg;
220 if (pHwData->SurpriseRemove)
223 reg->M00_MacControl &= ~0x01000000; //The HW value
225 reg->M00_MacControl |= 0x01000000; //The HW value
226 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
229 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
231 struct wb35_reg *reg = &pHwData->reg;
233 if (pHwData->SurpriseRemove)
237 if (!enable) //Due to SME and MLME are not suitable for 35
240 reg->M00_MacControl &= ~0x04000000; //The HW value
242 reg->M00_MacControl |= 0x04000000; //The HW value
244 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
247 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
249 struct wbsoft_priv *priv = dev->priv;
252 printk("wbsoft_config called\n");
254 /* Should use channel_num, or something, as that is already pre-translated */
258 hal_set_current_channel(&priv->sHwData, ch);
259 hal_set_accept_broadcast(&priv->sHwData, 1);
260 hal_set_accept_promiscuous(&priv->sHwData, 1);
261 hal_set_accept_multicast(&priv->sHwData, 1);
262 hal_set_accept_beacon(&priv->sHwData, 1);
263 hal_set_radio_mode(&priv->sHwData, 0);
268 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
270 printk("wbsoft_get_tsf called\n");
274 static const struct ieee80211_ops wbsoft_ops = {
276 .start = wbsoft_start,
278 .add_interface = wbsoft_add_interface,
279 .remove_interface = wbsoft_remove_interface,
280 .config = wbsoft_config,
281 .configure_filter = wbsoft_configure_filter,
282 .get_stats = wbsoft_get_stats,
283 .get_tx_stats = wbsoft_get_tx_stats,
284 .get_tsf = wbsoft_get_tsf,
288 hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address)
292 if (pHwData->SurpriseRemove)
295 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
297 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
299 cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
301 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
305 hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address)
307 if (pHwData->SurpriseRemove)
310 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
313 static void hal_stop(struct hw_data *pHwData)
315 struct wb35_reg *reg = &pHwData->reg;
317 pHwData->Wb35Rx.rx_halt = 1;
318 Wb35Rx_stop(pHwData);
320 pHwData->Wb35Tx.tx_halt = 1;
321 Wb35Tx_stop(pHwData);
323 reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off
324 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
327 static unsigned char hal_idle(struct hw_data *pHwData)
329 struct wb35_reg *reg = &pHwData->reg;
330 struct wb_usb *pWbUsb = &pHwData->WbUsb;
332 if (!pHwData->SurpriseRemove
333 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
339 u8 hal_get_antenna_number(struct hw_data *pHwData)
341 struct wb35_reg *reg = &pHwData->reg;
343 if ((reg->BB2C & BIT(11)) == 0)
349 /* 0 : radio on; 1: radio off */
350 static u8 hal_get_hw_radio_off(struct hw_data * pHwData)
352 struct wb35_reg *reg = &pHwData->reg;
354 if (pHwData->SurpriseRemove)
357 //read the bit16 of register U1B0
358 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
359 if ((reg->U1B0 & 0x00010000)) {
360 pHwData->CurrentRadioHw = 1;
363 pHwData->CurrentRadioHw = 0;
368 static u8 LED_GRAY[20] = {
369 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
372 static u8 LED_GRAY2[30] = {
373 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
374 0, 15, 14, 13, 12, 11, 10, 9, 8
377 static void hal_led_control(unsigned long data)
379 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
380 struct hw_data *pHwData = &adapter->sHwData;
381 struct wb35_reg *reg = &pHwData->reg;
382 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
383 u32 TimeInterval = 500, ltmp, ltmp2;
386 if (pHwData->SurpriseRemove)
389 if (pHwData->LED_control) {
390 ltmp2 = pHwData->LED_control & 0xff;
391 if (ltmp2 == 5) // 5 is WPS mode
394 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
396 case 1: // [0.2 On][0.1 Off]...
397 pHwData->LED_Blinking %= 3;
398 ltmp = 0x1010; // Led 1 & 0 Green and Red
399 if (pHwData->LED_Blinking == 2) // Turn off
402 case 2: // [0.1 On][0.1 Off]...
403 pHwData->LED_Blinking %= 2;
404 ltmp = 0x0010; // Led 0 red color
405 if (pHwData->LED_Blinking) // Turn off
408 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]...
409 pHwData->LED_Blinking %= 15;
410 ltmp = 0x0010; // Led 0 red color
411 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) // Turn off 0.6 sec
414 case 4: // [300 On][ off ]
415 ltmp = 0x1000; // Led 1 Green color
416 if (pHwData->LED_Blinking >= 3000)
417 ltmp = 0; // led maybe on after 300sec * 32bit counter overlap.
420 pHwData->LED_Blinking++;
422 reg->U1BC_LEDConfigure = ltmp;
423 if (LEDSet != 7) // Only 111 mode has 2 LEDs on PCB.
425 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; // Copy LED result to each LED control register
426 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
428 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
430 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) // If radio off
432 if (reg->U1BC_LEDConfigure & 0x1010) {
433 reg->U1BC_LEDConfigure &= ~0x1010;
434 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
438 case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
439 if (!pHwData->LED_LinkOn) // Blink only if not Link On
441 // Blinking if scanning is on progress
442 if (pHwData->LED_Scanning) {
443 if (pHwData->LED_Blinking == 0) {
444 reg->U1BC_LEDConfigure |= 0x10;
445 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On
446 pHwData->LED_Blinking = 1;
449 reg->U1BC_LEDConfigure &= ~0x10;
450 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
451 pHwData->LED_Blinking = 0;
456 if (reg->U1BC_LEDConfigure & 0x10) {
457 reg->U1BC_LEDConfigure &= ~0x10;
458 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
463 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
464 reg->U1BC_LEDConfigure |= 0x10;
465 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
470 case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
471 if (!pHwData->LED_LinkOn) // Blink only if not Link On
473 // Blinking if scanning is on progress
474 if (pHwData->LED_Scanning) {
475 if (pHwData->LED_Blinking == 0) {
476 reg->U1BC_LEDConfigure &= ~0xf;
477 reg->U1BC_LEDConfigure |= 0x10;
478 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On
479 pHwData->LED_Blinking = 1;
482 reg->U1BC_LEDConfigure &= ~0x1f;
483 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
484 pHwData->LED_Blinking = 0;
488 // 20060901 Gray blinking if in disconnect state and not scanning
489 ltmp = reg->U1BC_LEDConfigure;
490 reg->U1BC_LEDConfigure &= ~0x1f;
491 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
492 reg->U1BC_LEDConfigure |= 0x10;
493 reg->U1BC_LEDConfigure |=
494 LED_GRAY2[(pHwData->LED_Blinking % 30)];
496 pHwData->LED_Blinking++;
497 if (reg->U1BC_LEDConfigure != ltmp)
498 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
503 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
504 reg->U1BC_LEDConfigure |= 0x10;
505 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
510 case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
511 if (!pHwData->LED_LinkOn) // Blink only if not Link On
513 // Blinking if scanning is on progress
514 if (pHwData->LED_Scanning) {
515 if (pHwData->LED_Blinking == 0) {
516 reg->U1BC_LEDConfigure |=
518 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On
519 pHwData->LED_Blinking = 1;
522 reg->U1BC_LEDConfigure &=
524 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off
525 pHwData->LED_Blinking = 0;
530 if (reg->U1BC_LEDConfigure & 0x1000) {
531 reg->U1BC_LEDConfigure &=
533 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off
537 // Is transmitting/receiving ??
538 if ((adapter->RxByteCount !=
539 pHwData->RxByteCountLast)
540 || (adapter->TxByteCount !=
541 pHwData->TxByteCountLast)) {
542 if ((reg->U1BC_LEDConfigure & 0x3000) !=
544 reg->U1BC_LEDConfigure |=
546 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On
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
568 default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
569 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
570 reg->U1BC_LEDConfigure |= 0x3000; // LED_1 is always on and event enable
571 Wb35Reg_Write(pHwData, 0x03bc,
572 reg->U1BC_LEDConfigure);
575 if (pHwData->LED_Blinking) {
577 reg->U1BC_LEDConfigure &= ~0x0f;
578 reg->U1BC_LEDConfigure |= 0x10;
579 reg->U1BC_LEDConfigure |=
580 LED_GRAY[(pHwData->LED_Blinking - 1) % 20];
581 Wb35Reg_Write(pHwData, 0x03bc,
582 reg->U1BC_LEDConfigure);
584 pHwData->LED_Blinking += 2;
585 if (pHwData->LED_Blinking < 40)
588 pHwData->LED_Blinking = 0; // Stop blinking
589 reg->U1BC_LEDConfigure &= ~0x0f;
590 Wb35Reg_Write(pHwData, 0x03bc,
591 reg->U1BC_LEDConfigure);
596 if (pHwData->LED_LinkOn) {
597 if (!(reg->U1BC_LEDConfigure & 0x10)) // Check the LED_0
599 //Try to turn ON LED_0 after gray blinking
600 reg->U1BC_LEDConfigure |= 0x10;
601 pHwData->LED_Blinking = 1; //Start blinking
605 if (reg->U1BC_LEDConfigure & 0x10) // Check the LED_0
607 reg->U1BC_LEDConfigure &= ~0x10;
608 Wb35Reg_Write(pHwData, 0x03bc,
609 reg->U1BC_LEDConfigure);
615 //20060828.1 Active send null packet to avoid AP disconnect
616 if (pHwData->LED_LinkOn) {
617 pHwData->NullPacketCount += TimeInterval;
618 if (pHwData->NullPacketCount >=
619 DEFAULT_NULL_PACKET_COUNT) {
620 pHwData->NullPacketCount = 0;
625 pHwData->time_count += TimeInterval;
626 Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add
627 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
628 add_timer(&pHwData->LEDTimer);
631 static int hal_init_hardware(struct ieee80211_hw *hw)
633 struct wbsoft_priv *priv = hw->priv;
634 struct hw_data *pHwData = &priv->sHwData;
637 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
638 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
640 if (!Wb35Reg_initial(pHwData))
641 goto error_reg_destroy;
643 if (!Wb35Tx_initial(pHwData))
644 goto error_tx_destroy;
646 if (!Wb35Rx_initial(pHwData))
647 goto error_rx_destroy;
649 init_timer(&pHwData->LEDTimer);
650 pHwData->LEDTimer.function = hal_led_control;
651 pHwData->LEDTimer.data = (unsigned long)priv;
652 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
653 add_timer(&pHwData->LEDTimer);
655 SoftwareSet = hal_software_set(pHwData);
658 // Try to make sure the EEPROM contain
660 if (SoftwareSet != 0x82)
665 Wb35Tx_EP2VM_start(priv);
670 Wb35Rx_destroy(pHwData);
672 Wb35Tx_destroy(pHwData);
674 Wb35Reg_destroy(pHwData);
676 pHwData->SurpriseRemove = 1;
680 static int wb35_hw_init(struct ieee80211_hw *hw)
682 struct wbsoft_priv *priv = hw->priv;
683 struct hw_data *pHwData = &priv->sHwData;
690 pHwData->phy_type = RF_DECIDE_BY_INF;
692 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
693 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
695 priv->sLocalPara.region_INF = REGION_AUTO;
696 priv->sLocalPara.TxRateMode = RATE_AUTO;
697 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG;
698 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
699 priv->sLocalPara.bPreambleMode = AUTO_MODE;
700 priv->sLocalPara.bWepKeyError = false;
701 priv->sLocalPara.bToSelfPacketReceived = false;
702 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
704 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
706 err = hal_init_hardware(hw);
710 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
711 if (EEPROM_region != REGION_AUTO)
712 priv->sLocalPara.region = EEPROM_region;
714 if (priv->sLocalPara.region_INF != REGION_AUTO)
715 priv->sLocalPara.region = priv->sLocalPara.region_INF;
717 priv->sLocalPara.region = REGION_USA; /* default setting */
723 * If no user-defined address in the registry, use the addresss
724 * "burned" on the NIC instead.
726 pMacAddr = priv->sLocalPara.ThisMacAddress;
727 pMacAddr2 = priv->sLocalPara.PermanentAddress;
729 /* Reading ethernet address from EEPROM */
730 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
731 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
732 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
734 /* Set the user define MAC address */
735 hal_set_ethernet_address(pHwData,
736 priv->sLocalPara.ThisMacAddress);
739 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
740 #ifdef _PE_STATE_DUMP_
741 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
743 hal_get_hw_radio_off(pHwData);
745 /* Waiting for HAL setting OK */
746 while (!hal_idle(pHwData))
751 HwRadioOff = hal_get_hw_radio_off(pHwData);
752 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
754 hal_set_radio_mode(pHwData,
755 (unsigned char)(priv->sLocalPara.RadioOffStatus.
757 || priv->sLocalPara.RadioOffStatus.
760 /* Notify hal that the driver is ready now. */
761 hal_driver_init_OK(pHwData) = 1;
767 static int wb35_probe(struct usb_interface *intf,
768 const struct usb_device_id *id_table)
770 struct usb_device *udev = interface_to_usbdev(intf);
771 struct usb_endpoint_descriptor *endpoint;
772 struct usb_host_interface *interface;
773 struct ieee80211_hw *dev;
774 struct wbsoft_priv *priv;
775 struct wb_usb *pWbUsb;
781 /* Check the device if it already be opened */
782 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
784 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
785 0x0, 0x400, <mp, 4, HZ * 100);
791 /* Is already initialized? */
792 ltmp = cpu_to_le32(ltmp);
798 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
806 spin_lock_init(&priv->SpinLock);
808 pWbUsb = &priv->sHwData.WbUsb;
811 interface = intf->cur_altsetting;
812 endpoint = &interface->endpoint[0].desc;
814 if (endpoint[2].wMaxPacketSize == 512) {
815 printk("[w35und] Working on USB 2.0\n");
819 err = wb35_hw_init(dev);
823 SET_IEEE80211_DEV(dev, &udev->dev);
825 struct hw_data *pHwData = &priv->sHwData;
826 unsigned char dev_addr[MAX_ADDR_LEN];
827 hal_get_permanent_address(pHwData, dev_addr);
828 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
831 dev->extra_tx_headroom = 12; /* FIXME */
832 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
833 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
835 dev->channel_change_time = 1000;
836 dev->max_signal = 100;
839 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
841 err = ieee80211_register_hw(dev);
845 usb_set_intfdata(intf, dev);
850 ieee80211_free_hw(dev);
856 static void hal_halt(struct hw_data *pHwData)
858 del_timer_sync(&pHwData->LEDTimer);
859 /* XXX: Wait for Timer DPC exit. */
861 Wb35Rx_destroy(pHwData);
862 Wb35Tx_destroy(pHwData);
863 Wb35Reg_destroy(pHwData);
866 static void wb35_hw_halt(struct wbsoft_priv *adapter)
868 Mds_Destroy(adapter);
870 /* Turn off Rx and Tx hardware ability */
871 hal_stop(&adapter->sHwData);
872 #ifdef _PE_USB_INI_DUMP_
873 printk("[w35und] Hal_stop O.K.\n");
875 /* Waiting Irp completed */
878 hal_halt(&adapter->sHwData);
881 static void wb35_disconnect(struct usb_interface *intf)
883 struct ieee80211_hw *hw = usb_get_intfdata(intf);
884 struct wbsoft_priv *priv = hw->priv;
888 ieee80211_stop_queues(hw);
889 ieee80211_unregister_hw(hw);
890 ieee80211_free_hw(hw);
892 usb_set_intfdata(intf, NULL);
893 usb_put_dev(interface_to_usbdev(intf));
896 static struct usb_driver wb35_driver = {
898 .id_table = wb35_table,
900 .disconnect = wb35_disconnect,
903 static int __init wb35_init(void)
905 return usb_register(&wb35_driver);
908 static void __exit wb35_exit(void)
910 usb_deregister(&wb35_driver);
913 module_init(wb35_init);
914 module_exit(wb35_exit);