1
2
3
4
5
6
7
8
9
10
11
12#include <net/mac80211.h>
13#include <linux/usb.h>
14
15#include "core.h"
16#include "mds_f.h"
17#include "mlmetxrx_f.h"
18#include "mto.h"
19#include "wbhal_f.h"
20#include "wblinux_f.h"
21
22MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
23MODULE_LICENSE("GPL");
24MODULE_VERSION("0.1");
25
26static 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) },
34 { 0, }
35};
36
37MODULE_DEVICE_TABLE(usb, wb35_table);
38
39static struct ieee80211_rate wbsoft_rates[] = {
40 { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
41};
42
43static struct ieee80211_channel wbsoft_channels[] = {
44 { .center_freq = 2412 },
45};
46
47static 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),
52};
53
54static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
55{
56 u32 tmp;
57
58 if (pHwData->SurpriseRemove)
59 return;
60
61 pHwData->BeaconPeriod = beacon_period;
62 tmp = pHwData->BeaconPeriod << 16;
63 tmp |= pHwData->ProbeDelay;
64 Wb35Reg_Write(pHwData, 0x0848, tmp);
65}
66
67static int wbsoft_add_interface(struct ieee80211_hw *dev,
68 struct ieee80211_if_init_conf *conf)
69{
70 struct wbsoft_priv *priv = dev->priv;
71
72 hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
73
74 return 0;
75}
76
77static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78 struct ieee80211_if_init_conf *conf)
79{
80 printk("wbsoft_remove interface called\n");
81}
82
83static void wbsoft_stop(struct ieee80211_hw *hw)
84{
85 printk(KERN_INFO "%s called\n", __func__);
86}
87
88static int wbsoft_get_stats(struct ieee80211_hw *hw,
89 struct ieee80211_low_level_stats *stats)
90{
91 printk(KERN_INFO "%s called\n", __func__);
92 return 0;
93}
94
95static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
96 struct ieee80211_tx_queue_stats *stats)
97{
98 printk(KERN_INFO "%s called\n", __func__);
99 return 0;
100}
101
102static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
103 struct dev_addr_list *mc_list)
104{
105 return mc_count;
106}
107
108static void wbsoft_configure_filter(struct ieee80211_hw *dev,
109 unsigned int changed_flags,
110 unsigned int *total_flags,
111 u64 multicast)
112{
113 unsigned int new_flags;
114
115 new_flags = 0;
116
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;
121
122 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
123
124 *total_flags = new_flags;
125}
126
127static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
128{
129 struct wbsoft_priv *priv = dev->priv;
130
131 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
132
133 return NETDEV_TX_OK;
134}
135
136static int wbsoft_start(struct ieee80211_hw *dev)
137{
138 struct wbsoft_priv *priv = dev->priv;
139
140 priv->enabled = true;
141
142 return 0;
143}
144
145static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
146{
147 struct wb35_reg *reg = &pHwData->reg;
148
149 if (pHwData->SurpriseRemove)
150 return;
151
152 if (radio_off)
153 {
154 pHwData->CurrentRadioSw = 1;
155 reg->M24_MacControl &= 0xffffffbf;
156 } else {
157 pHwData->CurrentRadioSw = 0;
158 reg->M24_MacControl |= 0x00000040;
159 }
160 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
161}
162
163static void
164hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
165{
166 struct wb35_reg *reg = &pHwData->reg;
167
168 if (pHwData->SurpriseRemove)
169 return;
170
171 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
172
173 RFSynthesizer_SwitchingChannel(pHwData, 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,
178 pHwData->band);
179#endif
180 reg->M28_MacControl &= ~0xff;
181 reg->M28_MacControl |= channel.ChanNo;
182 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
183 (s8 *) & channel, sizeof(ChanInfo));
184}
185
186static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
187{
188 hal_set_current_channel_ex(pHwData, channel);
189}
190
191static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
192{
193 struct wb35_reg *reg = &pHwData->reg;
194
195 if (pHwData->SurpriseRemove)
196 return;
197
198 reg->M00_MacControl &= ~0x02000000;
199
200 if (enable)
201 reg->M00_MacControl |= 0x02000000;
202
203 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
204}
205
206
207static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
208{
209 struct wb35_reg *reg = &pHwData->reg;
210
211 if (pHwData->SurpriseRemove)
212 return;
213 if (enable) {
214 reg->M00_MacControl |= 0x00400000;
215 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
216 } else {
217 reg->M00_MacControl &= ~0x00400000;
218 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
219 }
220}
221
222static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
223{
224 struct wb35_reg *reg = &pHwData->reg;
225
226 if (pHwData->SurpriseRemove)
227 return;
228
229 reg->M00_MacControl &= ~0x01000000;
230 if (enable)
231 reg->M00_MacControl |= 0x01000000;
232 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
233}
234
235static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
236{
237 struct wb35_reg *reg = &pHwData->reg;
238
239 if (pHwData->SurpriseRemove)
240 return;
241
242
243 if (!enable)
244 return;
245
246 reg->M00_MacControl &= ~0x04000000;
247 if (enable)
248 reg->M00_MacControl |= 0x04000000;
249
250 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
251}
252
253static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
254{
255 struct wbsoft_priv *priv = dev->priv;
256 ChanInfo ch;
257
258 printk("wbsoft_config called\n");
259
260
261 ch.band = 1;
262 ch.ChanNo = 1;
263
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);
270
271 return 0;
272}
273
274static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
275{
276 printk("wbsoft_get_tsf called\n");
277 return 0;
278}
279
280static const struct ieee80211_ops wbsoft_ops = {
281 .tx = wbsoft_tx,
282 .start = wbsoft_start,
283 .stop = wbsoft_stop,
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,
292};
293
294static void
295hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address)
296{
297 u32 ltmp[2];
298
299 if (pHwData->SurpriseRemove)
300 return;
301
302 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
303
304 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
305 ltmp[1] =
306 cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
307
308 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
309}
310
311static void
312hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address)
313{
314 if (pHwData->SurpriseRemove)
315 return;
316
317 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
318}
319
320static void hal_stop(struct hw_data *pHwData)
321{
322 struct wb35_reg *reg = &pHwData->reg;
323
324 pHwData->Wb35Rx.rx_halt = 1;
325 Wb35Rx_stop(pHwData);
326
327 pHwData->Wb35Tx.tx_halt = 1;
328 Wb35Tx_stop(pHwData);
329
330 reg->D00_DmaControl &= ~0xc0000000;
331 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
332}
333
334static unsigned char hal_idle(struct hw_data *pHwData)
335{
336 struct wb35_reg *reg = &pHwData->reg;
337 struct wb_usb *pWbUsb = &pHwData->WbUsb;
338
339 if (!pHwData->SurpriseRemove
340 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
341 return false;
342
343 return true;
344}
345
346u8 hal_get_antenna_number(struct hw_data *pHwData)
347{
348 struct wb35_reg *reg = &pHwData->reg;
349
350 if ((reg->BB2C & BIT(11)) == 0)
351 return 0;
352 else
353 return 1;
354}
355
356
357static u8 hal_get_hw_radio_off(struct hw_data * pHwData)
358{
359 struct wb35_reg *reg = &pHwData->reg;
360
361 if (pHwData->SurpriseRemove)
362 return 1;
363
364
365 Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0);
366 if ((reg->U1B0 & 0x00010000)) {
367 pHwData->CurrentRadioHw = 1;
368 return 1;
369 } else {
370 pHwData->CurrentRadioHw = 0;
371 return 0;
372 }
373}
374
375static 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
377};
378
379static 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
382};
383
384static void hal_led_control(unsigned long data)
385{
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;
391 ltmp = 0;
392
393 if (pHwData->SurpriseRemove)
394 return;
395
396 if (pHwData->LED_control) {
397 ltmp2 = pHwData->LED_control & 0xff;
398 if (ltmp2 == 5)
399 {
400 TimeInterval = 100;
401 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
402 switch (ltmp2) {
403 case 1:
404 pHwData->LED_Blinking %= 3;
405 ltmp = 0x1010;
406 if (pHwData->LED_Blinking == 2)
407 ltmp = 0;
408 break;
409 case 2:
410 pHwData->LED_Blinking %= 2;
411 ltmp = 0x0010;
412 if (pHwData->LED_Blinking)
413 ltmp = 0;
414 break;
415 case 3:
416 pHwData->LED_Blinking %= 15;
417 ltmp = 0x0010;
418 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2))
419 ltmp = 0;
420 break;
421 case 4:
422 ltmp = 0x1000;
423 if (pHwData->LED_Blinking >= 3000)
424 ltmp = 0;
425 break;
426 }
427 pHwData->LED_Blinking++;
428
429 reg->U1BC_LEDConfigure = ltmp;
430 if (LEDSet != 7)
431 {
432 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8;
433 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
434 }
435 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
436 }
437 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw)
438 {
439 if (reg->U1BC_LEDConfigure & 0x1010) {
440 reg->U1BC_LEDConfigure &= ~0x1010;
441 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
442 }
443 } else {
444 switch (LEDSet) {
445 case 4:
446 if (!pHwData->LED_LinkOn)
447 {
448
449 if (pHwData->LED_Scanning) {
450 if (pHwData->LED_Blinking == 0) {
451 reg->U1BC_LEDConfigure |= 0x10;
452 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
453 pHwData->LED_Blinking = 1;
454 TimeInterval = 300;
455 } else {
456 reg->U1BC_LEDConfigure &= ~0x10;
457 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
458 pHwData->LED_Blinking = 0;
459 TimeInterval = 300;
460 }
461 } else {
462
463 if (reg->U1BC_LEDConfigure & 0x10) {
464 reg->U1BC_LEDConfigure &= ~0x10;
465 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
466 }
467 }
468 } else {
469
470 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
471 reg->U1BC_LEDConfigure |= 0x10;
472 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
473 }
474 }
475 break;
476
477 case 6:
478 if (!pHwData->LED_LinkOn)
479 {
480
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);
486 pHwData->LED_Blinking = 1;
487 TimeInterval = 300;
488 } else {
489 reg->U1BC_LEDConfigure &= ~0x1f;
490 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
491 pHwData->LED_Blinking = 0;
492 TimeInterval = 300;
493 }
494 } else {
495
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)];
502 }
503 pHwData->LED_Blinking++;
504 if (reg->U1BC_LEDConfigure != ltmp)
505 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
506 TimeInterval = 100;
507 }
508 } else {
509
510 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
511 reg->U1BC_LEDConfigure |= 0x10;
512 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
513 }
514 }
515 break;
516
517 case 5:
518 if (!pHwData->LED_LinkOn)
519 {
520
521 if (pHwData->LED_Scanning) {
522 if (pHwData->LED_Blinking == 0) {
523 reg->U1BC_LEDConfigure |=
524 0x1000;
525 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
526 pHwData->LED_Blinking = 1;
527 TimeInterval = 300;
528 } else {
529 reg->U1BC_LEDConfigure &=
530 ~0x1000;
531 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
532 pHwData->LED_Blinking = 0;
533 TimeInterval = 300;
534 }
535 } else {
536
537 if (reg->U1BC_LEDConfigure & 0x1000) {
538 reg->U1BC_LEDConfigure &=
539 ~0x1000;
540 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
541 }
542 }
543 } else {
544
545 if ((adapter->RxByteCount !=
546 pHwData->RxByteCountLast)
547 || (adapter->TxByteCount !=
548 pHwData->TxByteCountLast)) {
549 if ((reg->U1BC_LEDConfigure & 0x3000) !=
550 0x3000) {
551 reg->U1BC_LEDConfigure |=
552 0x3000;
553 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
554 }
555
556 pHwData->RxByteCountLast =
557 adapter->RxByteCount;
558 pHwData->TxByteCountLast =
559 adapter->TxByteCount;
560 TimeInterval = 200;
561 } else {
562
563 if ((reg->U1BC_LEDConfigure & 0x3000) !=
564 0x1000) {
565 reg->U1BC_LEDConfigure &=
566 ~0x3000;
567 reg->U1BC_LEDConfigure |=
568 0x1000;
569 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
570 }
571 }
572 }
573 break;
574
575 default:
576 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
577 reg->U1BC_LEDConfigure |= 0x3000;
578 Wb35Reg_Write(pHwData, 0x03bc,
579 reg->U1BC_LEDConfigure);
580 }
581
582 if (pHwData->LED_Blinking) {
583
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);
590
591 pHwData->LED_Blinking += 2;
592 if (pHwData->LED_Blinking < 40)
593 TimeInterval = 100;
594 else {
595 pHwData->LED_Blinking = 0;
596 reg->U1BC_LEDConfigure &= ~0x0f;
597 Wb35Reg_Write(pHwData, 0x03bc,
598 reg->U1BC_LEDConfigure);
599 }
600 break;
601 }
602
603 if (pHwData->LED_LinkOn) {
604 if (!(reg->U1BC_LEDConfigure & 0x10))
605 {
606
607 reg->U1BC_LEDConfigure |= 0x10;
608 pHwData->LED_Blinking = 1;
609 TimeInterval = 50;
610 }
611 } else {
612 if (reg->U1BC_LEDConfigure & 0x10)
613 {
614 reg->U1BC_LEDConfigure &= ~0x10;
615 Wb35Reg_Write(pHwData, 0x03bc,
616 reg->U1BC_LEDConfigure);
617 }
618 }
619 break;
620 }
621
622
623 if (pHwData->LED_LinkOn) {
624 pHwData->NullPacketCount += TimeInterval;
625 if (pHwData->NullPacketCount >=
626 DEFAULT_NULL_PACKET_COUNT) {
627 pHwData->NullPacketCount = 0;
628 }
629 }
630 }
631
632 pHwData->time_count += TimeInterval;
633 Wb35Tx_CurrentTime(adapter, pHwData->time_count);
634 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
635 add_timer(&pHwData->LEDTimer);
636}
637
638static int hal_init_hardware(struct ieee80211_hw *hw)
639{
640 struct wbsoft_priv *priv = hw->priv;
641 struct hw_data *pHwData = &priv->sHwData;
642 u16 SoftwareSet;
643
644 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
645 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
646
647 if (!Wb35Reg_initial(pHwData))
648 goto error_reg_destroy;
649
650 if (!Wb35Tx_initial(pHwData))
651 goto error_tx_destroy;
652
653 if (!Wb35Rx_initial(pHwData))
654 goto error_rx_destroy;
655
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);
661
662 SoftwareSet = hal_software_set(pHwData);
663
664#ifdef Vendor2
665
666 SoftwareSet >>= 8;
667 if (SoftwareSet != 0x82)
668 return false;
669#endif
670
671 Wb35Rx_start(hw);
672 Wb35Tx_EP2VM_start(priv);
673
674 return 0;
675
676error_rx_destroy:
677 Wb35Rx_destroy(pHwData);
678error_tx_destroy:
679 Wb35Tx_destroy(pHwData);
680error_reg_destroy:
681 Wb35Reg_destroy(pHwData);
682
683 pHwData->SurpriseRemove = 1;
684 return -EINVAL;
685}
686
687static int wb35_hw_init(struct ieee80211_hw *hw)
688{
689 struct wbsoft_priv *priv = hw->priv;
690 struct hw_data *pHwData = &priv->sHwData;
691 u8 EEPROM_region;
692 u8 HwRadioOff;
693 u8 *pMacAddr2;
694 u8 *pMacAddr;
695 int err;
696
697 pHwData->phy_type = RF_DECIDE_BY_INF;
698
699 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
700 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
701
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;
710
711 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
712
713 err = hal_init_hardware(hw);
714 if (err)
715 goto error;
716
717 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
718 if (EEPROM_region != REGION_AUTO)
719 priv->sLocalPara.region = EEPROM_region;
720 else {
721 if (priv->sLocalPara.region_INF != REGION_AUTO)
722 priv->sLocalPara.region = priv->sLocalPara.region_INF;
723 else
724 priv->sLocalPara.region = REGION_USA;
725 }
726
727 Mds_initial(priv);
728
729
730
731
732
733 pMacAddr = priv->sLocalPara.ThisMacAddress;
734 pMacAddr2 = priv->sLocalPara.PermanentAddress;
735
736
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);
740 else {
741
742 hal_set_ethernet_address(pHwData,
743 priv->sLocalPara.ThisMacAddress);
744 }
745
746 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
747#ifdef _PE_STATE_DUMP_
748 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
749#endif
750 hal_get_hw_radio_off(pHwData);
751
752
753 while (!hal_idle(pHwData))
754 msleep(10);
755
756 MTO_Init(priv);
757
758 HwRadioOff = hal_get_hw_radio_off(pHwData);
759 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
760
761 hal_set_radio_mode(pHwData,
762 (unsigned char)(priv->sLocalPara.RadioOffStatus.
763 boSwRadioOff
764 || priv->sLocalPara.RadioOffStatus.
765 boHwRadioOff));
766
767
768 hal_driver_init_OK(pHwData) = 1;
769
770error:
771 return err;
772}
773
774static int wb35_probe(struct usb_interface *intf,
775 const struct usb_device_id *id_table)
776{
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;
783 int nr, err;
784 u32 ltmp;
785
786 usb_get_dev(udev);
787
788
789 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
790 0x01,
791 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
792 0x0, 0x400, <mp, 4, HZ * 100);
793 if (nr < 0) {
794 err = nr;
795 goto error;
796 }
797
798
799 ltmp = cpu_to_le32(ltmp);
800 if (ltmp) {
801 err = -EBUSY;
802 goto error;
803 }
804
805 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
806 if (!dev) {
807 err = -ENOMEM;
808 goto error;
809 }
810
811 priv = dev->priv;
812
813 spin_lock_init(&priv->SpinLock);
814
815 pWbUsb = &priv->sHwData.WbUsb;
816 pWbUsb->udev = udev;
817
818 interface = intf->cur_altsetting;
819 endpoint = &interface->endpoint[0].desc;
820
821 if (endpoint[2].wMaxPacketSize == 512) {
822 printk("[w35und] Working on USB 2.0\n");
823 pWbUsb->IsUsb20 = 1;
824 }
825
826 err = wb35_hw_init(dev);
827 if (err)
828 goto error_free_hw;
829
830 SET_IEEE80211_DEV(dev, &udev->dev);
831 {
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);
836 }
837
838 dev->extra_tx_headroom = 12;
839 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
840 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
841
842 dev->channel_change_time = 1000;
843 dev->max_signal = 100;
844 dev->queues = 1;
845
846 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
847
848 err = ieee80211_register_hw(dev);
849 if (err)
850 goto error_free_hw;
851
852 usb_set_intfdata(intf, dev);
853
854 return 0;
855
856error_free_hw:
857 ieee80211_free_hw(dev);
858error:
859 usb_put_dev(udev);
860 return err;
861}
862
863static void hal_halt(struct hw_data *pHwData)
864{
865 del_timer_sync(&pHwData->LEDTimer);
866
867 msleep(100);
868 Wb35Rx_destroy(pHwData);
869 Wb35Tx_destroy(pHwData);
870 Wb35Reg_destroy(pHwData);
871}
872
873static void wb35_hw_halt(struct wbsoft_priv *adapter)
874{
875 Mds_Destroy(adapter);
876
877
878 hal_stop(&adapter->sHwData);
879#ifdef _PE_USB_INI_DUMP_
880 printk("[w35und] Hal_stop O.K.\n");
881#endif
882
883 msleep(100);
884
885 hal_halt(&adapter->sHwData);
886}
887
888static void wb35_disconnect(struct usb_interface *intf)
889{
890 struct ieee80211_hw *hw = usb_get_intfdata(intf);
891 struct wbsoft_priv *priv = hw->priv;
892
893 wb35_hw_halt(priv);
894
895 ieee80211_stop_queues(hw);
896 ieee80211_unregister_hw(hw);
897 ieee80211_free_hw(hw);
898
899 usb_set_intfdata(intf, NULL);
900 usb_put_dev(interface_to_usbdev(intf));
901}
902
903static struct usb_driver wb35_driver = {
904 .name = "w35und",
905 .id_table = wb35_table,
906 .probe = wb35_probe,
907 .disconnect = wb35_disconnect,
908};
909
910static int __init wb35_init(void)
911{
912 return usb_register(&wb35_driver);
913}
914
915static void __exit wb35_exit(void)
916{
917 usb_deregister(&wb35_driver);
918}
919
920module_init(wb35_init);
921module_exit(wb35_exit);
922