Merge commit 'v2.6.36-rc1' into HEAD
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / winbond / wbusb.c
1 /*
2 * Copyright 2008 Pavel Machek <pavel@ucw.cz>
3 *
4 * Distribute under GPLv2.
5 *
6 * The original driver was written by:
7 * Jeff Lee <YY_Lee@issc.com.tw>
8 *
9 * and was adapted to the 2.6 kernel by:
10 * Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>
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
22 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
23 MODULE_LICENSE("GPL");
24 MODULE_VERSION("0.1");
25
26 static const struct usb_device_id wb35_table[] __devinitconst = {
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
37 MODULE_DEVICE_TABLE(usb, wb35_table);
38
39 static struct ieee80211_rate wbsoft_rates[] = {
40 { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
41 };
42
43 static struct ieee80211_channel wbsoft_channels[] = {
44 { .center_freq = 2412 },
45 };
46
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),
52 };
53
54 static 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
67 static int wbsoft_add_interface(struct ieee80211_hw *dev,
68 struct ieee80211_vif *vif)
69 {
70 struct wbsoft_priv *priv = dev->priv;
71
72 hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
73
74 return 0;
75 }
76
77 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78 struct ieee80211_vif *vif)
79 {
80 printk("wbsoft_remove interface called\n");
81 }
82
83 static void wbsoft_stop(struct ieee80211_hw *hw)
84 {
85 printk(KERN_INFO "%s called\n", __func__);
86 }
87
88 static 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
95 static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw,
96 struct netdev_hw_addr_list *mc_list)
97 {
98 return netdev_hw_addr_list_count(mc_list);
99 }
100
101 static void wbsoft_configure_filter(struct ieee80211_hw *dev,
102 unsigned int changed_flags,
103 unsigned int *total_flags,
104 u64 multicast)
105 {
106 unsigned int new_flags;
107
108 new_flags = 0;
109
110 if (*total_flags & FIF_PROMISC_IN_BSS)
111 new_flags |= FIF_PROMISC_IN_BSS;
112 else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32))
113 new_flags |= FIF_ALLMULTI;
114
115 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
116
117 *total_flags = new_flags;
118 }
119
120 static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
121 {
122 struct wbsoft_priv *priv = dev->priv;
123
124 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
125
126 return NETDEV_TX_OK;
127 }
128
129 static int wbsoft_start(struct ieee80211_hw *dev)
130 {
131 struct wbsoft_priv *priv = dev->priv;
132
133 priv->enabled = true;
134
135 return 0;
136 }
137
138 static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
139 {
140 struct wb35_reg *reg = &pHwData->reg;
141
142 if (pHwData->SurpriseRemove)
143 return;
144
145 if (radio_off) { /* disable Baseband receive off */
146 pHwData->CurrentRadioSw = 1; /* off */
147 reg->M24_MacControl &= 0xffffffbf;
148 } else {
149 pHwData->CurrentRadioSw = 0; /* on */
150 reg->M24_MacControl |= 0x00000040;
151 }
152 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
153 }
154
155 static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
156 {
157 struct wb35_reg *reg = &pHwData->reg;
158
159 if (pHwData->SurpriseRemove)
160 return;
161
162 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
163
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,
169 pHwData->band);
170 #endif
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,
175 sizeof(struct chan_info));
176 }
177
178 static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
179 {
180 hal_set_current_channel_ex(pHwData, channel);
181 }
182
183 static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
184 {
185 struct wb35_reg *reg = &pHwData->reg;
186
187 if (pHwData->SurpriseRemove)
188 return;
189
190 reg->M00_MacControl &= ~0x02000000; /* The HW value */
191
192 if (enable)
193 reg->M00_MacControl |= 0x02000000; /* The HW value */
194
195 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
196 }
197
198 /* For wep key error detection, we need to accept broadcast packets to be received temporary. */
199 static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
200 {
201 struct wb35_reg *reg = &pHwData->reg;
202
203 if (pHwData->SurpriseRemove)
204 return;
205
206 if (enable) {
207 reg->M00_MacControl |= 0x00400000;
208 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
209 } else {
210 reg->M00_MacControl &= ~0x00400000;
211 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
212 }
213 }
214
215 static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
216 {
217 struct wb35_reg *reg = &pHwData->reg;
218
219 if (pHwData->SurpriseRemove)
220 return;
221
222 reg->M00_MacControl &= ~0x01000000; /* The HW value */
223 if (enable)
224 reg->M00_MacControl |= 0x01000000; /* The HW value */
225 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
226 }
227
228 static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
229 {
230 struct wb35_reg *reg = &pHwData->reg;
231
232 if (pHwData->SurpriseRemove)
233 return;
234
235 if (!enable) /* Due to SME and MLME are not suitable for 35 */
236 return;
237
238 reg->M00_MacControl &= ~0x04000000; /* The HW value */
239 if (enable)
240 reg->M00_MacControl |= 0x04000000; /* The HW value */
241
242 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
243 }
244
245 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
246 {
247 struct wbsoft_priv *priv = dev->priv;
248 struct chan_info ch;
249
250 printk("wbsoft_config called\n");
251
252 /* Should use channel_num, or something, as that is already pre-translated */
253 ch.band = 1;
254 ch.ChanNo = 1;
255
256 hal_set_current_channel(&priv->sHwData, ch);
257 hal_set_accept_broadcast(&priv->sHwData, 1);
258 hal_set_accept_promiscuous(&priv->sHwData, 1);
259 hal_set_accept_multicast(&priv->sHwData, 1);
260 hal_set_accept_beacon(&priv->sHwData, 1);
261 hal_set_radio_mode(&priv->sHwData, 0);
262
263 return 0;
264 }
265
266 static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
267 {
268 printk("wbsoft_get_tsf called\n");
269 return 0;
270 }
271
272 static const struct ieee80211_ops wbsoft_ops = {
273 .tx = wbsoft_tx,
274 .start = wbsoft_start,
275 .stop = wbsoft_stop,
276 .add_interface = wbsoft_add_interface,
277 .remove_interface = wbsoft_remove_interface,
278 .config = wbsoft_config,
279 .prepare_multicast = wbsoft_prepare_multicast,
280 .configure_filter = wbsoft_configure_filter,
281 .get_stats = wbsoft_get_stats,
282 .get_tsf = wbsoft_get_tsf,
283 };
284
285 static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address)
286 {
287 u32 ltmp[2];
288
289 if (pHwData->SurpriseRemove)
290 return;
291
292 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);
293
294 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
295 ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;
296
297 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
298 }
299
300 static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address)
301 {
302 if (pHwData->SurpriseRemove)
303 return;
304
305 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
306 }
307
308 static void hal_stop(struct hw_data *pHwData)
309 {
310 struct wb35_reg *reg = &pHwData->reg;
311
312 pHwData->Wb35Rx.rx_halt = 1;
313 Wb35Rx_stop(pHwData);
314
315 pHwData->Wb35Tx.tx_halt = 1;
316 Wb35Tx_stop(pHwData);
317
318 reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */
319 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
320 }
321
322 static unsigned char hal_idle(struct hw_data *pHwData)
323 {
324 struct wb35_reg *reg = &pHwData->reg;
325 struct wb_usb *pWbUsb = &pHwData->WbUsb;
326
327 if (!pHwData->SurpriseRemove
328 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
329 return false;
330
331 return true;
332 }
333
334 u8 hal_get_antenna_number(struct hw_data *pHwData)
335 {
336 struct wb35_reg *reg = &pHwData->reg;
337
338 if ((reg->BB2C & BIT(11)) == 0)
339 return 0;
340 else
341 return 1;
342 }
343
344 /* 0 : radio on; 1: radio off */
345 static u8 hal_get_hw_radio_off(struct hw_data *pHwData)
346 {
347 struct wb35_reg *reg = &pHwData->reg;
348
349 if (pHwData->SurpriseRemove)
350 return 1;
351
352 /* read the bit16 of register U1B0 */
353 Wb35Reg_Read(pHwData, 0x3b0, &reg->U1B0);
354 if ((reg->U1B0 & 0x00010000)) {
355 pHwData->CurrentRadioHw = 1;
356 return 1;
357 } else {
358 pHwData->CurrentRadioHw = 0;
359 return 0;
360 }
361 }
362
363 static u8 LED_GRAY[20] = {
364 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2
365 };
366
367 static u8 LED_GRAY2[30] = {
368 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
369 0, 15, 14, 13, 12, 11, 10, 9, 8
370 };
371
372 static void hal_led_control(unsigned long data)
373 {
374 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data;
375 struct hw_data *pHwData = &adapter->sHwData;
376 struct wb35_reg *reg = &pHwData->reg;
377 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
378 u32 TimeInterval = 500, ltmp, ltmp2;
379 ltmp = 0;
380
381 if (pHwData->SurpriseRemove)
382 return;
383
384 if (pHwData->LED_control) {
385 ltmp2 = pHwData->LED_control & 0xff;
386 if (ltmp2 == 5) { /* 5 is WPS mode */
387 TimeInterval = 100;
388 ltmp2 = (pHwData->LED_control >> 8) & 0xff;
389 switch (ltmp2) {
390 case 1: /* [0.2 On][0.1 Off]... */
391 pHwData->LED_Blinking %= 3;
392 ltmp = 0x1010; /* Led 1 & 0 Green and Red */
393 if (pHwData->LED_Blinking == 2) /* Turn off */
394 ltmp = 0;
395 break;
396 case 2: /* [0.1 On][0.1 Off]... */
397 pHwData->LED_Blinking %= 2;
398 ltmp = 0x0010; /* Led 0 red color */
399 if (pHwData->LED_Blinking) /* Turn off */
400 ltmp = 0;
401 break;
402 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]... */
403 pHwData->LED_Blinking %= 15;
404 ltmp = 0x0010; /* Led 0 red color */
405 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) /* Turn off 0.6 sec */
406 ltmp = 0;
407 break;
408 case 4: /* [300 On][ off ] */
409 ltmp = 0x1000; /* Led 1 Green color */
410 if (pHwData->LED_Blinking >= 3000)
411 ltmp = 0; /* led maybe on after 300sec * 32bit counter overlap. */
412 break;
413 }
414 pHwData->LED_Blinking++;
415
416 reg->U1BC_LEDConfigure = ltmp;
417 if (LEDSet != 7) { /* Only 111 mode has 2 LEDs on PCB. */
418 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; /* Copy LED result to each LED control register */
419 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8;
420 }
421 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
422 }
423 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) { /* If radio off */
424 if (reg->U1BC_LEDConfigure & 0x1010) {
425 reg->U1BC_LEDConfigure &= ~0x1010;
426 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure);
427 }
428 } else {
429 switch (LEDSet) {
430 case 4: /* [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
431 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
432 /* Blinking if scanning is on progress */
433 if (pHwData->LED_Scanning) {
434 if (pHwData->LED_Blinking == 0) {
435 reg->U1BC_LEDConfigure |= 0x10;
436 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
437 pHwData->LED_Blinking = 1;
438 TimeInterval = 300;
439 } else {
440 reg->U1BC_LEDConfigure &= ~0x10;
441 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
442 pHwData->LED_Blinking = 0;
443 TimeInterval = 300;
444 }
445 } else {
446 /* Turn Off LED_0 */
447 if (reg->U1BC_LEDConfigure & 0x10) {
448 reg->U1BC_LEDConfigure &= ~0x10;
449 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
450 }
451 }
452 } else {
453 /* Turn On LED_0 */
454 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
455 reg->U1BC_LEDConfigure |= 0x10;
456 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
457 }
458 }
459 break;
460 case 6: /* [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */
461 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
462 /* Blinking if scanning is on progress */
463 if (pHwData->LED_Scanning) {
464 if (pHwData->LED_Blinking == 0) {
465 reg->U1BC_LEDConfigure &= ~0xf;
466 reg->U1BC_LEDConfigure |= 0x10;
467 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */
468 pHwData->LED_Blinking = 1;
469 TimeInterval = 300;
470 } else {
471 reg->U1BC_LEDConfigure &= ~0x1f;
472 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
473 pHwData->LED_Blinking = 0;
474 TimeInterval = 300;
475 }
476 } else {
477 /* Gray blinking if in disconnect state and not scanning */
478 ltmp = reg->U1BC_LEDConfigure;
479 reg->U1BC_LEDConfigure &= ~0x1f;
480 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) {
481 reg->U1BC_LEDConfigure |= 0x10;
482 reg->U1BC_LEDConfigure |=
483 LED_GRAY2[(pHwData->LED_Blinking % 30)];
484 }
485 pHwData->LED_Blinking++;
486 if (reg->U1BC_LEDConfigure != ltmp)
487 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
488 TimeInterval = 100;
489 }
490 } else {
491 /* Turn On LED_0 */
492 if ((reg->U1BC_LEDConfigure & 0x10) == 0) {
493 reg->U1BC_LEDConfigure |= 0x10;
494 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */
495 }
496 }
497 break;
498 case 5: /* [101] Only 1 Led be placed on PCB and use LED_1 for showing */
499 if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */
500 /* Blinking if scanning is on progress */
501 if (pHwData->LED_Scanning) {
502 if (pHwData->LED_Blinking == 0) {
503 reg->U1BC_LEDConfigure |= 0x1000;
504 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
505 pHwData->LED_Blinking = 1;
506 TimeInterval = 300;
507 } else {
508 reg->U1BC_LEDConfigure &= ~0x1000;
509 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
510 pHwData->LED_Blinking = 0;
511 TimeInterval = 300;
512 }
513 } else {
514 /* Turn Off LED_1 */
515 if (reg->U1BC_LEDConfigure & 0x1000) {
516 reg->U1BC_LEDConfigure &= ~0x1000;
517 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */
518 }
519 }
520 } else {
521 /* Is transmitting/receiving ?? */
522 if ((adapter->RxByteCount !=
523 pHwData->RxByteCountLast)
524 || (adapter->TxByteCount !=
525 pHwData->TxByteCountLast)) {
526 if ((reg->U1BC_LEDConfigure & 0x3000) !=
527 0x3000) {
528 reg->U1BC_LEDConfigure |= 0x3000;
529 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
530 }
531 /* Update variable */
532 pHwData->RxByteCountLast =
533 adapter->RxByteCount;
534 pHwData->TxByteCountLast =
535 adapter->TxByteCount;
536 TimeInterval = 200;
537 } else {
538 /* Turn On LED_1 and blinking if transmitting/receiving */
539 if ((reg->U1BC_LEDConfigure & 0x3000) !=
540 0x1000) {
541 reg->U1BC_LEDConfigure &=
542 ~0x3000;
543 reg->U1BC_LEDConfigure |=
544 0x1000;
545 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */
546 }
547 }
548 }
549 break;
550 default: /* Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active */
551 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) {
552 reg->U1BC_LEDConfigure |= 0x3000; /* LED_1 is always on and event enable */
553 Wb35Reg_Write(pHwData, 0x03bc,
554 reg->U1BC_LEDConfigure);
555 }
556
557 if (pHwData->LED_Blinking) {
558 /* Gray blinking */
559 reg->U1BC_LEDConfigure &= ~0x0f;
560 reg->U1BC_LEDConfigure |= 0x10;
561 reg->U1BC_LEDConfigure |=
562 LED_GRAY[(pHwData->LED_Blinking - 1) % 20];
563 Wb35Reg_Write(pHwData, 0x03bc,
564 reg->U1BC_LEDConfigure);
565
566 pHwData->LED_Blinking += 2;
567 if (pHwData->LED_Blinking < 40)
568 TimeInterval = 100;
569 else {
570 pHwData->LED_Blinking = 0; /* Stop blinking */
571 reg->U1BC_LEDConfigure &= ~0x0f;
572 Wb35Reg_Write(pHwData, 0x03bc,
573 reg->U1BC_LEDConfigure);
574 }
575 break;
576 }
577
578 if (pHwData->LED_LinkOn) {
579 if (!(reg->U1BC_LEDConfigure & 0x10)) { /* Check the LED_0 */
580 /* Try to turn ON LED_0 after gray blinking */
581 reg->U1BC_LEDConfigure |= 0x10;
582 pHwData->LED_Blinking = 1; /* Start blinking */
583 TimeInterval = 50;
584 }
585 } else {
586 if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */
587 reg->U1BC_LEDConfigure &= ~0x10;
588 Wb35Reg_Write(pHwData, 0x03bc,
589 reg->U1BC_LEDConfigure);
590 }
591 }
592 break;
593 }
594
595 /* Active send null packet to avoid AP disconnect */
596 if (pHwData->LED_LinkOn) {
597 pHwData->NullPacketCount += TimeInterval;
598 if (pHwData->NullPacketCount >=
599 DEFAULT_NULL_PACKET_COUNT) {
600 pHwData->NullPacketCount = 0;
601 }
602 }
603 }
604
605 pHwData->time_count += TimeInterval;
606 Wb35Tx_CurrentTime(adapter, pHwData->time_count);
607 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval);
608 add_timer(&pHwData->LEDTimer);
609 }
610
611 static int hal_init_hardware(struct ieee80211_hw *hw)
612 {
613 struct wbsoft_priv *priv = hw->priv;
614 struct hw_data *pHwData = &priv->sHwData;
615 u16 SoftwareSet;
616
617 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME;
618 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
619
620 if (!Wb35Reg_initial(pHwData))
621 goto error_reg_destroy;
622
623 if (!Wb35Tx_initial(pHwData))
624 goto error_tx_destroy;
625
626 if (!Wb35Rx_initial(pHwData))
627 goto error_rx_destroy;
628
629 init_timer(&pHwData->LEDTimer);
630 pHwData->LEDTimer.function = hal_led_control;
631 pHwData->LEDTimer.data = (unsigned long)priv;
632 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000);
633 add_timer(&pHwData->LEDTimer);
634
635 SoftwareSet = hal_software_set(pHwData);
636
637 #ifdef Vendor2
638 /* Try to make sure the EEPROM contain */
639 SoftwareSet >>= 8;
640 if (SoftwareSet != 0x82)
641 return false;
642 #endif
643
644 Wb35Rx_start(hw);
645 Wb35Tx_EP2VM_start(priv);
646
647 return 0;
648
649 error_rx_destroy:
650 Wb35Rx_destroy(pHwData);
651 error_tx_destroy:
652 Wb35Tx_destroy(pHwData);
653 error_reg_destroy:
654 Wb35Reg_destroy(pHwData);
655
656 pHwData->SurpriseRemove = 1;
657 return -EINVAL;
658 }
659
660 static int wb35_hw_init(struct ieee80211_hw *hw)
661 {
662 struct wbsoft_priv *priv = hw->priv;
663 struct hw_data *pHwData = &priv->sHwData;
664 u8 EEPROM_region;
665 u8 HwRadioOff;
666 u8 *pMacAddr2;
667 u8 *pMacAddr;
668 int err;
669
670 pHwData->phy_type = RF_DECIDE_BY_INF;
671
672 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
673 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
674
675 priv->sLocalPara.region_INF = REGION_AUTO;
676 priv->sLocalPara.TxRateMode = RATE_AUTO;
677 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG;
678 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
679 priv->sLocalPara.bPreambleMode = AUTO_MODE;
680 priv->sLocalPara.bWepKeyError = false;
681 priv->sLocalPara.bToSelfPacketReceived = false;
682 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */
683
684 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false;
685
686 err = hal_init_hardware(hw);
687 if (err)
688 goto error;
689
690 EEPROM_region = hal_get_region_from_EEPROM(pHwData);
691 if (EEPROM_region != REGION_AUTO)
692 priv->sLocalPara.region = EEPROM_region;
693 else {
694 if (priv->sLocalPara.region_INF != REGION_AUTO)
695 priv->sLocalPara.region = priv->sLocalPara.region_INF;
696 else
697 priv->sLocalPara.region = REGION_USA; /* default setting */
698 }
699
700 Mds_initial(priv);
701
702 /*
703 * If no user-defined address in the registry, use the address
704 * "burned" on the NIC instead.
705 */
706 pMacAddr = priv->sLocalPara.ThisMacAddress;
707 pMacAddr2 = priv->sLocalPara.PermanentAddress;
708
709 /* Reading ethernet address from EEPROM */
710 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress);
711 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0)
712 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH);
713 else {
714 /* Set the user define MAC address */
715 hal_set_ethernet_address(pHwData,
716 priv->sLocalPara.ThisMacAddress);
717 }
718
719 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
720 #ifdef _PE_STATE_DUMP_
721 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
722 #endif
723 hal_get_hw_radio_off(pHwData);
724
725 /* Waiting for HAL setting OK */
726 while (!hal_idle(pHwData))
727 msleep(10);
728
729 MTO_Init(priv);
730
731 HwRadioOff = hal_get_hw_radio_off(pHwData);
732 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff;
733
734 hal_set_radio_mode(pHwData,
735 (unsigned char)(priv->sLocalPara.RadioOffStatus.
736 boSwRadioOff
737 || priv->sLocalPara.RadioOffStatus.
738 boHwRadioOff));
739
740 /* Notify hal that the driver is ready now. */
741 hal_driver_init_OK(pHwData) = 1;
742
743 error:
744 return err;
745 }
746
747 static int wb35_probe(struct usb_interface *intf,
748 const struct usb_device_id *id_table)
749 {
750 struct usb_device *udev = interface_to_usbdev(intf);
751 struct usb_endpoint_descriptor *endpoint;
752 struct usb_host_interface *interface;
753 struct ieee80211_hw *dev;
754 struct wbsoft_priv *priv;
755 struct wb_usb *pWbUsb;
756 int nr, err;
757 u32 ltmp;
758
759 usb_get_dev(udev);
760
761 /* Check the device if it already be opened */
762 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
763 0x01,
764 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
765 0x0, 0x400, &ltmp, 4, HZ * 100);
766 if (nr < 0) {
767 err = nr;
768 goto error;
769 }
770
771 /* Is already initialized? */
772 ltmp = cpu_to_le32(ltmp);
773 if (ltmp) {
774 err = -EBUSY;
775 goto error;
776 }
777
778 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
779 if (!dev) {
780 err = -ENOMEM;
781 goto error;
782 }
783
784 priv = dev->priv;
785
786 spin_lock_init(&priv->SpinLock);
787
788 pWbUsb = &priv->sHwData.WbUsb;
789 pWbUsb->udev = udev;
790
791 interface = intf->cur_altsetting;
792 endpoint = &interface->endpoint[0].desc;
793
794 if (endpoint[2].wMaxPacketSize == 512) {
795 printk("[w35und] Working on USB 2.0\n");
796 pWbUsb->IsUsb20 = 1;
797 }
798
799 err = wb35_hw_init(dev);
800 if (err)
801 goto error_free_hw;
802
803 SET_IEEE80211_DEV(dev, &udev->dev);
804 {
805 struct hw_data *pHwData = &priv->sHwData;
806 unsigned char dev_addr[MAX_ADDR_LEN];
807 hal_get_permanent_address(pHwData, dev_addr);
808 SET_IEEE80211_PERM_ADDR(dev, dev_addr);
809 }
810
811 dev->extra_tx_headroom = 12; /* FIXME */
812 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
813 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
814
815 dev->channel_change_time = 1000;
816 dev->max_signal = 100;
817 dev->queues = 1;
818
819 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
820
821 err = ieee80211_register_hw(dev);
822 if (err)
823 goto error_free_hw;
824
825 usb_set_intfdata(intf, dev);
826
827 return 0;
828
829 error_free_hw:
830 ieee80211_free_hw(dev);
831 error:
832 usb_put_dev(udev);
833 return err;
834 }
835
836 static void hal_halt(struct hw_data *pHwData)
837 {
838 del_timer_sync(&pHwData->LEDTimer);
839 /* XXX: Wait for Timer DPC exit. */
840 msleep(100);
841 Wb35Rx_destroy(pHwData);
842 Wb35Tx_destroy(pHwData);
843 Wb35Reg_destroy(pHwData);
844 }
845
846 static void wb35_hw_halt(struct wbsoft_priv *adapter)
847 {
848 Mds_Destroy(adapter);
849
850 /* Turn off Rx and Tx hardware ability */
851 hal_stop(&adapter->sHwData);
852 #ifdef _PE_USB_INI_DUMP_
853 printk("[w35und] Hal_stop O.K.\n");
854 #endif
855 /* Waiting Irp completed */
856 msleep(100);
857
858 hal_halt(&adapter->sHwData);
859 }
860
861 static void wb35_disconnect(struct usb_interface *intf)
862 {
863 struct ieee80211_hw *hw = usb_get_intfdata(intf);
864 struct wbsoft_priv *priv = hw->priv;
865
866 wb35_hw_halt(priv);
867
868 ieee80211_stop_queues(hw);
869 ieee80211_unregister_hw(hw);
870 ieee80211_free_hw(hw);
871
872 usb_set_intfdata(intf, NULL);
873 usb_put_dev(interface_to_usbdev(intf));
874 }
875
876 static struct usb_driver wb35_driver = {
877 .name = "w35und",
878 .id_table = wb35_table,
879 .probe = wb35_probe,
880 .disconnect = wb35_disconnect,
881 };
882
883 static int __init wb35_init(void)
884 {
885 return usb_register(&wb35_driver);
886 }
887
888 static void __exit wb35_exit(void)
889 {
890 usb_deregister(&wb35_driver);
891 }
892
893 module_init(wb35_init);
894 module_exit(wb35_exit);