2 * Copyright 2008 Pavel Machek <pavel@suse.cz>
4 * Distribute under GPLv2.
6 #include <net/mac80211.h>
11 #include "mlmetxrx_f.h"
14 #include "wblinux_f.h"
16 MODULE_AUTHOR("Original by: Jeff Lee<YY_Lee@issc.com.tw> Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>");
17 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
18 MODULE_LICENSE("GPL");
19 MODULE_VERSION("0.1");
21 static struct usb_device_id wb35_table
[] __devinitdata
= {
22 {USB_DEVICE(0x0416, 0x0035)},
23 {USB_DEVICE(0x18E8, 0x6201)},
24 {USB_DEVICE(0x18E8, 0x6206)},
25 {USB_DEVICE(0x18E8, 0x6217)},
26 {USB_DEVICE(0x18E8, 0x6230)},
27 {USB_DEVICE(0x18E8, 0x6233)},
28 {USB_DEVICE(0x1131, 0x2035)},
32 MODULE_DEVICE_TABLE(usb
, wb35_table
);
34 static struct ieee80211_rate wbsoft_rates
[] = {
35 { .bitrate
= 10, .flags
= IEEE80211_RATE_SHORT_PREAMBLE
},
38 static struct ieee80211_channel wbsoft_channels
[] = {
39 { .center_freq
= 2412},
42 static struct ieee80211_supported_band wbsoft_band_2GHz
= {
43 .channels
= wbsoft_channels
,
44 .n_channels
= ARRAY_SIZE(wbsoft_channels
),
45 .bitrates
= wbsoft_rates
,
46 .n_bitrates
= ARRAY_SIZE(wbsoft_rates
),
49 static int wbsoft_add_interface(struct ieee80211_hw
*dev
,
50 struct ieee80211_if_init_conf
*conf
)
52 printk("wbsoft_add interface called\n");
56 static void wbsoft_remove_interface(struct ieee80211_hw
*dev
,
57 struct ieee80211_if_init_conf
*conf
)
59 printk("wbsoft_remove interface called\n");
62 static void wbsoft_stop(struct ieee80211_hw
*hw
)
64 printk(KERN_INFO
"%s called\n", __func__
);
67 static int wbsoft_get_stats(struct ieee80211_hw
*hw
,
68 struct ieee80211_low_level_stats
*stats
)
70 printk(KERN_INFO
"%s called\n", __func__
);
74 static int wbsoft_get_tx_stats(struct ieee80211_hw
*hw
,
75 struct ieee80211_tx_queue_stats
*stats
)
77 printk(KERN_INFO
"%s called\n", __func__
);
81 static void wbsoft_configure_filter(struct ieee80211_hw
*dev
,
82 unsigned int changed_flags
,
83 unsigned int *total_flags
,
84 int mc_count
, struct dev_mc_list
*mclist
)
86 unsigned int bit_nr
, new_flags
;
92 if (*total_flags
& FIF_PROMISC_IN_BSS
) {
93 new_flags
|= FIF_PROMISC_IN_BSS
;
94 mc_filter
[1] = mc_filter
[0] = ~0;
95 } else if ((*total_flags
& FIF_ALLMULTI
) || (mc_count
> 32)) {
96 new_flags
|= FIF_ALLMULTI
;
97 mc_filter
[1] = mc_filter
[0] = ~0;
99 mc_filter
[1] = mc_filter
[0] = 0;
100 for (i
= 0; i
< mc_count
; i
++) {
103 printk("Should call ether_crc here\n");
104 //bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
108 mc_filter
[bit_nr
>> 5] |= 1 << (bit_nr
& 31);
109 mclist
= mclist
->next
;
113 dev
->flags
&= ~IEEE80211_HW_RX_INCLUDES_FCS
;
115 *total_flags
= new_flags
;
118 static int wbsoft_tx(struct ieee80211_hw
*dev
, struct sk_buff
*skb
)
120 struct wbsoft_priv
*priv
= dev
->priv
;
122 MLMESendFrame(priv
, skb
->data
, skb
->len
, FRAME_TYPE_802_11_MANAGEMENT
);
128 static int wbsoft_start(struct ieee80211_hw
*dev
)
130 struct wbsoft_priv
*priv
= dev
->priv
;
132 priv
->enabled
= true;
137 static int wbsoft_config(struct ieee80211_hw
*dev
, u32 changed
)
139 struct wbsoft_priv
*priv
= dev
->priv
;
140 struct ieee80211_conf
*conf
= &dev
->conf
;
143 printk("wbsoft_config called\n");
146 ch
.ChanNo
= 1; /* Should use channel_num, or something, as that is already pre-translated */
149 hal_set_current_channel(&priv
->sHwData
, ch
);
150 hal_set_beacon_period(&priv
->sHwData
, conf
->beacon_int
);
151 // hal_set_cap_info(&priv->sHwData, ?? );
152 // hal_set_ssid(struct hw_data * pHwData, u8 * pssid, u8 ssid_len); ??
153 hal_set_accept_broadcast(&priv
->sHwData
, 1);
154 hal_set_accept_promiscuous(&priv
->sHwData
, 1);
155 hal_set_accept_multicast(&priv
->sHwData
, 1);
156 hal_set_accept_beacon(&priv
->sHwData
, 1);
157 hal_set_radio_mode(&priv
->sHwData
, 0);
158 //hal_set_antenna_number( struct hw_data * pHwData, u8 number )
159 //hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
162 // hal_start_bss(&priv->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ??
164 //void hal_set_rates(struct hw_data * pHwData, u8 * pbss_rates,
165 // u8 length, unsigned char basic_rate_set)
170 static int wbsoft_config_interface(struct ieee80211_hw
*dev
,
171 struct ieee80211_vif
*vif
,
172 struct ieee80211_if_conf
*conf
)
174 printk("wbsoft_config_interface called\n");
178 static u64
wbsoft_get_tsf(struct ieee80211_hw
*dev
)
180 printk("wbsoft_get_tsf called\n");
184 static const struct ieee80211_ops wbsoft_ops
= {
186 .start
= wbsoft_start
, /* Start can be pretty much empty as we do wb35_hw_init() during probe? */
188 .add_interface
= wbsoft_add_interface
,
189 .remove_interface
= wbsoft_remove_interface
,
190 .config
= wbsoft_config
,
191 .config_interface
= wbsoft_config_interface
,
192 .configure_filter
= wbsoft_configure_filter
,
193 .get_stats
= wbsoft_get_stats
,
194 .get_tx_stats
= wbsoft_get_tx_stats
,
195 .get_tsf
= wbsoft_get_tsf
,
196 // conf_tx: hal_set_cwmin()/hal_set_cwmax;
199 static unsigned char wb35_hw_init(struct ieee80211_hw
*hw
)
201 struct wbsoft_priv
*priv
= hw
->priv
;
202 struct hw_data
* pHwData
;
210 // Setting default value for Linux
212 priv
->sLocalPara
.region_INF
= REGION_AUTO
;
213 priv
->sLocalPara
.TxRateMode
= RATE_AUTO
;
214 priv
->sLocalPara
.bMacOperationMode
= MODE_802_11_BG
; // B/G mode
215 priv
->Mds
.TxRTSThreshold
= DEFAULT_RTSThreshold
;
216 priv
->Mds
.TxFragmentThreshold
= DEFAULT_FRAGMENT_THRESHOLD
;
217 hal_set_phy_type( &priv
->sHwData
, RF_WB_242_1
);
218 priv
->sLocalPara
.MTUsize
= MAX_ETHERNET_PACKET_SIZE
;
219 priv
->sLocalPara
.bPreambleMode
= AUTO_MODE
;
220 priv
->sLocalPara
.RadioOffStatus
.boSwRadioOff
= false;
221 pHwData
= &priv
->sHwData
;
222 hal_set_phy_type( pHwData
, RF_DECIDE_BY_INF
);
224 //added by ws for wep key error detection
225 priv
->sLocalPara
.bWepKeyError
= false;
226 priv
->sLocalPara
.bToSelfPacketReceived
= false;
227 priv
->sLocalPara
.WepKeyDetectTimerCount
= 2 * 100; /// 2 seconds
231 pHwData
= &priv
->sHwData
;
232 if (!hal_init_hardware(hw
))
235 EEPROM_region
= hal_get_region_from_EEPROM( pHwData
);
236 if (EEPROM_region
!= REGION_AUTO
)
237 priv
->sLocalPara
.region
= EEPROM_region
;
239 if (priv
->sLocalPara
.region_INF
!= REGION_AUTO
)
240 priv
->sLocalPara
.region
= priv
->sLocalPara
.region_INF
;
242 priv
->sLocalPara
.region
= REGION_USA
; //default setting
245 // Get Software setting flag from hal
246 priv
->sLocalPara
.boAntennaDiversity
= false;
247 if (hal_software_set(pHwData
) & 0x00000001)
248 priv
->sLocalPara
.boAntennaDiversity
= true;
259 //=======================================
260 // Initialize the SME, SCAN, MLME, ROAM
261 //=======================================
266 // If no user-defined address in the registry, use the addresss "burned" on the NIC instead.
267 pMacAddr
= priv
->sLocalPara
.ThisMacAddress
;
268 pMacAddr2
= priv
->sLocalPara
.PermanentAddress
;
269 hal_get_permanent_address( pHwData
, priv
->sLocalPara
.PermanentAddress
);// Reading ethernet address from EEPROM
270 if (memcmp(pMacAddr
, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH
) == 0)
271 memcpy(pMacAddr
, pMacAddr2
, MAC_ADDR_LENGTH
);
273 // Set the user define MAC address
274 hal_set_ethernet_address(pHwData
, priv
->sLocalPara
.ThisMacAddress
);
277 //get current antenna
278 priv
->sLocalPara
.bAntennaNo
= hal_get_antenna_number(pHwData
);
279 #ifdef _PE_STATE_DUMP_
280 printk("Driver init, antenna no = %d\n", psLOCAL
->bAntennaNo
);
282 hal_get_hw_radio_off( pHwData
);
284 // Waiting for HAL setting OK
285 while (!hal_idle(pHwData
))
290 HwRadioOff
= hal_get_hw_radio_off( pHwData
);
291 priv
->sLocalPara
.RadioOffStatus
.boHwRadioOff
= !!HwRadioOff
;
293 hal_set_radio_mode( pHwData
, (unsigned char)(priv
->sLocalPara
.RadioOffStatus
.boSwRadioOff
|| priv
->sLocalPara
.RadioOffStatus
.boHwRadioOff
) );
295 hal_driver_init_OK(pHwData
) = 1; // Notify hal that the driver is ready now.
296 //set a tx power for reference.....
297 // sme_set_tx_power_level(priv, 12); FIXME?
304 case 3: Mds_Destroy( priv
);
306 case 1: hal_halt( pHwData
, NULL
);
313 static int wb35_probe(struct usb_interface
*intf
, const struct usb_device_id
*id_table
)
315 struct wb_usb
*pWbUsb
;
316 struct usb_host_interface
*interface
;
317 struct usb_endpoint_descriptor
*endpoint
;
319 struct usb_device
*udev
= interface_to_usbdev(intf
);
320 struct wbsoft_priv
*priv
;
321 struct ieee80211_hw
*dev
;
326 // 20060630.2 Check the device if it already be opened
327 nr
= usb_control_msg(udev
, usb_rcvctrlpipe( udev
, 0 ),
328 0x01, USB_TYPE_VENDOR
|USB_RECIP_DEVICE
|USB_DIR_IN
,
329 0x0, 0x400, <mp
, 4, HZ
*100 );
335 ltmp
= cpu_to_le32(ltmp
);
336 if (ltmp
) { // Is already initialized?
341 dev
= ieee80211_alloc_hw(sizeof(*priv
), &wbsoft_ops
);
349 spin_lock_init(&priv
->SpinLock
);
351 pWbUsb
= &priv
->sHwData
.WbUsb
;
354 interface
= intf
->cur_altsetting
;
355 endpoint
= &interface
->endpoint
[0].desc
;
357 if (endpoint
[2].wMaxPacketSize
== 512) {
358 printk("[w35und] Working on USB 2.0\n");
362 if (!wb35_hw_init(dev
)) {
367 SET_IEEE80211_DEV(dev
, &udev
->dev
);
369 struct hw_data
* pHwData
= &priv
->sHwData
;
370 unsigned char dev_addr
[MAX_ADDR_LEN
];
371 hal_get_permanent_address(pHwData
, dev_addr
);
372 SET_IEEE80211_PERM_ADDR(dev
, dev_addr
);
375 dev
->extra_tx_headroom
= 12; /* FIXME */
376 dev
->flags
= IEEE80211_HW_SIGNAL_UNSPEC
;
377 dev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
);
379 dev
->channel_change_time
= 1000;
380 dev
->max_signal
= 100;
383 dev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &wbsoft_band_2GHz
;
385 err
= ieee80211_register_hw(dev
);
389 usb_set_intfdata(intf
, dev
);
394 ieee80211_free_hw(dev
);
400 static void wb35_hw_halt(struct wbsoft_priv
*adapter
)
402 Mds_Destroy( adapter
);
404 // Turn off Rx and Tx hardware ability
405 hal_stop( &adapter
->sHwData
);
406 #ifdef _PE_USB_INI_DUMP_
407 printk("[w35und] Hal_stop O.K.\n");
409 msleep(100);// Waiting Irp completed
412 hal_halt(&adapter
->sHwData
, NULL
);
416 static void wb35_disconnect(struct usb_interface
*intf
)
418 struct ieee80211_hw
*hw
= usb_get_intfdata(intf
);
419 struct wbsoft_priv
*priv
= hw
->priv
;
423 ieee80211_stop_queues(hw
);
424 ieee80211_unregister_hw(hw
);
425 ieee80211_free_hw(hw
);
427 usb_set_intfdata(intf
, NULL
);
428 usb_put_dev(interface_to_usbdev(intf
));
431 static struct usb_driver wb35_driver
= {
433 .id_table
= wb35_table
,
435 .disconnect
= wb35_disconnect
,
438 static int __init
wb35_init(void)
440 return usb_register(&wb35_driver
);
443 static void __exit
wb35_exit(void)
445 usb_deregister(&wb35_driver
);
448 module_init(wb35_init
);
449 module_exit(wb35_exit
);