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 int wbsoft_add_interface(struct ieee80211_hw *dev,
55 struct ieee80211_if_init_conf *conf)
57 printk("wbsoft_add interface called\n");
61 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
62 struct ieee80211_if_init_conf *conf)
64 printk("wbsoft_remove interface called\n");
67 static void wbsoft_stop(struct ieee80211_hw *hw)
69 printk(KERN_INFO "%s called\n", __func__);
72 static int wbsoft_get_stats(struct ieee80211_hw *hw,
73 struct ieee80211_low_level_stats *stats)
75 printk(KERN_INFO "%s called\n", __func__);
79 static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
80 struct ieee80211_tx_queue_stats *stats)
82 printk(KERN_INFO "%s called\n", __func__);
86 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
87 unsigned int changed_flags,
88 unsigned int *total_flags,
89 int mc_count, struct dev_mc_list *mclist)
91 unsigned int new_flags;
95 if (*total_flags & FIF_PROMISC_IN_BSS)
96 new_flags |= FIF_PROMISC_IN_BSS;
97 else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32))
98 new_flags |= FIF_ALLMULTI;
100 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
102 *total_flags = new_flags;
105 static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
107 struct wbsoft_priv *priv = dev->priv;
109 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
114 static int wbsoft_start(struct ieee80211_hw *dev)
116 struct wbsoft_priv *priv = dev->priv;
118 priv->enabled = true;
123 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
125 struct wb35_reg *reg = &pHwData->reg;
127 if (pHwData->SurpriseRemove)
130 if (radio_off) //disable Baseband receive off
132 pHwData->CurrentRadioSw = 1; // off
133 reg->M24_MacControl &= 0xffffffbf;
135 pHwData->CurrentRadioSw = 0; // on
136 reg->M24_MacControl |= 0x00000040;
138 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
141 static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
145 if (pHwData->SurpriseRemove)
148 pHwData->BeaconPeriod = beacon_period;
149 tmp = pHwData->BeaconPeriod << 16;
150 tmp |= pHwData->ProbeDelay;
151 Wb35Reg_Write(pHwData, 0x0848, tmp);
155 hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo 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,
174 (s8 *) & channel, sizeof(ChanInfo));
177 static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
179 hal_set_current_channel_ex(pHwData, channel);
182 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
184 struct wb35_reg *reg = &pHwData->reg;
186 if (pHwData->SurpriseRemove)
189 reg->M00_MacControl &= ~0x02000000; //The HW value
192 reg->M00_MacControl |= 0x02000000; //The HW value
194 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
197 //for wep key error detection, we need to accept broadcast packets to be received temporary.
198 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
200 struct wb35_reg *reg = &pHwData->reg;
202 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)
234 if (!enable) //Due to SME and MLME are not suitable for 35
237 reg->M00_MacControl &= ~0x04000000; //The HW value
239 reg->M00_MacControl |= 0x04000000; //The HW value
241 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
244 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
246 struct wbsoft_priv *priv = dev->priv;
247 struct ieee80211_conf *conf = &dev->conf;
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_beacon_period(&priv->sHwData, conf->beacon_int);
258 hal_set_accept_broadcast(&priv->sHwData, 1);
259 hal_set_accept_promiscuous(&priv->sHwData, 1);
260 hal_set_accept_multicast(&priv->sHwData, 1);
261 hal_set_accept_beacon(&priv->sHwData, 1);
262 hal_set_radio_mode(&priv->sHwData, 0);
267 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
269 printk("wbsoft_get_tsf called\n");
273 static const struct ieee80211_ops wbsoft_ops = {
275 .start = wbsoft_start,
277 .add_interface = wbsoft_add_interface,
278 .remove_interface = wbsoft_remove_interface,
279 .config = wbsoft_config,
280 .configure_filter = wbsoft_configure_filter,
281 .get_stats = wbsoft_get_stats,
282 .get_tx_stats = wbsoft_get_tx_stats,
283 .get_tsf = wbsoft_get_tsf,
287 hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address)
291 if (pHwData->SurpriseRemove)
294 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
296 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
298 cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
300 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
304 hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address)
306 if (pHwData->SurpriseRemove)
309 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
312 static void hal_stop(struct hw_data *pHwData)
314 struct wb35_reg *reg = &pHwData->reg;
316 pHwData->Wb35Rx.rx_halt = 1;
317 Wb35Rx_stop(pHwData);
319 pHwData->Wb35Tx.tx_halt = 1;
320 Wb35Tx_stop(pHwData);
322 reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off
323 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
326 static unsigned char hal_idle(struct hw_data *pHwData)
328 struct wb35_reg *reg = &pHwData->reg;
329 struct wb_usb *pWbUsb = &pHwData->WbUsb;
331 if (!pHwData->SurpriseRemove
332 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
338 u8 hal_get_antenna_number(struct hw_data *pHwData)
340 struct wb35_reg *reg = &pHwData->reg;
342 if ((reg->BB2C & BIT(11)) == 0)
348 /* 0 : radio on; 1: radio off */
349 static u8 hal_get_hw_radio_off(struct hw_data * pHwData)
351 struct wb35_reg *reg = &pHwData->reg;
353 if (pHwData->SurpriseRemove)
356 //read the bit16 of register U1B0
357 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
358 if ((reg->U1B0 & 0x00010000)) {
359 pHwData->CurrentRadioHw = 1;
362 pHwData->CurrentRadioHw = 0;
367 static u8 LED_GRAY[20] = {
368 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
371 static u8 LED_GRAY2[30] = {
372 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
373 0, 15, 14, 13, 12, 11, 10, 9, 8
376 static void hal_led_control(unsigned long data)
378 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
379 struct hw_data *pHwData = &adapter->sHwData;
380 struct wb35_reg *reg = &pHwData->reg;
381 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
382 u32 TimeInterval = 500, ltmp, ltmp2;
385 if (pHwData->SurpriseRemove)
388 if (pHwData->LED_control) {
389 ltmp2 = pHwData->LED_control & 0xff;
390 if (ltmp2 == 5) // 5 is WPS mode
393 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
395 case 1: // [0.2 On][0.1 Off]...
396 pHwData->LED_Blinking %= 3;
397 ltmp = 0x1010; // Led 1 & 0 Green and Red
398 if (pHwData->LED_Blinking == 2) // Turn off
401 case 2: // [0.1 On][0.1 Off]...
402 pHwData->LED_Blinking %= 2;
403 ltmp = 0x0010; // Led 0 red color
404 if (pHwData->LED_Blinking) // Turn off
407 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]...
408 pHwData->LED_Blinking %= 15;
409 ltmp = 0x0010; // Led 0 red color
410 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) // Turn off 0.6 sec
413 case 4: // [300 On][ off ]
414 ltmp = 0x1000; // Led 1 Green color
415 if (pHwData->LED_Blinking >= 3000)
416 ltmp = 0; // led maybe on after 300sec * 32bit counter overlap.
419 pHwData->LED_Blinking++;
421 reg->U1BC_LEDConfigure = ltmp;
422 if (LEDSet != 7) // Only 111 mode has 2 LEDs on PCB.
424 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; // Copy LED result to each LED control register
425 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
427 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
429 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) // If radio off
431 if (reg->U1BC_LEDConfigure & 0x1010) {
432 reg->U1BC_LEDConfigure &= ~0x1010;
433 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
437 case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
438 if (!pHwData->LED_LinkOn) // Blink only if not Link On
440 // Blinking if scanning is on progress
441 if (pHwData->LED_Scanning) {
442 if (pHwData->LED_Blinking == 0) {
443 reg->U1BC_LEDConfigure |= 0x10;
444 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On
445 pHwData->LED_Blinking = 1;
448 reg->U1BC_LEDConfigure &= ~0x10;
449 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
450 pHwData->LED_Blinking = 0;
455 if (reg->U1BC_LEDConfigure & 0x10) {
456 reg->U1BC_LEDConfigure &= ~0x10;
457 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
462 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
463 reg->U1BC_LEDConfigure |= 0x10;
464 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
469 case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
470 if (!pHwData->LED_LinkOn) // Blink only if not Link On
472 // Blinking if scanning is on progress
473 if (pHwData->LED_Scanning) {
474 if (pHwData->LED_Blinking == 0) {
475 reg->U1BC_LEDConfigure &= ~0xf;
476 reg->U1BC_LEDConfigure |= 0x10;
477 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On
478 pHwData->LED_Blinking = 1;
481 reg->U1BC_LEDConfigure &= ~0x1f;
482 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
483 pHwData->LED_Blinking = 0;
487 // 20060901 Gray blinking if in disconnect state and not scanning
488 ltmp = reg->U1BC_LEDConfigure;
489 reg->U1BC_LEDConfigure &= ~0x1f;
490 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
491 reg->U1BC_LEDConfigure |= 0x10;
492 reg->U1BC_LEDConfigure |=
493 LED_GRAY2[(pHwData->LED_Blinking % 30)];
495 pHwData->LED_Blinking++;
496 if (reg->U1BC_LEDConfigure != ltmp)
497 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
502 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
503 reg->U1BC_LEDConfigure |= 0x10;
504 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off
509 case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
510 if (!pHwData->LED_LinkOn) // Blink only if not Link On
512 // Blinking if scanning is on progress
513 if (pHwData->LED_Scanning) {
514 if (pHwData->LED_Blinking == 0) {
515 reg->U1BC_LEDConfigure |=
517 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On
518 pHwData->LED_Blinking = 1;
521 reg->U1BC_LEDConfigure &=
523 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off
524 pHwData->LED_Blinking = 0;
529 if (reg->U1BC_LEDConfigure & 0x1000) {
530 reg->U1BC_LEDConfigure &=
532 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off
536 // Is transmitting/receiving ??
537 if ((adapter->RxByteCount !=
538 pHwData->RxByteCountLast)
539 || (adapter->TxByteCount !=
540 pHwData->TxByteCountLast)) {
541 if ((reg->U1BC_LEDConfigure & 0x3000) !=
543 reg->U1BC_LEDConfigure |=
545 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On
548 pHwData->RxByteCountLast =
549 adapter->RxByteCount;
550 pHwData->TxByteCountLast =
551 adapter->TxByteCount;
554 // Turn On LED_1 and blinking if transmitting/receiving
555 if ((reg->U1BC_LEDConfigure & 0x3000) !=
557 reg->U1BC_LEDConfigure &=
559 reg->U1BC_LEDConfigure |=
561 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
598 //Try to turn ON LED_0 after gray blinking
599 reg->U1BC_LEDConfigure |= 0x10;
600 pHwData->LED_Blinking = 1; //Start blinking
604 if (reg->U1BC_LEDConfigure & 0x10) // Check the LED_0
606 reg->U1BC_LEDConfigure &= ~0x10;
607 Wb35Reg_Write(pHwData, 0x03bc,
608 reg->U1BC_LEDConfigure);
614 //20060828.1 Active send null packet to avoid AP disconnect
615 if (pHwData->LED_LinkOn) {
616 pHwData->NullPacketCount += TimeInterval;
617 if (pHwData->NullPacketCount >=
618 DEFAULT_NULL_PACKET_COUNT) {
619 pHwData->NullPacketCount = 0;
624 pHwData->time_count += TimeInterval;
625 Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add
626 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
627 add_timer(&pHwData->LEDTimer);
630 static int hal_init_hardware(struct ieee80211_hw *hw)
632 struct wbsoft_priv *priv = hw->priv;
633 struct hw_data *pHwData = &priv->sHwData;
636 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
637 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
639 if (!Wb35Reg_initial(pHwData))
640 goto error_reg_destroy;
642 if (!Wb35Tx_initial(pHwData))
643 goto error_tx_destroy;
645 if (!Wb35Rx_initial(pHwData))
646 goto error_rx_destroy;
648 init_timer(&pHwData->LEDTimer);
649 pHwData->LEDTimer.function = hal_led_control;
650 pHwData->LEDTimer.data = (unsigned long)priv;
651 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
652 add_timer(&pHwData->LEDTimer);
654 SoftwareSet = hal_software_set(pHwData);
657 // Try to make sure the EEPROM contain
659 if (SoftwareSet != 0x82)
664 Wb35Tx_EP2VM_start(priv);
669 Wb35Rx_destroy(pHwData);
671 Wb35Tx_destroy(pHwData);
673 Wb35Reg_destroy(pHwData);
675 pHwData->SurpriseRemove = 1;
679 static int wb35_hw_init(struct ieee80211_hw *hw)
681 struct wbsoft_priv *priv = hw->priv;
682 struct hw_data *pHwData = &priv->sHwData;
689 pHwData->phy_type = RF_DECIDE_BY_INF;
691 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
692 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
694 priv->sLocalPara.region_INF = REGION_AUTO;
695 priv->sLocalPara.TxRateMode = RATE_AUTO;
696 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG;
697 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
698 priv->sLocalPara.bPreambleMode = AUTO_MODE;
699 priv->sLocalPara.bWepKeyError = false;
700 priv->sLocalPara.bToSelfPacketReceived = false;
701 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
703 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
705 err = hal_init_hardware(hw);
709 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
710 if (EEPROM_region != REGION_AUTO)
711 priv->sLocalPara.region = EEPROM_region;
713 if (priv->sLocalPara.region_INF != REGION_AUTO)
714 priv->sLocalPara.region = priv->sLocalPara.region_INF;
716 priv->sLocalPara.region = REGION_USA; /* default setting */
719 // Get Software setting flag from hal
720 priv->sLocalPara.boAntennaDiversity = false;
721 if (hal_software_set(pHwData) & 0x00000001)
722 priv->sLocalPara.boAntennaDiversity = true;
727 * If no user-defined address in the registry, use the addresss
728 * "burned" on the NIC instead.
730 pMacAddr = priv->sLocalPara.ThisMacAddress;
731 pMacAddr2 = priv->sLocalPara.PermanentAddress;
733 /* Reading ethernet address from EEPROM */
734 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
735 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
736 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
738 /* Set the user define MAC address */
739 hal_set_ethernet_address(pHwData,
740 priv->sLocalPara.ThisMacAddress);
743 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
744 #ifdef _PE_STATE_DUMP_
745 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
747 hal_get_hw_radio_off(pHwData);
749 /* Waiting for HAL setting OK */
750 while (!hal_idle(pHwData))
755 HwRadioOff = hal_get_hw_radio_off(pHwData);
756 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
758 hal_set_radio_mode(pHwData,
759 (unsigned char)(priv->sLocalPara.RadioOffStatus.
761 || priv->sLocalPara.RadioOffStatus.
764 /* Notify hal that the driver is ready now. */
765 hal_driver_init_OK(pHwData) = 1;
771 static int wb35_probe(struct usb_interface *intf,
772 const struct usb_device_id *id_table)
774 struct usb_device *udev = interface_to_usbdev(intf);
775 struct usb_endpoint_descriptor *endpoint;
776 struct usb_host_interface *interface;
777 struct ieee80211_hw *dev;
778 struct wbsoft_priv *priv;
779 struct wb_usb *pWbUsb;
785 /* Check the device if it already be opened */
786 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
788 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
789 0x0, 0x400, <mp, 4, HZ * 100);
795 /* Is already initialized? */
796 ltmp = cpu_to_le32(ltmp);
802 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
810 spin_lock_init(&priv->SpinLock);
812 pWbUsb = &priv->sHwData.WbUsb;
815 interface = intf->cur_altsetting;
816 endpoint = &interface->endpoint[0].desc;
818 if (endpoint[2].wMaxPacketSize == 512) {
819 printk("[w35und] Working on USB 2.0\n");
823 err = wb35_hw_init(dev);
827 SET_IEEE80211_DEV(dev, &udev->dev);
829 struct hw_data *pHwData = &priv->sHwData;
830 unsigned char dev_addr[MAX_ADDR_LEN];
831 hal_get_permanent_address(pHwData, dev_addr);
832 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
835 dev->extra_tx_headroom = 12; /* FIXME */
836 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
837 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
839 dev->channel_change_time = 1000;
840 dev->max_signal = 100;
843 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
845 err = ieee80211_register_hw(dev);
849 usb_set_intfdata(intf, dev);
854 ieee80211_free_hw(dev);
860 static void hal_halt(struct hw_data *pHwData)
862 del_timer_sync(&pHwData->LEDTimer);
863 /* XXX: Wait for Timer DPC exit. */
865 Wb35Rx_destroy(pHwData);
866 Wb35Tx_destroy(pHwData);
867 Wb35Reg_destroy(pHwData);
870 static void wb35_hw_halt(struct wbsoft_priv *adapter)
872 Mds_Destroy(adapter);
874 /* Turn off Rx and Tx hardware ability */
875 hal_stop(&adapter->sHwData);
876 #ifdef _PE_USB_INI_DUMP_
877 printk("[w35und] Hal_stop O.K.\n");
879 /* Waiting Irp completed */
882 hal_halt(&adapter->sHwData);
885 static void wb35_disconnect(struct usb_interface *intf)
887 struct ieee80211_hw *hw = usb_get_intfdata(intf);
888 struct wbsoft_priv *priv = hw->priv;
892 ieee80211_stop_queues(hw);
893 ieee80211_unregister_hw(hw);
894 ieee80211_free_hw(hw);
896 usb_set_intfdata(intf, NULL);
897 usb_put_dev(interface_to_usbdev(intf));
900 static struct usb_driver wb35_driver = {
902 .id_table = wb35_table,
904 .disconnect = wb35_disconnect,
907 static int __init wb35_init(void)
909 return usb_register(&wb35_driver);
912 static void __exit wb35_exit(void)
914 usb_deregister(&wb35_driver);
917 module_init(wb35_init);
918 module_exit(wb35_exit);