ASoC: tlv312aic23: unbreak resume
[zen-stable.git] / drivers / staging / winbond / wbusb.c
blobc3751a718384cf0f7821627482e6fab813b9c6e4
1 /*
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>
14 #include <linux/module.h>
16 #include "core.h"
17 #include "mds_f.h"
18 #include "mto.h"
19 #include "wbhal.h"
20 #include "wb35reg_f.h"
21 #include "wb35tx_f.h"
22 #include "wb35rx_f.h"
24 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
25 MODULE_LICENSE("GPL");
26 MODULE_VERSION("0.1");
28 static const struct usb_device_id wb35_table[] __devinitconst = {
29 { USB_DEVICE(0x0416, 0x0035) },
30 { USB_DEVICE(0x18E8, 0x6201) },
31 { USB_DEVICE(0x18E8, 0x6206) },
32 { USB_DEVICE(0x18E8, 0x6217) },
33 { USB_DEVICE(0x18E8, 0x6230) },
34 { USB_DEVICE(0x18E8, 0x6233) },
35 { USB_DEVICE(0x1131, 0x2035) },
36 { 0, }
39 MODULE_DEVICE_TABLE(usb, wb35_table);
41 static struct ieee80211_rate wbsoft_rates[] = {
42 { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
45 static struct ieee80211_channel wbsoft_channels[] = {
46 { .center_freq = 2412 },
49 static struct ieee80211_supported_band wbsoft_band_2GHz = {
50 .channels = wbsoft_channels,
51 .n_channels = ARRAY_SIZE(wbsoft_channels),
52 .bitrates = wbsoft_rates,
53 .n_bitrates = ARRAY_SIZE(wbsoft_rates),
56 static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
58 u32 tmp;
60 if (pHwData->SurpriseRemove)
61 return;
63 pHwData->BeaconPeriod = beacon_period;
64 tmp = pHwData->BeaconPeriod << 16;
65 tmp |= pHwData->ProbeDelay;
66 Wb35Reg_Write(pHwData, 0x0848, tmp);
69 static int wbsoft_add_interface(struct ieee80211_hw *dev,
70 struct ieee80211_vif *vif)
72 struct wbsoft_priv *priv = dev->priv;
74 hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
76 return 0;
79 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
80 struct ieee80211_vif *vif)
82 printk("wbsoft_remove interface called\n");
85 static void wbsoft_stop(struct ieee80211_hw *hw)
87 printk(KERN_INFO "%s called\n", __func__);
90 static int wbsoft_get_stats(struct ieee80211_hw *hw,
91 struct ieee80211_low_level_stats *stats)
93 printk(KERN_INFO "%s called\n", __func__);
94 return 0;
97 static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw,
98 struct netdev_hw_addr_list *mc_list)
100 return netdev_hw_addr_list_count(mc_list);
103 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
104 unsigned int changed_flags,
105 unsigned int *total_flags,
106 u64 multicast)
108 unsigned int new_flags;
110 new_flags = 0;
112 if (*total_flags & FIF_PROMISC_IN_BSS)
113 new_flags |= FIF_PROMISC_IN_BSS;
114 else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32))
115 new_flags |= FIF_ALLMULTI;
117 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
119 *total_flags = new_flags;
122 static void wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
124 struct wbsoft_priv *priv = dev->priv;
126 if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
127 priv->sMlmeFrame.wNumTxMMPDUDiscarded++;
128 kfree_skb(skb);
129 return;
132 priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
134 priv->sMlmeFrame.pMMPDU = skb->data;
135 priv->sMlmeFrame.DataType = FRAME_TYPE_802_11_MANAGEMENT;
136 priv->sMlmeFrame.len = skb->len;
137 priv->sMlmeFrame.wNumTxMMPDU++;
140 * H/W will enter power save by set the register. S/W don't send null
141 * frame with PWRMgt bit enbled to enter power save now.
144 Mds_Tx(priv);
147 static int wbsoft_start(struct ieee80211_hw *dev)
149 struct wbsoft_priv *priv = dev->priv;
151 priv->enabled = true;
153 return 0;
156 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
158 struct wb35_reg *reg = &pHwData->reg;
160 if (pHwData->SurpriseRemove)
161 return;
163 if (radio_off) { /* disable Baseband receive off */
164 pHwData->CurrentRadioSw = 1; /* off */
165 reg->M24_MacControl &= 0xffffffbf;
166 } else {
167 pHwData->CurrentRadioSw = 0; /* on */
168 reg->M24_MacControl |= 0x00000040;
170 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
173 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
175 struct wb35_reg *reg = &pHwData->reg;
177 if (pHwData->SurpriseRemove)
178 return;
180 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
182 RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */
183 pHwData->Channel = channel.ChanNo;
184 pHwData->band = channel.band;
185 pr_debug("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
186 reg->M28_MacControl &= ~0xff; /* Clean channel information field */
187 reg->M28_MacControl |= channel.ChanNo;
188 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
189 (s8 *) &channel,
190 sizeof(struct chan_info));
193 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
195 hal_set_current_channel_ex(pHwData, channel);
198 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
200 struct wb35_reg *reg = &pHwData->reg;
202 if (pHwData->SurpriseRemove)
203 return;
205 reg->M00_MacControl &= ~0x02000000; /* The HW value */
207 if (enable)
208 reg->M00_MacControl |= 0x02000000; /* The HW value */
210 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
213 /* For wep key error detection, we need to accept broadcast packets to be received temporary. */
214 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
216 struct wb35_reg *reg = &pHwData->reg;
218 if (pHwData->SurpriseRemove)
219 return;
221 if (enable) {
222 reg->M00_MacControl |= 0x00400000;
223 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
224 } else {
225 reg->M00_MacControl &= ~0x00400000;
226 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
230 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
232 struct wb35_reg *reg = &pHwData->reg;
234 if (pHwData->SurpriseRemove)
235 return;
237 reg->M00_MacControl &= ~0x01000000; /* The HW value */
238 if (enable)
239 reg->M00_MacControl |= 0x01000000; /* The HW value */
240 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
243 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
245 struct wb35_reg *reg = &pHwData->reg;
247 if (pHwData->SurpriseRemove)
248 return;
250 if (!enable) /* Due to SME and MLME are not suitable for 35 */
251 return;
253 reg->M00_MacControl &= ~0x04000000; /* The HW value */
254 if (enable)
255 reg->M00_MacControl |= 0x04000000; /* The HW value */
257 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
260 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
262 struct wbsoft_priv *priv = dev->priv;
263 struct chan_info ch;
265 printk("wbsoft_config called\n");
267 /* Should use channel_num, or something, as that is already pre-translated */
268 ch.band = 1;
269 ch.ChanNo = 1;
271 hal_set_current_channel(&priv->sHwData, ch);
272 hal_set_accept_broadcast(&priv->sHwData, 1);
273 hal_set_accept_promiscuous(&priv->sHwData, 1);
274 hal_set_accept_multicast(&priv->sHwData, 1);
275 hal_set_accept_beacon(&priv->sHwData, 1);
276 hal_set_radio_mode(&priv->sHwData, 0);
278 return 0;
281 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
283 printk("wbsoft_get_tsf called\n");
284 return 0;
287 static const struct ieee80211_ops wbsoft_ops = {
288 .tx = wbsoft_tx,
289 .start = wbsoft_start,
290 .stop = wbsoft_stop,
291 .add_interface = wbsoft_add_interface,
292 .remove_interface = wbsoft_remove_interface,
293 .config = wbsoft_config,
294 .prepare_multicast = wbsoft_prepare_multicast,
295 .configure_filter = wbsoft_configure_filter,
296 .get_stats = wbsoft_get_stats,
297 .get_tsf = wbsoft_get_tsf,
300 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
302 u32 ltmp[2];
304 if (pHwData->SurpriseRemove)
305 return;
307 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
309 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
310 ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
312 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
315 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
317 if (pHwData->SurpriseRemove)
318 return;
320 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
323 static void hal_stop(struct hw_data *pHwData)
325 struct wb35_reg *reg = &pHwData->reg;
327 pHwData->Wb35Rx.rx_halt = 1;
328 Wb35Rx_stop(pHwData);
330 pHwData->Wb35Tx.tx_halt = 1;
331 Wb35Tx_stop(pHwData);
333 reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */
334 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
337 static unsigned char hal_idle(struct hw_data *pHwData)
339 struct wb35_reg *reg = &pHwData->reg;
341 if (!pHwData->SurpriseRemove && reg->EP0vm_state != VM_STOP)
342 return false;
344 return true;
347 u8 hal_get_antenna_number(struct hw_data *pHwData)
349 struct wb35_reg *reg = &pHwData->reg;
351 if ((reg->BB2C & BIT(11)) == 0)
352 return 0;
353 else
354 return 1;
357 /* 0 : radio on; 1: radio off */
358 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
360 struct wb35_reg *reg = &pHwData->reg;
362 if (pHwData->SurpriseRemove)
363 return 1;
365 /* read the bit16 of register U1B0 */
366 Wb35Reg_Read(pHwData, 0x3b0, &reg->U1B0);
367 if ((reg->U1B0 & 0x00010000)) {
368 pHwData->CurrentRadioHw = 1;
369 return 1;
370 } else {
371 pHwData->CurrentRadioHw = 0;
372 return 0;
376 static u8 LED_GRAY[20] = {
377 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
380 static u8 LED_GRAY2[30] = {
381 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
382 0, 15, 14, 13, 12, 11, 10, 9, 8
385 static void hal_led_control(unsigned long data)
387 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
388 struct hw_data *pHwData = &adapter->sHwData;
389 struct wb35_reg *reg = &pHwData->reg;
390 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
391 u32 TimeInterval = 500, ltmp, ltmp2;
392 ltmp = 0;
394 if (pHwData->SurpriseRemove)
395 return;
397 if (pHwData->LED_control) {
398 ltmp2 = pHwData->LED_control & 0xff;
399 if (ltmp2 == 5) { /* 5 is WPS mode */
400 TimeInterval = 100;
401 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
402 switch (ltmp2) {
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 */
407 ltmp = 0;
408 break;
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 */
413 ltmp = 0;
414 break;
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 */
419 ltmp = 0;
420 break;
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. */
425 break;
427 pHwData->LED_Blinking++;
429 reg->U1BC_LEDConfigure = ltmp;
430 if (LEDSet != 7) { /* Only 111 mode has 2 LEDs on PCB. */
431 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; /* Copy LED result to each LED control register */
432 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
434 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
436 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) { /* If radio off */
437 if (reg->U1BC_LEDConfigure & 0x1010) {
438 reg->U1BC_LEDConfigure &= ~0x1010;
439 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
441 } else {
442 switch (LEDSet) {
443 case 4: /* [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
444 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
445 /* Blinking if scanning is on progress */
446 if (pHwData->LED_Scanning) {
447 if (pHwData->LED_Blinking == 0) {
448 reg->U1BC_LEDConfigure |= 0x10;
449 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
450 pHwData->LED_Blinking = 1;
451 TimeInterval = 300;
452 } else {
453 reg->U1BC_LEDConfigure &= ~0x10;
454 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
455 pHwData->LED_Blinking = 0;
456 TimeInterval = 300;
458 } else {
459 /* Turn Off LED_0 */
460 if (reg->U1BC_LEDConfigure & 0x10) {
461 reg->U1BC_LEDConfigure &= ~0x10;
462 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
465 } else {
466 /* Turn On LED_0 */
467 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
468 reg->U1BC_LEDConfigure |= 0x10;
469 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
472 break;
473 case 6: /* [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
474 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
475 /* Blinking if scanning is on progress */
476 if (pHwData->LED_Scanning) {
477 if (pHwData->LED_Blinking == 0) {
478 reg->U1BC_LEDConfigure &= ~0xf;
479 reg->U1BC_LEDConfigure |= 0x10;
480 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
481 pHwData->LED_Blinking = 1;
482 TimeInterval = 300;
483 } else {
484 reg->U1BC_LEDConfigure &= ~0x1f;
485 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
486 pHwData->LED_Blinking = 0;
487 TimeInterval = 300;
489 } else {
490 /* Gray blinking if in disconnect state and not scanning */
491 ltmp = reg->U1BC_LEDConfigure;
492 reg->U1BC_LEDConfigure &= ~0x1f;
493 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
494 reg->U1BC_LEDConfigure |= 0x10;
495 reg->U1BC_LEDConfigure |=
496 LED_GRAY2[(pHwData->LED_Blinking % 30)];
498 pHwData->LED_Blinking++;
499 if (reg->U1BC_LEDConfigure != ltmp)
500 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
501 TimeInterval = 100;
503 } else {
504 /* Turn On LED_0 */
505 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
506 reg->U1BC_LEDConfigure |= 0x10;
507 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
510 break;
511 case 5: /* [101] Only 1 Led be placed on PCB and use LED_1 for showing */
512 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 |= 0x1000;
517 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
518 pHwData->LED_Blinking = 1;
519 TimeInterval = 300;
520 } else {
521 reg->U1BC_LEDConfigure &= ~0x1000;
522 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
523 pHwData->LED_Blinking = 0;
524 TimeInterval = 300;
526 } else {
527 /* Turn Off LED_1 */
528 if (reg->U1BC_LEDConfigure & 0x1000) {
529 reg->U1BC_LEDConfigure &= ~0x1000;
530 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
533 } else {
534 /* Is transmitting/receiving ?? */
535 if ((adapter->RxByteCount !=
536 pHwData->RxByteCountLast)
537 || (adapter->TxByteCount !=
538 pHwData->TxByteCountLast)) {
539 if ((reg->U1BC_LEDConfigure & 0x3000) !=
540 0x3000) {
541 reg->U1BC_LEDConfigure |= 0x3000;
542 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
544 /* Update variable */
545 pHwData->RxByteCountLast =
546 adapter->RxByteCount;
547 pHwData->TxByteCountLast =
548 adapter->TxByteCount;
549 TimeInterval = 200;
550 } else {
551 /* Turn On LED_1 and blinking if transmitting/receiving */
552 if ((reg->U1BC_LEDConfigure & 0x3000) !=
553 0x1000) {
554 reg->U1BC_LEDConfigure &=
555 ~0x3000;
556 reg->U1BC_LEDConfigure |=
557 0x1000;
558 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
562 break;
563 default: /* Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active */
564 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
565 reg->U1BC_LEDConfigure |= 0x3000; /* LED_1 is always on and event enable */
566 Wb35Reg_Write(pHwData, 0x03bc,
567 reg->U1BC_LEDConfigure);
570 if (pHwData->LED_Blinking) {
571 /* Gray blinking */
572 reg->U1BC_LEDConfigure &= ~0x0f;
573 reg->U1BC_LEDConfigure |= 0x10;
574 reg->U1BC_LEDConfigure |=
575 LED_GRAY[(pHwData->LED_Blinking - 1) % 20];
576 Wb35Reg_Write(pHwData, 0x03bc,
577 reg->U1BC_LEDConfigure);
579 pHwData->LED_Blinking += 2;
580 if (pHwData->LED_Blinking < 40)
581 TimeInterval = 100;
582 else {
583 pHwData->LED_Blinking = 0; /* Stop blinking */
584 reg->U1BC_LEDConfigure &= ~0x0f;
585 Wb35Reg_Write(pHwData, 0x03bc,
586 reg->U1BC_LEDConfigure);
588 break;
591 if (pHwData->LED_LinkOn) {
592 if (!(reg->U1BC_LEDConfigure & 0x10)) { /* Check the LED_0 */
593 /* Try to turn ON LED_0 after gray blinking */
594 reg->U1BC_LEDConfigure |= 0x10;
595 pHwData->LED_Blinking = 1; /* Start blinking */
596 TimeInterval = 50;
598 } else {
599 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
600 reg->U1BC_LEDConfigure &= ~0x10;
601 Wb35Reg_Write(pHwData, 0x03bc,
602 reg->U1BC_LEDConfigure);
605 break;
609 pHwData->time_count += TimeInterval;
610 Wb35Tx_CurrentTime(adapter, pHwData->time_count);
611 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
612 add_timer(&pHwData->LEDTimer);
615 static int hal_init_hardware(struct ieee80211_hw *hw)
617 struct wbsoft_priv *priv = hw->priv;
618 struct hw_data *pHwData = &priv->sHwData;
619 u16 SoftwareSet;
621 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
622 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
624 if (!Wb35Reg_initial(pHwData))
625 goto error_reg_destroy;
627 if (!Wb35Tx_initial(pHwData))
628 goto error_tx_destroy;
630 if (!Wb35Rx_initial(pHwData))
631 goto error_rx_destroy;
633 init_timer(&pHwData->LEDTimer);
634 pHwData->LEDTimer.function = hal_led_control;
635 pHwData->LEDTimer.data = (unsigned long)priv;
636 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
637 add_timer(&pHwData->LEDTimer);
639 SoftwareSet = hal_software_set(pHwData);
641 Wb35Rx_start(hw);
642 Wb35Tx_EP2VM_start(priv);
644 return 0;
646 error_rx_destroy:
647 Wb35Rx_destroy(pHwData);
648 error_tx_destroy:
649 Wb35Tx_destroy(pHwData);
650 error_reg_destroy:
651 Wb35Reg_destroy(pHwData);
653 pHwData->SurpriseRemove = 1;
654 return -EINVAL;
657 static int wb35_hw_init(struct ieee80211_hw *hw)
659 struct wbsoft_priv *priv = hw->priv;
660 struct hw_data *pHwData = &priv->sHwData;
661 u8 EEPROM_region;
662 u8 HwRadioOff;
663 u8 *pMacAddr2;
664 u8 *pMacAddr;
665 int err;
667 pHwData->phy_type = RF_DECIDE_BY_INF;
669 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
670 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
672 priv->sLocalPara.region_INF = REGION_AUTO;
673 priv->sLocalPara.TxRateMode = RATE_AUTO;
674 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG;
675 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
676 priv->sLocalPara.bPreambleMode = AUTO_MODE;
677 priv->sLocalPara.bWepKeyError = false;
678 priv->sLocalPara.bToSelfPacketReceived = false;
679 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
681 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
683 err = hal_init_hardware(hw);
684 if (err)
685 goto error;
687 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
688 if (EEPROM_region != REGION_AUTO)
689 priv->sLocalPara.region = EEPROM_region;
690 else {
691 if (priv->sLocalPara.region_INF != REGION_AUTO)
692 priv->sLocalPara.region = priv->sLocalPara.region_INF;
693 else
694 priv->sLocalPara.region = REGION_USA; /* default setting */
697 Mds_initial(priv);
700 * If no user-defined address in the registry, use the address
701 * "burned" on the NIC instead.
703 pMacAddr = priv->sLocalPara.ThisMacAddress;
704 pMacAddr2 = priv->sLocalPara.PermanentAddress;
706 /* Reading ethernet address from EEPROM */
707 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
708 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
709 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
710 else {
711 /* Set the user define MAC address */
712 hal_set_ethernet_address(pHwData,
713 priv->sLocalPara.ThisMacAddress);
716 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
717 pr_debug("Driver init, antenna no = %d\n", priv->sLocalPara.bAntennaNo);
718 hal_get_hw_radio_off(pHwData);
720 /* Waiting for HAL setting OK */
721 while (!hal_idle(pHwData))
722 msleep(10);
724 MTO_Init(priv);
726 HwRadioOff = hal_get_hw_radio_off(pHwData);
727 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
729 hal_set_radio_mode(pHwData,
730 (unsigned char)(priv->sLocalPara.RadioOffStatus.
731 boSwRadioOff
732 || priv->sLocalPara.RadioOffStatus.
733 boHwRadioOff));
735 /* Notify hal that the driver is ready now. */
736 hal_driver_init_OK(pHwData) = 1;
738 error:
739 return err;
742 static int wb35_probe(struct usb_interface *intf,
743 const struct usb_device_id *id_table)
745 struct usb_device *udev = interface_to_usbdev(intf);
746 struct usb_endpoint_descriptor *endpoint;
747 struct usb_host_interface *interface;
748 struct ieee80211_hw *dev;
749 struct wbsoft_priv *priv;
750 int nr, err;
751 u32 ltmp;
753 usb_get_dev(udev);
755 /* Check the device if it already be opened */
756 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
757 0x01,
758 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
759 0x0, 0x400, &ltmp, 4, HZ * 100);
760 if (nr < 0) {
761 err = nr;
762 goto error;
765 /* Is already initialized? */
766 ltmp = cpu_to_le32(ltmp);
767 if (ltmp) {
768 err = -EBUSY;
769 goto error;
772 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
773 if (!dev) {
774 err = -ENOMEM;
775 goto error;
778 priv = dev->priv;
780 priv->sHwData.udev = udev;
782 interface = intf->cur_altsetting;
783 endpoint = &interface->endpoint[0].desc;
785 if (endpoint[2].wMaxPacketSize == 512)
786 printk("[w35und] Working on USB 2.0\n");
788 err = wb35_hw_init(dev);
789 if (err)
790 goto error_free_hw;
792 SET_IEEE80211_DEV(dev, &udev->dev);
794 struct hw_data *pHwData = &priv->sHwData;
795 unsigned char dev_addr[MAX_ADDR_LEN];
796 hal_get_permanent_address(pHwData, dev_addr);
797 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
800 dev->extra_tx_headroom = 12; /* FIXME */
801 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
802 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
804 dev->channel_change_time = 1000;
805 dev->max_signal = 100;
806 dev->queues = 1;
808 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
810 err = ieee80211_register_hw(dev);
811 if (err)
812 goto error_free_hw;
814 usb_set_intfdata(intf, dev);
816 return 0;
818 error_free_hw:
819 ieee80211_free_hw(dev);
820 error:
821 usb_put_dev(udev);
822 return err;
825 static void hal_halt(struct hw_data *pHwData)
827 del_timer_sync(&pHwData->LEDTimer);
828 /* XXX: Wait for Timer DPC exit. */
829 msleep(100);
830 Wb35Rx_destroy(pHwData);
831 Wb35Tx_destroy(pHwData);
832 Wb35Reg_destroy(pHwData);
835 static void wb35_hw_halt(struct wbsoft_priv *adapter)
837 /* Turn off Rx and Tx hardware ability */
838 hal_stop(&adapter->sHwData);
839 pr_debug("[w35und] Hal_stop O.K.\n");
840 /* Waiting Irp completed */
841 msleep(100);
843 hal_halt(&adapter->sHwData);
846 static void wb35_disconnect(struct usb_interface *intf)
848 struct ieee80211_hw *hw = usb_get_intfdata(intf);
849 struct wbsoft_priv *priv = hw->priv;
851 wb35_hw_halt(priv);
853 ieee80211_stop_queues(hw);
854 ieee80211_unregister_hw(hw);
855 ieee80211_free_hw(hw);
857 usb_set_intfdata(intf, NULL);
858 usb_put_dev(interface_to_usbdev(intf));
861 static struct usb_driver wb35_driver = {
862 .name = "w35und",
863 .id_table = wb35_table,
864 .probe = wb35_probe,
865 .disconnect = wb35_disconnect,
868 module_usb_driver(wb35_driver);