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 u64
wbsoft_prepare_multicast(struct ieee80211_hw
*hw
, int mc_count
,
103 struct dev_addr_list
*mc_list
)
108 static void wbsoft_configure_filter(struct ieee80211_hw
*dev
,
109 unsigned int changed_flags
,
110 unsigned int *total_flags
,
113 unsigned int new_flags
;
117 if (*total_flags
& FIF_PROMISC_IN_BSS
)
118 new_flags
|= FIF_PROMISC_IN_BSS
;
119 else if ((*total_flags
& FIF_ALLMULTI
) || (multicast
> 32))
120 new_flags
|= FIF_ALLMULTI
;
122 dev
->flags
&= ~IEEE80211_HW_RX_INCLUDES_FCS
;
124 *total_flags
= new_flags
;
127 static int wbsoft_tx(struct ieee80211_hw
*dev
, struct sk_buff
*skb
)
129 struct wbsoft_priv
*priv
= dev
->priv
;
131 MLMESendFrame(priv
, skb
->data
, skb
->len
, FRAME_TYPE_802_11_MANAGEMENT
);
136 static int wbsoft_start(struct ieee80211_hw
*dev
)
138 struct wbsoft_priv
*priv
= dev
->priv
;
140 priv
->enabled
= true;
145 static void hal_set_radio_mode(struct hw_data
*pHwData
, unsigned char radio_off
)
147 struct wb35_reg
*reg
= &pHwData
->reg
;
149 if (pHwData
->SurpriseRemove
)
152 if (radio_off
) //disable Baseband receive off
154 pHwData
->CurrentRadioSw
= 1; // off
155 reg
->M24_MacControl
&= 0xffffffbf;
157 pHwData
->CurrentRadioSw
= 0; // on
158 reg
->M24_MacControl
|= 0x00000040;
160 Wb35Reg_Write(pHwData
, 0x0824, reg
->M24_MacControl
);
164 hal_set_current_channel_ex(struct hw_data
*pHwData
, ChanInfo channel
)
166 struct wb35_reg
*reg
= &pHwData
->reg
;
168 if (pHwData
->SurpriseRemove
)
171 printk("Going to channel: %d/%d\n", channel
.band
, channel
.ChanNo
);
173 RFSynthesizer_SwitchingChannel(pHwData
, channel
); // Switch channel
174 pHwData
->Channel
= channel
.ChanNo
;
175 pHwData
->band
= channel
.band
;
176 #ifdef _PE_STATE_DUMP_
177 printk("Set channel is %d, band =%d\n", pHwData
->Channel
,
180 reg
->M28_MacControl
&= ~0xff; // Clean channel information field
181 reg
->M28_MacControl
|= channel
.ChanNo
;
182 Wb35Reg_WriteWithCallbackValue(pHwData
, 0x0828, reg
->M28_MacControl
,
183 (s8
*) & channel
, sizeof(ChanInfo
));
186 static void hal_set_current_channel(struct hw_data
*pHwData
, ChanInfo channel
)
188 hal_set_current_channel_ex(pHwData
, channel
);
191 static void hal_set_accept_broadcast(struct hw_data
*pHwData
, u8 enable
)
193 struct wb35_reg
*reg
= &pHwData
->reg
;
195 if (pHwData
->SurpriseRemove
)
198 reg
->M00_MacControl
&= ~0x02000000; //The HW value
201 reg
->M00_MacControl
|= 0x02000000; //The HW value
203 Wb35Reg_Write(pHwData
, 0x0800, reg
->M00_MacControl
);
206 //for wep key error detection, we need to accept broadcast packets to be received temporary.
207 static void hal_set_accept_promiscuous(struct hw_data
*pHwData
, u8 enable
)
209 struct wb35_reg
*reg
= &pHwData
->reg
;
211 if (pHwData
->SurpriseRemove
)
214 reg
->M00_MacControl
|= 0x00400000;
215 Wb35Reg_Write(pHwData
, 0x0800, reg
->M00_MacControl
);
217 reg
->M00_MacControl
&= ~0x00400000;
218 Wb35Reg_Write(pHwData
, 0x0800, reg
->M00_MacControl
);
222 static void hal_set_accept_multicast(struct hw_data
*pHwData
, u8 enable
)
224 struct wb35_reg
*reg
= &pHwData
->reg
;
226 if (pHwData
->SurpriseRemove
)
229 reg
->M00_MacControl
&= ~0x01000000; //The HW value
231 reg
->M00_MacControl
|= 0x01000000; //The HW value
232 Wb35Reg_Write(pHwData
, 0x0800, reg
->M00_MacControl
);
235 static void hal_set_accept_beacon(struct hw_data
*pHwData
, u8 enable
)
237 struct wb35_reg
*reg
= &pHwData
->reg
;
239 if (pHwData
->SurpriseRemove
)
243 if (!enable
) //Due to SME and MLME are not suitable for 35
246 reg
->M00_MacControl
&= ~0x04000000; //The HW value
248 reg
->M00_MacControl
|= 0x04000000; //The HW value
250 Wb35Reg_Write(pHwData
, 0x0800, reg
->M00_MacControl
);
253 static int wbsoft_config(struct ieee80211_hw
*dev
, u32 changed
)
255 struct wbsoft_priv
*priv
= dev
->priv
;
258 printk("wbsoft_config called\n");
260 /* Should use channel_num, or something, as that is already pre-translated */
264 hal_set_current_channel(&priv
->sHwData
, ch
);
265 hal_set_accept_broadcast(&priv
->sHwData
, 1);
266 hal_set_accept_promiscuous(&priv
->sHwData
, 1);
267 hal_set_accept_multicast(&priv
->sHwData
, 1);
268 hal_set_accept_beacon(&priv
->sHwData
, 1);
269 hal_set_radio_mode(&priv
->sHwData
, 0);
274 static u64
wbsoft_get_tsf(struct ieee80211_hw
*dev
)
276 printk("wbsoft_get_tsf called\n");
280 static const struct ieee80211_ops wbsoft_ops
= {
282 .start
= wbsoft_start
,
284 .add_interface
= wbsoft_add_interface
,
285 .remove_interface
= wbsoft_remove_interface
,
286 .config
= wbsoft_config
,
287 .prepare_multicast
= wbsoft_prepare_multicast
,
288 .configure_filter
= wbsoft_configure_filter
,
289 .get_stats
= wbsoft_get_stats
,
290 .get_tx_stats
= wbsoft_get_tx_stats
,
291 .get_tsf
= wbsoft_get_tsf
,
295 hal_set_ethernet_address(struct hw_data
*pHwData
, u8
* current_address
)
299 if (pHwData
->SurpriseRemove
)
302 memcpy(pHwData
->CurrentMacAddress
, current_address
, ETH_ALEN
);
304 ltmp
[0] = cpu_to_le32(*(u32
*) pHwData
->CurrentMacAddress
);
306 cpu_to_le32(*(u32
*) (pHwData
->CurrentMacAddress
+ 4)) & 0xffff;
308 Wb35Reg_BurstWrite(pHwData
, 0x03e8, ltmp
, 2, AUTO_INCREMENT
);
312 hal_get_permanent_address(struct hw_data
*pHwData
, u8
* pethernet_address
)
314 if (pHwData
->SurpriseRemove
)
317 memcpy(pethernet_address
, pHwData
->PermanentMacAddress
, 6);
320 static void hal_stop(struct hw_data
*pHwData
)
322 struct wb35_reg
*reg
= &pHwData
->reg
;
324 pHwData
->Wb35Rx
.rx_halt
= 1;
325 Wb35Rx_stop(pHwData
);
327 pHwData
->Wb35Tx
.tx_halt
= 1;
328 Wb35Tx_stop(pHwData
);
330 reg
->D00_DmaControl
&= ~0xc0000000; //Tx Off, Rx Off
331 Wb35Reg_Write(pHwData
, 0x0400, reg
->D00_DmaControl
);
334 static unsigned char hal_idle(struct hw_data
*pHwData
)
336 struct wb35_reg
*reg
= &pHwData
->reg
;
337 struct wb_usb
*pWbUsb
= &pHwData
->WbUsb
;
339 if (!pHwData
->SurpriseRemove
340 && (pWbUsb
->DetectCount
|| reg
->EP0vm_state
!= VM_STOP
))
346 u8
hal_get_antenna_number(struct hw_data
*pHwData
)
348 struct wb35_reg
*reg
= &pHwData
->reg
;
350 if ((reg
->BB2C
& BIT(11)) == 0)
356 /* 0 : radio on; 1: radio off */
357 static u8
hal_get_hw_radio_off(struct hw_data
* pHwData
)
359 struct wb35_reg
*reg
= &pHwData
->reg
;
361 if (pHwData
->SurpriseRemove
)
364 //read the bit16 of register U1B0
365 Wb35Reg_Read(pHwData
, 0x3b0, ®
->U1B0
);
366 if ((reg
->U1B0
& 0x00010000)) {
367 pHwData
->CurrentRadioHw
= 1;
370 pHwData
->CurrentRadioHw
= 0;
375 static u8 LED_GRAY
[20] = {
376 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
379 static u8 LED_GRAY2
[30] = {
380 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
381 0, 15, 14, 13, 12, 11, 10, 9, 8
384 static void hal_led_control(unsigned long data
)
386 struct wbsoft_priv
*adapter
= (struct wbsoft_priv
*)data
;
387 struct hw_data
*pHwData
= &adapter
->sHwData
;
388 struct wb35_reg
*reg
= &pHwData
->reg
;
389 u32 LEDSet
= (pHwData
->SoftwareSet
& HAL_LED_SET_MASK
) >> HAL_LED_SET_SHIFT
;
390 u32 TimeInterval
= 500, ltmp
, ltmp2
;
393 if (pHwData
->SurpriseRemove
)
396 if (pHwData
->LED_control
) {
397 ltmp2
= pHwData
->LED_control
& 0xff;
398 if (ltmp2
== 5) // 5 is WPS mode
401 ltmp2
= (pHwData
->LED_control
>> 8) & 0xff;
403 case 1: // [0.2 On][0.1 Off]...
404 pHwData
->LED_Blinking
%= 3;
405 ltmp
= 0x1010; // Led 1 & 0 Green and Red
406 if (pHwData
->LED_Blinking
== 2) // Turn off
409 case 2: // [0.1 On][0.1 Off]...
410 pHwData
->LED_Blinking
%= 2;
411 ltmp
= 0x0010; // Led 0 red color
412 if (pHwData
->LED_Blinking
) // Turn off
415 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]...
416 pHwData
->LED_Blinking
%= 15;
417 ltmp
= 0x0010; // Led 0 red color
418 if ((pHwData
->LED_Blinking
>= 9) || (pHwData
->LED_Blinking
% 2)) // Turn off 0.6 sec
421 case 4: // [300 On][ off ]
422 ltmp
= 0x1000; // Led 1 Green color
423 if (pHwData
->LED_Blinking
>= 3000)
424 ltmp
= 0; // led maybe on after 300sec * 32bit counter overlap.
427 pHwData
->LED_Blinking
++;
429 reg
->U1BC_LEDConfigure
= ltmp
;
430 if (LEDSet
!= 7) // Only 111 mode has 2 LEDs on PCB.
432 reg
->U1BC_LEDConfigure
|= (ltmp
& 0xff) << 8; // Copy LED result to each LED control register
433 reg
->U1BC_LEDConfigure
|= (ltmp
& 0xff00) >> 8;
435 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
437 } else if (pHwData
->CurrentRadioSw
|| pHwData
->CurrentRadioHw
) // If radio off
439 if (reg
->U1BC_LEDConfigure
& 0x1010) {
440 reg
->U1BC_LEDConfigure
&= ~0x1010;
441 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
445 case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
446 if (!pHwData
->LED_LinkOn
) // Blink only if not Link On
448 // Blinking if scanning is on progress
449 if (pHwData
->LED_Scanning
) {
450 if (pHwData
->LED_Blinking
== 0) {
451 reg
->U1BC_LEDConfigure
|= 0x10;
452 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 On
453 pHwData
->LED_Blinking
= 1;
456 reg
->U1BC_LEDConfigure
&= ~0x10;
457 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
458 pHwData
->LED_Blinking
= 0;
463 if (reg
->U1BC_LEDConfigure
& 0x10) {
464 reg
->U1BC_LEDConfigure
&= ~0x10;
465 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
470 if ((reg
->U1BC_LEDConfigure
& 0x10) == 0) {
471 reg
->U1BC_LEDConfigure
|= 0x10;
472 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
480 // Blinking if scanning is on progress
481 if (pHwData
->LED_Scanning
) {
482 if (pHwData
->LED_Blinking
== 0) {
483 reg
->U1BC_LEDConfigure
&= ~0xf;
484 reg
->U1BC_LEDConfigure
|= 0x10;
485 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 On
486 pHwData
->LED_Blinking
= 1;
489 reg
->U1BC_LEDConfigure
&= ~0x1f;
490 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
491 pHwData
->LED_Blinking
= 0;
495 // 20060901 Gray blinking if in disconnect state and not scanning
496 ltmp
= reg
->U1BC_LEDConfigure
;
497 reg
->U1BC_LEDConfigure
&= ~0x1f;
498 if (LED_GRAY2
[(pHwData
->LED_Blinking
% 30)]) {
499 reg
->U1BC_LEDConfigure
|= 0x10;
500 reg
->U1BC_LEDConfigure
|=
501 LED_GRAY2
[(pHwData
->LED_Blinking
% 30)];
503 pHwData
->LED_Blinking
++;
504 if (reg
->U1BC_LEDConfigure
!= ltmp
)
505 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
510 if ((reg
->U1BC_LEDConfigure
& 0x10) == 0) {
511 reg
->U1BC_LEDConfigure
|= 0x10;
512 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
517 case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
518 if (!pHwData
->LED_LinkOn
) // Blink only if not Link On
520 // Blinking if scanning is on progress
521 if (pHwData
->LED_Scanning
) {
522 if (pHwData
->LED_Blinking
== 0) {
523 reg
->U1BC_LEDConfigure
|=
525 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
526 pHwData
->LED_Blinking
= 1;
529 reg
->U1BC_LEDConfigure
&=
531 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 Off
532 pHwData
->LED_Blinking
= 0;
537 if (reg
->U1BC_LEDConfigure
& 0x1000) {
538 reg
->U1BC_LEDConfigure
&=
540 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 Off
544 // Is transmitting/receiving ??
545 if ((adapter
->RxByteCount
!=
546 pHwData
->RxByteCountLast
)
547 || (adapter
->TxByteCount
!=
548 pHwData
->TxByteCountLast
)) {
549 if ((reg
->U1BC_LEDConfigure
& 0x3000) !=
551 reg
->U1BC_LEDConfigure
|=
553 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
556 pHwData
->RxByteCountLast
=
557 adapter
->RxByteCount
;
558 pHwData
->TxByteCountLast
=
559 adapter
->TxByteCount
;
562 // Turn On LED_1 and blinking if transmitting/receiving
563 if ((reg
->U1BC_LEDConfigure
& 0x3000) !=
565 reg
->U1BC_LEDConfigure
&=
567 reg
->U1BC_LEDConfigure
|=
569 Wb35Reg_Write(pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
575 default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
576 if ((reg
->U1BC_LEDConfigure
& 0x3000) != 0x3000) {
577 reg
->U1BC_LEDConfigure
|= 0x3000; // LED_1 is always on and event enable
578 Wb35Reg_Write(pHwData
, 0x03bc,
579 reg
->U1BC_LEDConfigure
);
582 if (pHwData
->LED_Blinking
) {
584 reg
->U1BC_LEDConfigure
&= ~0x0f;
585 reg
->U1BC_LEDConfigure
|= 0x10;
586 reg
->U1BC_LEDConfigure
|=
587 LED_GRAY
[(pHwData
->LED_Blinking
- 1) % 20];
588 Wb35Reg_Write(pHwData
, 0x03bc,
589 reg
->U1BC_LEDConfigure
);
591 pHwData
->LED_Blinking
+= 2;
592 if (pHwData
->LED_Blinking
< 40)
595 pHwData
->LED_Blinking
= 0; // Stop blinking
596 reg
->U1BC_LEDConfigure
&= ~0x0f;
597 Wb35Reg_Write(pHwData
, 0x03bc,
598 reg
->U1BC_LEDConfigure
);
603 if (pHwData
->LED_LinkOn
) {
604 if (!(reg
->U1BC_LEDConfigure
& 0x10)) // Check the LED_0
606 //Try to turn ON LED_0 after gray blinking
607 reg
->U1BC_LEDConfigure
|= 0x10;
608 pHwData
->LED_Blinking
= 1; //Start blinking
612 if (reg
->U1BC_LEDConfigure
& 0x10) // Check the LED_0
614 reg
->U1BC_LEDConfigure
&= ~0x10;
615 Wb35Reg_Write(pHwData
, 0x03bc,
616 reg
->U1BC_LEDConfigure
);
622 //20060828.1 Active send null packet to avoid AP disconnect
623 if (pHwData
->LED_LinkOn
) {
624 pHwData
->NullPacketCount
+= TimeInterval
;
625 if (pHwData
->NullPacketCount
>=
626 DEFAULT_NULL_PACKET_COUNT
) {
627 pHwData
->NullPacketCount
= 0;
632 pHwData
->time_count
+= TimeInterval
;
633 Wb35Tx_CurrentTime(adapter
, pHwData
->time_count
); // 20060928 add
634 pHwData
->LEDTimer
.expires
= jiffies
+ msecs_to_jiffies(TimeInterval
);
635 add_timer(&pHwData
->LEDTimer
);
638 static int hal_init_hardware(struct ieee80211_hw
*hw
)
640 struct wbsoft_priv
*priv
= hw
->priv
;
641 struct hw_data
*pHwData
= &priv
->sHwData
;
644 pHwData
->MaxReceiveLifeTime
= DEFAULT_MSDU_LIFE_TIME
;
645 pHwData
->FragmentThreshold
= DEFAULT_FRAGMENT_THRESHOLD
;
647 if (!Wb35Reg_initial(pHwData
))
648 goto error_reg_destroy
;
650 if (!Wb35Tx_initial(pHwData
))
651 goto error_tx_destroy
;
653 if (!Wb35Rx_initial(pHwData
))
654 goto error_rx_destroy
;
656 init_timer(&pHwData
->LEDTimer
);
657 pHwData
->LEDTimer
.function
= hal_led_control
;
658 pHwData
->LEDTimer
.data
= (unsigned long)priv
;
659 pHwData
->LEDTimer
.expires
= jiffies
+ msecs_to_jiffies(1000);
660 add_timer(&pHwData
->LEDTimer
);
662 SoftwareSet
= hal_software_set(pHwData
);
665 // Try to make sure the EEPROM contain
667 if (SoftwareSet
!= 0x82)
672 Wb35Tx_EP2VM_start(priv
);
677 Wb35Rx_destroy(pHwData
);
679 Wb35Tx_destroy(pHwData
);
681 Wb35Reg_destroy(pHwData
);
683 pHwData
->SurpriseRemove
= 1;
687 static int wb35_hw_init(struct ieee80211_hw
*hw
)
689 struct wbsoft_priv
*priv
= hw
->priv
;
690 struct hw_data
*pHwData
= &priv
->sHwData
;
697 pHwData
->phy_type
= RF_DECIDE_BY_INF
;
699 priv
->Mds
.TxRTSThreshold
= DEFAULT_RTSThreshold
;
700 priv
->Mds
.TxFragmentThreshold
= DEFAULT_FRAGMENT_THRESHOLD
;
702 priv
->sLocalPara
.region_INF
= REGION_AUTO
;
703 priv
->sLocalPara
.TxRateMode
= RATE_AUTO
;
704 priv
->sLocalPara
.bMacOperationMode
= MODE_802_11_BG
;
705 priv
->sLocalPara
.MTUsize
= MAX_ETHERNET_PACKET_SIZE
;
706 priv
->sLocalPara
.bPreambleMode
= AUTO_MODE
;
707 priv
->sLocalPara
.bWepKeyError
= false;
708 priv
->sLocalPara
.bToSelfPacketReceived
= false;
709 priv
->sLocalPara
.WepKeyDetectTimerCount
= 2 * 100; /* 2 seconds */
711 priv
->sLocalPara
.RadioOffStatus
.boSwRadioOff
= false;
713 err
= hal_init_hardware(hw
);
717 EEPROM_region
= hal_get_region_from_EEPROM(pHwData
);
718 if (EEPROM_region
!= REGION_AUTO
)
719 priv
->sLocalPara
.region
= EEPROM_region
;
721 if (priv
->sLocalPara
.region_INF
!= REGION_AUTO
)
722 priv
->sLocalPara
.region
= priv
->sLocalPara
.region_INF
;
724 priv
->sLocalPara
.region
= REGION_USA
; /* default setting */
730 * If no user-defined address in the registry, use the addresss
731 * "burned" on the NIC instead.
733 pMacAddr
= priv
->sLocalPara
.ThisMacAddress
;
734 pMacAddr2
= priv
->sLocalPara
.PermanentAddress
;
736 /* Reading ethernet address from EEPROM */
737 hal_get_permanent_address(pHwData
, priv
->sLocalPara
.PermanentAddress
);
738 if (memcmp(pMacAddr
, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH
) == 0)
739 memcpy(pMacAddr
, pMacAddr2
, MAC_ADDR_LENGTH
);
741 /* Set the user define MAC address */
742 hal_set_ethernet_address(pHwData
,
743 priv
->sLocalPara
.ThisMacAddress
);
746 priv
->sLocalPara
.bAntennaNo
= hal_get_antenna_number(pHwData
);
747 #ifdef _PE_STATE_DUMP_
748 printk("Driver init, antenna no = %d\n", psLOCAL
->bAntennaNo
);
750 hal_get_hw_radio_off(pHwData
);
752 /* Waiting for HAL setting OK */
753 while (!hal_idle(pHwData
))
758 HwRadioOff
= hal_get_hw_radio_off(pHwData
);
759 priv
->sLocalPara
.RadioOffStatus
.boHwRadioOff
= !!HwRadioOff
;
761 hal_set_radio_mode(pHwData
,
762 (unsigned char)(priv
->sLocalPara
.RadioOffStatus
.
764 || priv
->sLocalPara
.RadioOffStatus
.
767 /* Notify hal that the driver is ready now. */
768 hal_driver_init_OK(pHwData
) = 1;
774 static int wb35_probe(struct usb_interface
*intf
,
775 const struct usb_device_id
*id_table
)
777 struct usb_device
*udev
= interface_to_usbdev(intf
);
778 struct usb_endpoint_descriptor
*endpoint
;
779 struct usb_host_interface
*interface
;
780 struct ieee80211_hw
*dev
;
781 struct wbsoft_priv
*priv
;
782 struct wb_usb
*pWbUsb
;
788 /* Check the device if it already be opened */
789 nr
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
791 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
| USB_DIR_IN
,
792 0x0, 0x400, <mp
, 4, HZ
* 100);
798 /* Is already initialized? */
799 ltmp
= cpu_to_le32(ltmp
);
805 dev
= ieee80211_alloc_hw(sizeof(*priv
), &wbsoft_ops
);
813 spin_lock_init(&priv
->SpinLock
);
815 pWbUsb
= &priv
->sHwData
.WbUsb
;
818 interface
= intf
->cur_altsetting
;
819 endpoint
= &interface
->endpoint
[0].desc
;
821 if (endpoint
[2].wMaxPacketSize
== 512) {
822 printk("[w35und] Working on USB 2.0\n");
826 err
= wb35_hw_init(dev
);
830 SET_IEEE80211_DEV(dev
, &udev
->dev
);
832 struct hw_data
*pHwData
= &priv
->sHwData
;
833 unsigned char dev_addr
[MAX_ADDR_LEN
];
834 hal_get_permanent_address(pHwData
, dev_addr
);
835 SET_IEEE80211_PERM_ADDR(dev
, dev_addr
);
838 dev
->extra_tx_headroom
= 12; /* FIXME */
839 dev
->flags
= IEEE80211_HW_SIGNAL_UNSPEC
;
840 dev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
);
842 dev
->channel_change_time
= 1000;
843 dev
->max_signal
= 100;
846 dev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &wbsoft_band_2GHz
;
848 err
= ieee80211_register_hw(dev
);
852 usb_set_intfdata(intf
, dev
);
857 ieee80211_free_hw(dev
);
863 static void hal_halt(struct hw_data
*pHwData
)
865 del_timer_sync(&pHwData
->LEDTimer
);
866 /* XXX: Wait for Timer DPC exit. */
868 Wb35Rx_destroy(pHwData
);
869 Wb35Tx_destroy(pHwData
);
870 Wb35Reg_destroy(pHwData
);
873 static void wb35_hw_halt(struct wbsoft_priv
*adapter
)
875 Mds_Destroy(adapter
);
877 /* Turn off Rx and Tx hardware ability */
878 hal_stop(&adapter
->sHwData
);
879 #ifdef _PE_USB_INI_DUMP_
880 printk("[w35und] Hal_stop O.K.\n");
882 /* Waiting Irp completed */
885 hal_halt(&adapter
->sHwData
);
888 static void wb35_disconnect(struct usb_interface
*intf
)
890 struct ieee80211_hw
*hw
= usb_get_intfdata(intf
);
891 struct wbsoft_priv
*priv
= hw
->priv
;
895 ieee80211_stop_queues(hw
);
896 ieee80211_unregister_hw(hw
);
897 ieee80211_free_hw(hw
);
899 usb_set_intfdata(intf
, NULL
);
900 usb_put_dev(interface_to_usbdev(intf
));
903 static struct usb_driver wb35_driver
= {
905 .id_table
= wb35_table
,
907 .disconnect
= wb35_disconnect
,
910 static int __init
wb35_init(void)
912 return usb_register(&wb35_driver
);
915 static void __exit
wb35_exit(void)
917 usb_deregister(&wb35_driver
);
920 module_init(wb35_init
);
921 module_exit(wb35_exit
);