/drivers/staging/wlags49_h2/wl_main.c
C | 3870 lines | 2275 code | 523 blank | 1072 comment | 351 complexity | c3bd0e383eb30eee9671e4ec54fcf7cc MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
1/*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
4 *
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
11 *
12 *------------------------------------------------------------------------------
13 *
14 * This file contains the main driver entry points and other adapter
15 * specific routines.
16 *
17 *------------------------------------------------------------------------------
18 *
19 * SOFTWARE LICENSE
20 *
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
25 *
26 * Copyright � 2003 Agere Systems Inc.
27 * All rights reserved.
28 *
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
31 *
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
35 * distribution.
36 *
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 *
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * Disclaimer
46 *
47 * THIS SOFTWARE IS PROVIDED �AS IS� AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58 * DAMAGE.
59 *
60 ******************************************************************************/
61
62/*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
65
66/* Allow support for calling system fcns to access F/W iamge file */
67#define __KERNEL_SYSCALLS__
68
69/*******************************************************************************
70 * include files
71 ******************************************************************************/
72#include <wl_version.h>
73
74#include <linux/module.h>
75#include <linux/proc_fs.h>
76#include <linux/types.h>
77#include <linux/kernel.h>
78// #include <linux/sched.h>
79// #include <linux/ptrace.h>
80// #include <linux/slab.h>
81// #include <linux/ctype.h>
82// #include <linux/string.h>
83// #include <linux/timer.h>
84//#include <linux/interrupt.h>
85// #include <linux/tqueue.h>
86// #include <linux/in.h>
87// #include <linux/delay.h>
88// #include <asm/io.h>
89// #include <asm/system.h>
90// #include <asm/bitops.h>
91#include <linux/unistd.h>
92#include <asm/uaccess.h>
93
94#include <linux/netdevice.h>
95#include <linux/etherdevice.h>
96// #include <linux/skbuff.h>
97// #include <linux/if_arp.h>
98// #include <linux/ioport.h>
99
100#define BIN_DL 0
101#if BIN_DL
102#include <linux/vmalloc.h>
103#endif // BIN_DL
104
105
106#include <debug.h>
107
108#include <hcf.h>
109#include <dhf.h>
110//in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
111#include <hcfdef.h>
112
113#include <wl_if.h>
114#include <wl_internal.h>
115#include <wl_util.h>
116#include <wl_main.h>
117#include <wl_netdev.h>
118#include <wl_wext.h>
119
120#ifdef USE_PROFILE
121#include <wl_profile.h>
122#endif /* USE_PROFILE */
123
124#ifdef BUS_PCMCIA
125#include <wl_cs.h>
126#endif /* BUS_PCMCIA */
127
128#ifdef BUS_PCI
129#include <wl_pci.h>
130#endif /* BUS_PCI */
131/*******************************************************************************
132 * macro defintions
133 ******************************************************************************/
134#define VALID_PARAM(C) \
135 { \
136 if (!(C)) \
137 { \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
139 goto failed; \
140 } \
141 }
142/*******************************************************************************
143 * local functions
144 ******************************************************************************/
145void wl_isr_handler( unsigned long p );
146
147#if 0 //SCULL_USE_PROC /* don't waste space if unused */
148//int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
149int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
150static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
151static void proc_write(const char *name, write_proc_t *w, void *data);
152
153#endif /* SCULL_USE_PROC */
154
155/*******************************************************************************
156 * module parameter definitions - set with 'insmod'
157 ******************************************************************************/
158static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
159static p_s8 irq_list[4] = { -1 };
160
161#if 0
162MODULE_PARM(irq_mask, "h");
163MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
164MODULE_PARM(irq_list, "1-4b");
165MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
166#endif
167
168static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
169static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
170static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
171static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
172static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
173static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
174static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
175static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
176static p_char *PARM_DOWNLOAD_FIRMWARE = "";
177static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
178static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
179static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
180static p_char *PARM_KEY1 = "";
181static p_char *PARM_KEY2 = "";
182static p_char *PARM_KEY3 = "";
183static p_char *PARM_KEY4 = "";
184static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
185static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
186static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
187static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
188static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
189static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
190static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
191static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
192static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
193static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
194static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
195static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
196static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
197static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
198static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
199static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
200static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
201static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
202static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
203#ifdef USE_WDS
204static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
205static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
206static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
207static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
208static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
209static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
210#endif // USE_WDS
211static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
212static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
213static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
214static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
215static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
216static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
217#ifdef USE_WDS
218static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
219static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
220static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
221static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
222static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
223static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
224#endif // USE_WDS
225static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
226#ifdef USE_WDS
227static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
228static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
229static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
230static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
231static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
232static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
233#endif // USE_WDS
234
235
236#if 0
237MODULE_PARM(PARM_DESIRED_SSID, "s");
238MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
239MODULE_PARM(PARM_OWN_SSID, "s");
240MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
241MODULE_PARM(PARM_OWN_CHANNEL, "b");
242MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
243MODULE_PARM(PARM_SYSTEM_SCALE, "b");
244MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
245MODULE_PARM(PARM_TX_RATE, "b");
246MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
247MODULE_PARM(PARM_RTS_THRESHOLD, "h");
248MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
249MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
250MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
251MODULE_PARM(PARM_OWN_NAME, "s");
252MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
253
254MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
255MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
256
257MODULE_PARM(PARM_KEY1, "s");
258MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
259MODULE_PARM(PARM_KEY2, "s");
260MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
261MODULE_PARM(PARM_KEY3, "s");
262MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
263MODULE_PARM(PARM_KEY4, "s");
264MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
265MODULE_PARM(PARM_TX_KEY, "b");
266MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
267MODULE_PARM(PARM_MULTICAST_RATE, "b");
268MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
269MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
270MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
271
272MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
273MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
274
275MODULE_PARM(PARM_LOAD_BALANCING, "s");
276MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
277MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
278MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
279MODULE_PARM(PARM_TX_POW_LEVEL, "b");
280MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
281MODULE_PARM(PARM_SRSC_2GHZ, "b");
282MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
283MODULE_PARM(PARM_SRSC_5GHZ, "b");
284MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
285MODULE_PARM(PARM_BRSC_2GHZ, "b");
286MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
287MODULE_PARM(PARM_BRSC_5GHZ, "b");
288MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
289#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
290//;?seems reasonable that even an AP-only driver could afford this small additional footprint
291MODULE_PARM(PARM_PM_ENABLED, "h");
292MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
293MODULE_PARM(PARM_PORT_TYPE, "b");
294MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
295//;?MODULE_PARM(PARM_CREATE_IBSS, "s");
296//;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
297//;?MODULE_PARM(PARM_MULTICAST_RX, "s");
298//;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
299//;?MODULE_PARM(PARM_MAX_SLEEP, "h");
300//;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
301//;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
302//;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
303//;?MODULE_PARM(PARM_AUTHENTICATION, "b");
304//
305//tracker 12448
306//;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
307//;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
308//tracker 12448
309//
310//;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
311//;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
312//;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
313//;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
314//;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
315//;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
316//;?
317MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
318MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
319#endif /* HCF_STA */
320#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
321 //;?should we restore this to allow smaller memory footprint
322MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
323MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
324MODULE_PARM(PARM_REJECT_ANY, "s");
325MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
326MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
327MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
328MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
329MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
330MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
331MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
332MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
333MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
334MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
335MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
336MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
337MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
338MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
339MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
340MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
341MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
342MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
343MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
344MODULE_PARM(PARM_TX_RATE1, "b");
345MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
346MODULE_PARM(PARM_TX_RATE2, "b");
347MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
348MODULE_PARM(PARM_TX_RATE3, "b");
349MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
350MODULE_PARM(PARM_TX_RATE4, "b");
351MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
352MODULE_PARM(PARM_TX_RATE5, "b");
353MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
354MODULE_PARM(PARM_TX_RATE6, "b");
355MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
356MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
357MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
358MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
359MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
360MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
361MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
362MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
363MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
364MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
365MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
366MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
367MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
368
369MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
370MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
371MODULE_PARM(PARM_COEXISTENCE, "b");
372MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
373
374#endif /* HCF_AP */
375#endif
376
377/* END NEW PARAMETERS */
378/*******************************************************************************
379 * debugging specifics
380 ******************************************************************************/
381#if DBG
382
383static p_u32 pc_debug = DBG_LVL;
384//MODULE_PARM(pc_debug, "i");
385/*static ;?conflicts with my understanding of CL parameters and breaks now I moved
386 * the correspondig logic to wl_profile
387 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
388//MODULE_PARM(DebugFlag, "l");
389
390dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
391dbg_info_t *DbgInfo = &wl_info;
392
393#endif /* DBG */
394#ifdef USE_RTS
395
396static p_char *useRTS = "N";
397MODULE_PARM( useRTS, "s" );
398MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
399
400#endif /* USE_RTS */
401/*******************************************************************************
402 * firmware download specifics
403 ******************************************************************************/
404extern struct CFG_RANGE2_STRCT BASED
405 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
406
407#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
408extern memimage ap; // AP firmware image to be downloaded
409#endif /* HCF_AP */
410
411#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
412//extern memimage station; // STA firmware image to be downloaded
413extern memimage fw_image; // firmware image to be downloaded
414#endif /* HCF_STA */
415
416
417int wl_insert( struct net_device *dev )
418{
419 int result = 0;
420 int hcf_status = HCF_SUCCESS;
421 int i;
422 unsigned long flags = 0;
423 struct wl_private *lp = wl_priv(dev);
424 /*------------------------------------------------------------------------*/
425 DBG_FUNC( "wl_insert" );
426 DBG_ENTER( DbgInfo );
427
428 /* Initialize the adapter hardware. */
429 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
430
431 /* Initialize the adapter parameters. */
432 spin_lock_init( &( lp->slock ));
433
434 /* Initialize states */
435 //lp->lockcount = 0; //PE1DNN
436 lp->is_handling_int = WL_NOT_HANDLING_INT;
437 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
438
439 lp->dev = dev;
440
441 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
442 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
443 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
444 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
445 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
446 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
447 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
448 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
449 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
450 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
451 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
452 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
453//;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
454 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
455 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
456 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
457 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
458 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
459 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
460 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
461 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
462//;?#if (HCF_TYPE) & HCF_TYPE_STA
463 //;?should we make this code conditional depending on in STA mode
464//;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
465 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
466//;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
467//;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
468//;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
469/*
470 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
471 PARM_NETWORK_ADDR);
472 */
473//;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
474//;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
475//;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
476//;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
477//;?#endif /* HCF_STA */
478#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
479 //;?should we restore this to allow smaller memory footprint
480 //;?I guess: no, since this is Debug mode only
481 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
482 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
483 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
484 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
485 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
486#ifdef USE_WDS
487 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
488 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
489 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
490 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
491 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
492 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
493 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
494 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
495 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
496 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
497 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
498 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
499 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
500 PARM_WDS_ADDRESS1);
501 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
502 PARM_WDS_ADDRESS2);
503 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
504 PARM_WDS_ADDRESS3);
505 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
506 PARM_WDS_ADDRESS4);
507 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
508 PARM_WDS_ADDRESS5);
509 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
510 PARM_WDS_ADDRESS6);
511#endif /* USE_WDS */
512#endif /* HCF_AP */
513
514 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
515 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
516 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
517 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
518 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
519 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
520 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
521 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
522 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
523 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
524 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
525 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
526 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
527 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
528
529 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
530 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
531
532 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
533 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
534
535 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
536 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
537 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
538
539 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
540 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
541 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
542 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
543 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
544 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
545 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
546 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
547 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
548 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
549 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
550
551 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
552 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
553 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
554 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
555 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
556#ifdef USE_WDS
557 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
558 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
559 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
560 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
561 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
562 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
563 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
564 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
565 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
566 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
567 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
568 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
569#endif /* USE_WDS */
570
571 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
572 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
573
574 /* Set the driver parameters from the passed in parameters. */
575
576 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
577 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
578
579 /* START NEW PARAMETERS */
580
581 lp->Channel = PARM_OWN_CHANNEL;
582 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
583
584 /* Need to determine how to handle the new bands for 5GHz */
585 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
586 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
587
588 lp->RTSThreshold = PARM_RTS_THRESHOLD;
589
590 /* Need to determine how to handle the new bands for 5GHz */
591 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
592 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
593
594 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
595 lp->MicrowaveRobustness = 1;
596 } else {
597 lp->MicrowaveRobustness = 0;
598 }
599 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
600 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
601 }
602 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
603 strcpy( lp->NetworkName, PARM_OWN_SSID );
604 }
605 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
606 strcpy( lp->StationName, PARM_OWN_NAME );
607 }
608 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
609 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
610 strcpy( lp->Key1, PARM_KEY1 );
611 }
612 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
613 strcpy( lp->Key2, PARM_KEY2 );
614 }
615 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
616 strcpy( lp->Key3, PARM_KEY3 );
617 }
618 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
619 strcpy( lp->Key4, PARM_KEY4 );
620 }
621
622 lp->TransmitKeyID = PARM_TX_KEY;
623
624 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
625 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
626 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
627 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
628
629 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
630 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
631
632 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
633 lp->loadBalancing = 1;
634 } else {
635 lp->loadBalancing = 0;
636 }
637
638 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
639 lp->mediumDistribution = 1;
640 } else {
641 lp->mediumDistribution = 0;
642 }
643
644 lp->txPowLevel = PARM_TX_POW_LEVEL;
645
646 lp->srsc[0] = PARM_SRSC_2GHZ;
647 lp->srsc[1] = PARM_SRSC_5GHZ;
648 lp->brsc[0] = PARM_BRSC_2GHZ;
649 lp->brsc[1] = PARM_BRSC_5GHZ;
650#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
651//;?seems reasonable that even an AP-only driver could afford this small additional footprint
652 lp->PortType = PARM_PORT_TYPE;
653 lp->MaxSleepDuration = PARM_MAX_SLEEP;
654 lp->authentication = PARM_AUTHENTICATION;
655 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
656 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
657 lp->PMEnabled = PARM_PM_ENABLED; //;?
658 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
659 lp->CreateIBSS = 1;
660 } else {
661 lp->CreateIBSS = 0;
662 }
663 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
664 lp->MulticastReceive = 0;
665 } else {
666 lp->MulticastReceive = 1;
667 }
668 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
669 lp->promiscuousMode = 1;
670 } else {
671 lp->promiscuousMode = 0;
672 }
673 for( i = 0; i < ETH_ALEN; i++ ) {
674 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
675 }
676
677 lp->connectionControl = PARM_CONNECTION_CONTROL;
678
679#endif /* HCF_STA */
680#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
681 //;?should we restore this to allow smaller memory footprint
682 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
683
684 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
685 lp->RejectAny = 1;
686 } else {
687 lp->RejectAny = 0;
688 }
689 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
690 lp->ExcludeUnencrypted = 0;
691 } else {
692 lp->ExcludeUnencrypted = 1;
693 }
694 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
695 lp->multicastPMBuffering = 1;
696 } else {
697 lp->multicastPMBuffering = 0;
698 }
699 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
700 lp->intraBSSRelay = 1;
701 } else {
702 lp->intraBSSRelay = 0;
703 }
704
705 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
706 lp->coexistence = PARM_COEXISTENCE;
707
708#ifdef USE_WDS
709 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
710 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
711 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
712 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
713 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
714 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
715 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
716 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
717 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
718 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
719 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
720 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
721
722 for( i = 0; i < ETH_ALEN; i++ ) {
723 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
724 }
725 for( i = 0; i < ETH_ALEN; i++ ) {
726 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
727 }
728 for( i = 0; i < ETH_ALEN; i++ ) {
729 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
730 }
731 for( i = 0; i < ETH_ALEN; i++ ) {
732 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
733 }
734 for( i = 0; i < ETH_ALEN; i++ ) {
735 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
736 }
737 for( i = 0; i < ETH_ALEN; i++ ) {
738 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
739 }
740#endif /* USE_WDS */
741#endif /* HCF_AP */
742#ifdef USE_RTS
743 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
744 lp->useRTS = 1;
745 } else {
746 lp->useRTS = 0;
747 }
748#endif /* USE_RTS */
749
750
751 /* END NEW PARAMETERS */
752
753
754 wl_lock( lp, &flags );
755
756 /* Initialize the portState variable */
757 lp->portState = WVLAN_PORT_STATE_DISABLED;
758
759 /* Initialize the ScanResult struct */
760 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
761 lp->scan_results.scan_complete = FALSE;
762
763 /* Initialize the ProbeResult struct */
764 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
765 lp->probe_results.scan_complete = FALSE;
766 lp->probe_num_aps = 0;
767
768
769 /* Initialize Tx queue stuff */
770 memset( lp->txList, 0, sizeof( lp->txList ));
771
772 INIT_LIST_HEAD( &( lp->txFree ));
773
774 lp->txF.skb = NULL;
775 lp->txF.port = 0;
776
777
778 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
779 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
780 }
781
782
783 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
784 INIT_LIST_HEAD( &( lp->txQ[i] ));
785 }
786
787 lp->netif_queue_on = TRUE;
788 lp->txQ_count = 0;
789 /* Initialize the use_dma element in the adapter structure. Not sure if
790 this should be a compile-time or run-time configurable. So for now,
791 implement as run-time and just define here */
792#ifdef WARP
793#ifdef ENABLE_DMA
794 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
795 lp->use_dma = 1;
796#else
797 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
798 lp->use_dma = 0;
799#endif // ENABLE_DMA
800#endif // WARP
801
802 /* Register the ISR handler information here, so that it's not done
803 repeatedly in the ISR */
804 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
805
806 /* Connect to the adapter */
807 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
808 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
809 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
810 //HCF_ERR_INCOMP_PRI is not acceptable
811 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
812 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
813 wl_unlock( lp, &flags );
814 goto hcf_failed;
815 }
816
817 //;?should set HCF_version and how about driver_stat
818 lp->driverInfo.IO_address = dev->base_addr;
819 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
820 lp->driverInfo.IRQ_number = dev->irq;
821 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
822 //;? what happened to frame_type
823
824 /* Fill in the driver identity structure */
825 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
826 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
827 lp->driverIdentity.comp_id = DRV_IDENTITY;
828 lp->driverIdentity.variant = DRV_VARIANT;
829 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
830 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
831
832
833 /* Start the card here - This needs to be done in order to get the
834 MAC address for the network layer */
835 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
836 hcf_status = wl_go( lp );
837
838 if ( hcf_status != HCF_SUCCESS ) {
839 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
840 wl_unlock( lp, &flags );
841 goto hcf_failed;
842 }
843
844 /* Certain RIDs must be set before enabling the ports */
845 wl_put_ltv_init( lp );
846
847#if 0 //;?why was this already commented out in wl_lkm_720
848 /* Enable the ports */
849 if ( wl_adapter_is_open( lp->dev )) {
850 /* Enable the ports */
851 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
852 hcf_status = wl_enable( lp );
853
854 if ( hcf_status != HCF_SUCCESS ) {
855 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
856 }
857
858#if (HCF_TYPE) & HCF_TYPE_AP
859 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
860 //wl_enable_wds_ports( lp );
861#endif /* (HCF_TYPE) & HCF_TYPE_AP */
862
863 }
864#endif
865
866 /* Fill out the MAC address information in the net_device struct */
867 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
868 dev->addr_len = ETH_ALEN;
869
870 lp->is_registered = TRUE;
871
872#ifdef USE_PROFILE
873 /* Parse the config file for the sake of creating WDS ports if WDS is
874 configured there but not in the module options */
875 parse_config( dev );
876#endif /* USE_PROFILE */
877
878 /* If we're going into AP Mode, register the "virtual" ethernet devices
879 needed for WDS */
880 WL_WDS_NETDEV_REGISTER( lp );
881
882 /* Reset the DownloadFirmware variable in the private struct. If the
883 config file is not used, this will not matter; if it is used, it
884 will be reparsed in wl_open(). This is done because logic in wl_open
885 used to check if a firmware download is needed is broken by parsing
886 the file here; however, this parsing is needed to register WDS ports
887 in AP mode, if they are configured */
888 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
889
890#ifdef USE_RTS
891 if ( lp->useRTS == 1 ) {
892 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
893 wl_act_int_off( lp );
894 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
895
896 wl_disable( lp );
897
898 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
899 }
900#endif /* USE_RTS */
901
902 wl_unlock( lp, &flags );
903
904 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
905 dev->name, dev->base_addr, dev->irq );
906
907 for( i = 0; i < ETH_ALEN; i++ ) {
908 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
909 }
910
911#if 0 //SCULL_USE_PROC /* don't waste space if unused */
912 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
913 proc_mkdir("driver/wlags49", 0);
914 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
915#endif /* SCULL_USE_PROC */
916
917 DBG_LEAVE( DbgInfo );
918 return result;
919
920hcf_failed:
921 wl_hcf_error( dev, hcf_status );
922
923failed:
924
925 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
926
927 if ( lp->is_registered == TRUE ) {
928 lp->is_registered = FALSE;
929 }
930
931 WL_WDS_NETDEV_DEREGISTER( lp );
932
933 result = -EFAULT;
934
935
936 DBG_LEAVE( DbgInfo );
937 return result;
938} // wl_insert
939/*============================================================================*/
940
941
942/*******************************************************************************
943 * wl_reset()
944 *******************************************************************************
945 *
946 * DESCRIPTION:
947 *
948 * Reset the adapter.
949 *
950 * PARAMETERS:
951 *
952 * dev - a pointer to the net_device struct of the wireless device
953 *
954 * RETURNS:
955 *
956 * an HCF status code
957 *
958 ******************************************************************************/
959int wl_reset(struct net_device *dev)
960{
961 struct wl_private *lp = wl_priv(dev);
962 int hcf_status = HCF_SUCCESS;
963 /*------------------------------------------------------------------------*/
964 DBG_FUNC( "wl_reset" );
965 DBG_ENTER( DbgInfo );
966 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
967 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
968
969 /*
970 * The caller should already have a lock and
971 * disable the interrupts, we do not lock here,
972 * nor do we enable/disable interrupts!
973 */
974
975 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
976 if ( dev->base_addr ) {
977 /* Shutdown the adapter. */
978 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
979
980 /* Reset the driver information. */
981 lp->txBytes = 0;
982
983 /* Connect to the adapter. */
984 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
985 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
986 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
987 goto out;
988 }
989
990 /* Check if firmware is present, if not change state */
991 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
992 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
993 }
994
995 /* Initialize the portState variable */
996 lp->portState = WVLAN_PORT_STATE_DISABLED;
997
998 /* Restart the adapter. */
999 hcf_status = wl_go( lp );
1000 if ( hcf_status != HCF_SUCCESS ) {
1001 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1002 goto out;
1003 }
1004
1005 /* Certain RIDs must be set before enabling the ports */
1006 wl_put_ltv_init( lp );
1007 } else {
1008 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1009 }
1010
1011out:
1012 DBG_LEAVE( DbgInfo );
1013 return hcf_status;
1014} // wl_reset
1015/*============================================================================*/
1016
1017
1018/*******************************************************************************
1019 * wl_go()
1020 *******************************************************************************
1021 *
1022 * DESCRIPTION:
1023 *
1024 * Reset the adapter.
1025 *
1026 * PARAMETERS:
1027 *
1028 * dev - a pointer to the net_device struct of the wireless device
1029 *
1030 * RETURNS:
1031 *
1032 * an HCF status code
1033 *
1034 ******************************************************************************/
1035int wl_go( struct wl_private *lp )
1036{
1037 int hcf_status = HCF_SUCCESS;
1038 char *cp = NULL; //fw_image
1039 int retries = 0;
1040 /*------------------------------------------------------------------------*/
1041 DBG_FUNC( "wl_go" );
1042 DBG_ENTER( DbgInfo );
1043
1044 hcf_status = wl_disable( lp );
1045 if ( hcf_status != HCF_SUCCESS ) {
1046 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1047
1048 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1049 retries++;
1050 hcf_status = wl_disable( lp );
1051 }
1052 if ( hcf_status == HCF_SUCCESS ) {
1053 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1054 } else {
1055 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1056 }
1057 }
1058
1059#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1060 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1061 //wl_disable_wds_ports( lp );
1062#endif /* (HCF_TYPE) & HCF_TYPE_AP */
1063
1064//;?what was the purpose of this
1065// /* load the appropriate firmware image, depending on driver mode */
1066// lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1067// lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1068// hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1069
1070#if BIN_DL
1071 if ( strlen( lp->fw_image_filename ) ) {
1072mm_segment_t fs;
1073int file_desc;
1074int rc;
1075
1076 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1077 /* Obtain a user-space process context, storing the original context */
1078 fs = get_fs( );
1079 set_fs( get_ds( ));
1080 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1081 if ( file_desc == -1 ) {
1082 DBG_ERROR( DbgInfo, "No image file found\n" );
1083 } else {
1084 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1085#define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1086 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1087 if ( cp == NULL ) {
1088 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1089 } else {
1090 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1091 if ( rc == DHF_ALLOC_SIZE ) {
1092 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1093 } else if ( rc > 0 ) {
1094 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1095 rc = read( file_desc, &cp[rc], 1 );
1096 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1097 DBG_TRACE( DbgInfo, "no more to read\n" );
1098 }
1099 }
1100 if ( rc != 0 ) {
1101 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1102 ", give up, too complicated, rc = %0X\n", rc );
1103 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1104 } else {
1105 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1106 hcf_status = dhf_download_binary( (memimage *)cp );
1107 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1108 //;?improve error flow/handling
1109 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1110 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1111 }
1112 vfree( cp );
1113 }
1114 close( file_desc );
1115 }
1116 set_fs( fs ); /* Return to the original context */
1117 }
1118#endif // BIN_DL
1119
1120 /* If firmware is present but the type is unknown then download anyway */
1121 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1122 &&
1123 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1124 &&
1125 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1126 /* Unknown type, download needed. */
1127 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1128 }
1129
1130 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1131 {
1132 if ( cp == NULL ) {
1133 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1134// hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1135 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1136 }
1137 if ( hcf_status != HCF_SUCCESS ) {
1138 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1139 DBG_LEAVE( DbgInfo );
1140 return hcf_status;
1141 }
1142 }
1143 /* Report the FW versions */
1144 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1145 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1146 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1147 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1148 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1149 } else {
1150 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1151 }
1152
1153 /*
1154 * Downloaded, no need to repeat this next time, assume the
1155 * contents stays in the card until it is powered off. Note we
1156 * do not switch firmware on the fly, the firmware is fixed in
1157 * the driver for now.
1158 */
1159 lp->firmware_present = WL_FRIMWARE_PRESENT;
1160
1161 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1162 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1163 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1164 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1165 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1166
1167 /* now we wil get the MAC address of the card */
1168 lp->ltvRecord.len = 4;
1169 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1170 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1171 } else
1172 {
1173 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1174 }
1175 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1176 if ( hcf_status != HCF_SUCCESS ) {
1177 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1178 DBG_LEAVE( DbgInfo );
1179 return hcf_status;
1180 }
1181 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1182 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1183
1184 /* Write out configuration to the device, enable, and reconnect. However,
1185 only reconn…
Large files files are truncated, but you can click here to view the full file