• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/staging/winbond/
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
22MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
23MODULE_LICENSE("GPL");
24MODULE_VERSION("0.1");
25
26static 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
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_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
77static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78				    struct ieee80211_vif *vif)
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 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
101static 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
120static 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
129static 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
138static 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
155static 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
178static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
179{
180	hal_set_current_channel_ex(pHwData, channel);
181}
182
183static 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. */
199static 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
215static 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
228static 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
245static 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
266static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
267{
268	printk("wbsoft_get_tsf called\n");
269	return 0;
270}
271
272static 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
285static 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
300static 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
308static 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
322static 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
334u8 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 */
345static 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
363static 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
367static 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
372static 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
611static 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
649error_rx_destroy:
650	Wb35Rx_destroy(pHwData);
651error_tx_destroy:
652	Wb35Tx_destroy(pHwData);
653error_reg_destroy:
654	Wb35Reg_destroy(pHwData);
655
656	pHwData->SurpriseRemove = 1;
657	return -EINVAL;
658}
659
660static 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
743error:
744	return err;
745}
746
747static 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;
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
829error_free_hw:
830	ieee80211_free_hw(dev);
831error:
832	usb_put_dev(udev);
833	return err;
834}
835
836static void hal_halt(struct hw_data *pHwData)
837{
838	del_timer_sync(&pHwData->LEDTimer);
839	msleep(100);
840	Wb35Rx_destroy(pHwData);
841	Wb35Tx_destroy(pHwData);
842	Wb35Reg_destroy(pHwData);
843}
844
845static void wb35_hw_halt(struct wbsoft_priv *adapter)
846{
847	Mds_Destroy(adapter);
848
849	/* Turn off Rx and Tx hardware ability */
850	hal_stop(&adapter->sHwData);
851#ifdef _PE_USB_INI_DUMP_
852	printk("[w35und] Hal_stop O.K.\n");
853#endif
854	/* Waiting Irp completed */
855	msleep(100);
856
857	hal_halt(&adapter->sHwData);
858}
859
860static void wb35_disconnect(struct usb_interface *intf)
861{
862	struct ieee80211_hw *hw = usb_get_intfdata(intf);
863	struct wbsoft_priv *priv = hw->priv;
864
865	wb35_hw_halt(priv);
866
867	ieee80211_stop_queues(hw);
868	ieee80211_unregister_hw(hw);
869	ieee80211_free_hw(hw);
870
871	usb_set_intfdata(intf, NULL);
872	usb_put_dev(interface_to_usbdev(intf));
873}
874
875static struct usb_driver wb35_driver = {
876	.name		= "w35und",
877	.id_table	= wb35_table,
878	.probe		= wb35_probe,
879	.disconnect	= wb35_disconnect,
880};
881
882static int __init wb35_init(void)
883{
884	return usb_register(&wb35_driver);
885}
886
887static void __exit wb35_exit(void)
888{
889	usb_deregister(&wb35_driver);
890}
891
892module_init(wb35_init);
893module_exit(wb35_exit);
894