adding the patch file too
[linux-2.6.git] / linux-2.6-300-olpc.patch
1 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/11d.c linux-2.6.22-300/drivers/net/wireless/libertas/11d.c
2 --- linux-2.6.22-250/drivers/net/wireless/libertas/11d.c        2008-07-17 00:17:57.000000000 -0400
3 +++ linux-2.6.22-300/drivers/net/wireless/libertas/11d.c        2008-06-05 18:10:06.000000000 -0400
4 @@ -43,16 +43,14 @@ static struct chan_freq_power channel_fr
5         {14, 2484, TX_PWR_DEFAULT}
6  };
7  
8 -static u8 wlan_region_2_code(u8 * region)
9 +static u8 lbs_region_2_code(u8 *region)
10  {
11         u8 i;
12 -       u8 size = sizeof(region_code_mapping)/
13 -                 sizeof(struct region_code_mapping);
14  
15         for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++)
16                 region[i] = toupper(region[i]);
17  
18 -       for (i = 0; i < size; i++) {
19 +       for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
20                 if (!memcmp(region, region_code_mapping[i].region,
21                             COUNTRY_CODE_LEN))
22                         return (region_code_mapping[i].code);
23 @@ -62,12 +60,11 @@ static u8 wlan_region_2_code(u8 * region
24         return (region_code_mapping[0].code);
25  }
26  
27 -static u8 *wlan_code_2_region(u8 code)
28 +static u8 *lbs_code_2_region(u8 code)
29  {
30         u8 i;
31 -       u8 size = sizeof(region_code_mapping)
32 -                 / sizeof(struct region_code_mapping);
33 -       for (i = 0; i < size; i++) {
34 +
35 +       for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
36                 if (region_code_mapping[i].code == code)
37                         return (region_code_mapping[i].region);
38         }
39 @@ -82,7 +79,7 @@ static u8 *wlan_code_2_region(u8 code)
40   *  @param nrchan   number of channels
41   *  @return          the nrchan-th chan number
42  */
43 -static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
44 +static u8 lbs_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 *chan)
45  /*find the nrchan-th chan after the firstchan*/
46  {
47         u8 i;
48 @@ -90,8 +87,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 
49         u8 cfp_no;
50  
51         cfp = channel_freq_power_UN_BG;
52 -       cfp_no = sizeof(channel_freq_power_UN_BG) /
53 -           sizeof(struct chan_freq_power);
54 +       cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG);
55  
56         for (i = 0; i < cfp_no; i++) {
57                 if ((cfp + i)->channel == firstchan) {
58 @@ -117,40 +113,36 @@ static u8 wlan_get_chan_11d(u8 band, u8 
59   *  @param parsed_region_chan   pointer to parsed_region_chan_11d
60   *  @return                    TRUE; FALSE
61  */
62 -static u8 wlan_channel_known_11d(u8 chan,
63 +static u8 lbs_channel_known_11d(u8 chan,
64                           struct parsed_region_chan_11d * parsed_region_chan)
65  {
66         struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr;
67         u8 nr_chan = parsed_region_chan->nr_chan;
68         u8 i = 0;
69  
70 -       lbs_dbg_hex("11D:parsed_region_chan:", (char *)chanpwr,
71 +       lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)chanpwr,
72                 sizeof(struct chan_power_11d) * nr_chan);
73  
74         for (i = 0; i < nr_chan; i++) {
75                 if (chan == chanpwr[i].chan) {
76 -                       lbs_deb_11d("11D: Found Chan:%d\n", chan);
77 +                       lbs_deb_11d("found chan %d\n", chan);
78                         return 1;
79                 }
80         }
81  
82 -       lbs_deb_11d("11D: Not Find Chan:%d\n", chan);
83 +       lbs_deb_11d("chan %d not found\n", chan);
84         return 0;
85  }
86  
87 -u32 libertas_chan_2_freq(u8 chan, u8 band)
88 +u32 lbs_chan_2_freq(u8 chan, u8 band)
89  {
90         struct chan_freq_power *cf;
91 -       u16 cnt;
92         u16 i;
93         u32 freq = 0;
94  
95         cf = channel_freq_power_UN_BG;
96 -       cnt =
97 -           sizeof(channel_freq_power_UN_BG) /
98 -           sizeof(struct chan_freq_power);
99  
100 -       for (i = 0; i < cnt; i++) {
101 +       for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) {
102                 if (chan == cf[i].channel)
103                         freq = cf[i].freq;
104         }
105 @@ -160,7 +152,7 @@ u32 libertas_chan_2_freq(u8 chan, u8 ban
106  
107  static int generate_domain_info_11d(struct parsed_region_chan_11d
108                                   *parsed_region_chan,
109 -                                 struct wlan_802_11d_domain_reg * domaininfo)
110 +                                 struct lbs_802_11d_domain_reg *domaininfo)
111  {
112         u8 nr_subband = 0;
113  
114 @@ -174,8 +166,8 @@ static int generate_domain_info_11d(stru
115         memcpy(domaininfo->countrycode, parsed_region_chan->countrycode,
116                COUNTRY_CODE_LEN);
117  
118 -       lbs_deb_11d("11D:nrchan=%d\n", nr_chan);
119 -       lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan,
120 +       lbs_deb_11d("nrchan %d\n", nr_chan);
121 +       lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)parsed_region_chan,
122                 sizeof(struct parsed_region_chan_11d));
123  
124         for (i = 0; i < nr_chan; i++) {
125 @@ -213,7 +205,7 @@ static int generate_domain_info_11d(stru
126         domaininfo->nr_subband = nr_subband;
127  
128         lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
129 -       lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo,
130 +       lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
131                 COUNTRY_CODE_LEN + 1 +
132                 sizeof(struct ieeetypes_subbandset) * nr_subband);
133         return 0;
134 @@ -225,7 +217,7 @@ static int generate_domain_info_11d(stru
135   *  @param *parsed_region_chan  pointer to parsed_region_chan_11d
136   *  @return                    N/A
137  */
138 -static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_chan,
139 +static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_chan,
140                                           struct parsed_region_chan_11d *
141                                           parsed_region_chan)
142  {
143 @@ -233,34 +225,34 @@ static void wlan_generate_parsed_region_
144         struct chan_freq_power *cfp;
145  
146         if (region_chan == NULL) {
147 -               lbs_deb_11d("11D: region_chan is NULL\n");
148 +               lbs_deb_11d("region_chan is NULL\n");
149                 return;
150         }
151  
152         cfp = region_chan->CFP;
153         if (cfp == NULL) {
154 -               lbs_deb_11d("11D: cfp equal NULL \n");
155 +               lbs_deb_11d("cfp is NULL \n");
156                 return;
157         }
158  
159         parsed_region_chan->band = region_chan->band;
160         parsed_region_chan->region = region_chan->region;
161         memcpy(parsed_region_chan->countrycode,
162 -              wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
163 +              lbs_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
164  
165 -       lbs_deb_11d("11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
166 +       lbs_deb_11d("region 0x%x, band %d\n", parsed_region_chan->region,
167                parsed_region_chan->band);
168  
169         for (i = 0; i < region_chan->nrcfp; i++, cfp++) {
170                 parsed_region_chan->chanpwr[i].chan = cfp->channel;
171                 parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower;
172 -               lbs_deb_11d("11D: Chan[%d] Pwr[%d]\n",
173 +               lbs_deb_11d("chan %d, pwr %d\n",
174                        parsed_region_chan->chanpwr[i].chan,
175                        parsed_region_chan->chanpwr[i].pwr);
176         }
177         parsed_region_chan->nr_chan = region_chan->nrcfp;
178  
179 -       lbs_deb_11d("11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
180 +       lbs_deb_11d("nrchan %d\n", parsed_region_chan->nr_chan);
181  
182         return;
183  }
184 @@ -272,7 +264,7 @@ static void wlan_generate_parsed_region_
185   *  @param chan                 chan
186   *  @return                    TRUE;FALSE
187  */
188 -static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
189 +static u8 lbs_region_chan_supported_11d(u8 region, u8 band, u8 chan)
190  {
191         struct chan_freq_power *cfp;
192         int cfp_no;
193 @@ -281,7 +273,7 @@ static u8 wlan_region_chan_supported_11d
194  
195         lbs_deb_enter(LBS_DEB_11D);
196  
197 -       cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
198 +       cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
199         if (cfp == NULL)
200                 return 0;
201  
202 @@ -336,7 +328,7 @@ static int parse_domain_info_11d(struct 
203            6. Others
204          */
205  
206 -       lbs_dbg_hex("CountryInfo:", (u8 *) countryinfo, 30);
207 +       lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
208  
209         if ((*(countryinfo->countrycode)) == 0
210             || (countryinfo->len <= COUNTRY_CODE_LEN)) {
211 @@ -346,10 +338,10 @@ static int parse_domain_info_11d(struct 
212  
213         /*Step1: check region_code */
214         parsed_region_chan->region = region =
215 -           wlan_region_2_code(countryinfo->countrycode);
216 +           lbs_region_2_code(countryinfo->countrycode);
217  
218         lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region);
219 -       lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode,
220 +       lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode,
221                 COUNTRY_CODE_LEN);
222  
223         parsed_region_chan->band = band;
224 @@ -364,7 +356,7 @@ static int parse_domain_info_11d(struct 
225  
226                 if (countryinfo->subband[j].firstchan <= lastchan) {
227                         /*Step2&3. Check First Chan Num increment and no overlap */
228 -                       lbs_deb_11d("11D: Chan[%d>%d] Overlap\n",
229 +                       lbs_deb_11d("chan %d>%d, overlap\n",
230                                countryinfo->subband[j].firstchan, lastchan);
231                         continue;
232                 }
233 @@ -375,7 +367,7 @@ static int parse_domain_info_11d(struct 
234                 for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) {
235                         /*step4: channel is supported? */
236  
237 -                       if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) {
238 +                       if (!lbs_get_chan_11d(band, firstchan, i, &curchan)) {
239                                 /* Chan is not found in UN table */
240                                 lbs_deb_11d("chan is not supported: %d \n", i);
241                                 break;
242 @@ -383,7 +375,7 @@ static int parse_domain_info_11d(struct 
243  
244                         lastchan = curchan;
245  
246 -                       if (wlan_region_chan_supported_11d
247 +                       if (lbs_region_chan_supported_11d
248                             (region, band, curchan)) {
249                                 /*step5: Check if curchan is supported by mrvl in region */
250                                 parsed_region_chan->chanpwr[idx].chan = curchan;
251 @@ -393,7 +385,7 @@ static int parse_domain_info_11d(struct 
252                         } else {
253                                 /*not supported and ignore the chan */
254                                 lbs_deb_11d(
255 -                                      "11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n",
256 +                                      "i %d, chan %d unsupported in region %x, band %d\n",
257                                        i, curchan, region, band);
258                         }
259                 }
260 @@ -405,7 +397,7 @@ static int parse_domain_info_11d(struct 
261         parsed_region_chan->nr_chan = idx;
262  
263         lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan);
264 -       lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan,
265 +       lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (u8 *) parsed_region_chan,
266                 2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx);
267  
268  done:
269 @@ -419,18 +411,18 @@ done:
270   *  @param parsed_region_chan   pointer to parsed_region_chan_11d
271   *  @return                    PASSIVE if chan is unknown; ACTIVE if chan is known
272  */
273 -u8 libertas_get_scan_type_11d(u8 chan,
274 +u8 lbs_get_scan_type_11d(u8 chan,
275                           struct parsed_region_chan_11d * parsed_region_chan)
276  {
277 -       u8 scan_type = cmd_scan_type_passive;
278 +       u8 scan_type = CMD_SCAN_TYPE_PASSIVE;
279  
280         lbs_deb_enter(LBS_DEB_11D);
281  
282 -       if (wlan_channel_known_11d(chan, parsed_region_chan)) {
283 -               lbs_deb_11d("11D: Found and do Active Scan\n");
284 -               scan_type = cmd_scan_type_active;
285 +       if (lbs_channel_known_11d(chan, parsed_region_chan)) {
286 +               lbs_deb_11d("found, do active scan\n");
287 +               scan_type = CMD_SCAN_TYPE_ACTIVE;
288         } else {
289 -               lbs_deb_11d("11D: Not Find and do Passive Scan\n");
290 +               lbs_deb_11d("not found, do passive scan\n");
291         }
292  
293         lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type);
294 @@ -438,80 +430,60 @@ u8 libertas_get_scan_type_11d(u8 chan,
295  
296  }
297  
298 -void libertas_init_11d(wlan_private * priv)
299 +void lbs_init_11d(struct lbs_private *priv)
300  {
301 -       priv->adapter->enable11d = 0;
302 -       memset(&(priv->adapter->parsed_region_chan), 0,
303 +       priv->enable11d = 0;
304 +       memset(&(priv->parsed_region_chan), 0,
305                sizeof(struct parsed_region_chan_11d));
306         return;
307  }
308  
309 -static int wlan_enable_11d(wlan_private * priv, u8 flag)
310 -{
311 -       int ret;
312 -
313 -       priv->adapter->enable11d = flag;
314 -
315 -       /* send cmd to FW to enable/disable 11D function in FW */
316 -       ret = libertas_prepare_and_send_command(priv,
317 -                                   cmd_802_11_snmp_mib,
318 -                                   cmd_act_set,
319 -                                   cmd_option_waitforrsp,
320 -                                   OID_802_11D_ENABLE,
321 -                                   &priv->adapter->enable11d);
322 -       if (ret)
323 -               lbs_deb_11d("11D: Fail to enable 11D \n");
324 -
325 -       return 0;
326 -}
327 -
328  /**
329   *  @brief This function sets DOMAIN INFO to FW
330 - *  @param priv       pointer to wlan_private
331 + *  @param priv       pointer to struct lbs_private
332   *  @return          0; -1
333  */
334 -static int set_domain_info_11d(wlan_private * priv)
335 +static int set_domain_info_11d(struct lbs_private *priv)
336  {
337         int ret;
338  
339 -       if (!priv->adapter->enable11d) {
340 -               lbs_deb_11d("11D: dnld domain Info with 11d disabled\n");
341 +       if (!priv->enable11d) {
342 +               lbs_deb_11d("dnld domain Info with 11d disabled\n");
343                 return 0;
344         }
345  
346 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11d_domain_info,
347 -                                   cmd_act_set,
348 -                                   cmd_option_waitforrsp, 0, NULL);
349 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
350 +                                   CMD_ACT_SET,
351 +                                   CMD_OPTION_WAITFORRSP, 0, NULL);
352         if (ret)
353 -               lbs_deb_11d("11D: Fail to dnld domain Info\n");
354 +               lbs_deb_11d("fail to dnld domain info\n");
355  
356         return ret;
357  }
358  
359  /**
360   *  @brief This function setups scan channels
361 - *  @param priv       pointer to wlan_private
362 + *  @param priv       pointer to struct lbs_private
363   *  @param band       band
364   *  @return          0
365  */
366 -int libertas_set_universaltable(wlan_private * priv, u8 band)
367 +int lbs_set_universaltable(struct lbs_private *priv, u8 band)
368  {
369 -       wlan_adapter *adapter = priv->adapter;
370         u16 size = sizeof(struct chan_freq_power);
371         u16 i = 0;
372  
373 -       memset(adapter->universal_channel, 0,
374 -              sizeof(adapter->universal_channel));
375 +       memset(priv->universal_channel, 0,
376 +              sizeof(priv->universal_channel));
377  
378 -       adapter->universal_channel[i].nrcfp =
379 +       priv->universal_channel[i].nrcfp =
380             sizeof(channel_freq_power_UN_BG) / size;
381 -       lbs_deb_11d("11D: BG-band nrcfp=%d\n",
382 -              adapter->universal_channel[i].nrcfp);
383 +       lbs_deb_11d("BG-band nrcfp %d\n",
384 +              priv->universal_channel[i].nrcfp);
385  
386 -       adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
387 -       adapter->universal_channel[i].valid = 1;
388 -       adapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
389 -       adapter->universal_channel[i].band = band;
390 +       priv->universal_channel[i].CFP = channel_freq_power_UN_BG;
391 +       priv->universal_channel[i].valid = 1;
392 +       priv->universal_channel[i].region = UNIVERSAL_REGION_CODE;
393 +       priv->universal_channel[i].band = band;
394         i++;
395  
396         return 0;
397 @@ -519,21 +491,20 @@ int libertas_set_universaltable(wlan_pri
398  
399  /**
400   *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
401 - *  @param priv       pointer to wlan_private
402 + *  @param priv       pointer to struct lbs_private
403   *  @param cmd        pointer to cmd buffer
404   *  @param cmdno      cmd ID
405   *  @param cmdOption  cmd action
406   *  @return          0
407  */
408 -int libertas_cmd_802_11d_domain_info(wlan_private * priv,
409 +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
410                                  struct cmd_ds_command *cmd, u16 cmdno,
411                                  u16 cmdoption)
412  {
413         struct cmd_ds_802_11d_domain_info *pdomaininfo =
414             &cmd->params.domaininfo;
415         struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
416 -       wlan_adapter *adapter = priv->adapter;
417 -       u8 nr_subband = adapter->domainreg.nr_subband;
418 +       u8 nr_subband = priv->domainreg.nr_subband;
419  
420         lbs_deb_enter(LBS_DEB_11D);
421  
422 @@ -541,16 +512,16 @@ int libertas_cmd_802_11d_domain_info(wla
423  
424         cmd->command = cpu_to_le16(cmdno);
425         pdomaininfo->action = cpu_to_le16(cmdoption);
426 -       if (cmdoption == cmd_act_get) {
427 +       if (cmdoption == CMD_ACT_GET) {
428                 cmd->size =
429                     cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
430 -               lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd,
431 -                       (int)(cmd->size));
432 +               lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
433 +                       le16_to_cpu(cmd->size));
434                 goto done;
435         }
436  
437         domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
438 -       memcpy(domain->countrycode, adapter->domainreg.countrycode,
439 +       memcpy(domain->countrycode, priv->domainreg.countrycode,
440                sizeof(domain->countrycode));
441  
442         domain->header.len =
443 @@ -558,7 +529,7 @@ int libertas_cmd_802_11d_domain_info(wla
444                              sizeof(domain->countrycode));
445  
446         if (nr_subband) {
447 -               memcpy(domain->subband, adapter->domainreg.subband,
448 +               memcpy(domain->subband, priv->domainreg.subband,
449                        nr_subband * sizeof(struct ieeetypes_subbandset));
450  
451                 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
452 @@ -570,7 +541,7 @@ int libertas_cmd_802_11d_domain_info(wla
453                     cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
454         }
455  
456 -       lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, le16_to_cpu(cmd->size));
457 +       lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, le16_to_cpu(cmd->size));
458  
459  done:
460         lbs_deb_enter(LBS_DEB_11D);
461 @@ -578,37 +549,12 @@ done:
462  }
463  
464  /**
465 - *  @brief This function implements private cmd: enable/disable 11D
466 - *  @param priv    pointer to wlan_private
467 - *  @param wrq     pointer to user data
468 - *  @return       0 or -1
469 - */
470 -int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
471 -{
472 -       int data = 0;
473 -       int *val;
474 -
475 -       lbs_deb_enter(LBS_DEB_11D);
476 -       data = SUBCMD_DATA(wrq);
477 -
478 -       lbs_deb_11d("enable 11D: %s\n",
479 -              (data == 1) ? "enable" : "Disable");
480 -
481 -       wlan_enable_11d(priv, data);
482 -       val = (int *)wrq->u.name;
483 -       *val = priv->adapter->enable11d;
484 -
485 -       lbs_deb_enter(LBS_DEB_11D);
486 -       return 0;
487 -}
488 -
489 -/**
490   *  @brief This function parses countryinfo from AP and download country info to FW
491 - *  @param priv    pointer to wlan_private
492 + *  @param priv    pointer to struct lbs_private
493   *  @param resp    pointer to command response buffer
494   *  @return       0; -1
495   */
496 -int libertas_ret_802_11d_domain_info(wlan_private * priv,
497 +int lbs_ret_802_11d_domain_info(struct lbs_private *priv,
498                                  struct cmd_ds_command *resp)
499  {
500         struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
501 @@ -619,13 +565,13 @@ int libertas_ret_802_11d_domain_info(wla
502  
503         lbs_deb_enter(LBS_DEB_11D);
504  
505 -       lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp,
506 +       lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
507                 (int)le16_to_cpu(resp->size));
508  
509         nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
510                       sizeof(struct ieeetypes_subbandset);
511  
512 -       lbs_deb_11d("11D Domain Info Resp: nr_subband=%d\n", nr_subband);
513 +       lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
514  
515         if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) {
516                 lbs_deb_11d("Invalid Numrer of Subband returned!!\n");
517 @@ -633,10 +579,10 @@ int libertas_ret_802_11d_domain_info(wla
518         }
519  
520         switch (action) {
521 -       case cmd_act_set:       /*Proc Set action */
522 +       case CMD_ACT_SET:       /*Proc Set action */
523                 break;
524  
525 -       case cmd_act_get:
526 +       case CMD_ACT_GET:
527                 break;
528         default:
529                 lbs_deb_11d("Invalid action:%d\n", domaininfo->action);
530 @@ -650,36 +596,35 @@ int libertas_ret_802_11d_domain_info(wla
531  
532  /**
533   *  @brief This function parses countryinfo from AP and download country info to FW
534 - *  @param priv    pointer to wlan_private
535 + *  @param priv    pointer to struct lbs_private
536   *  @return       0; -1
537   */
538 -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
539 +int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
540                                          struct bss_descriptor * bss)
541  {
542         int ret;
543 -       wlan_adapter *adapter = priv->adapter;
544  
545         lbs_deb_enter(LBS_DEB_11D);
546 -       if (priv->adapter->enable11d) {
547 -               memset(&adapter->parsed_region_chan, 0,
548 +       if (priv->enable11d) {
549 +               memset(&priv->parsed_region_chan, 0,
550                        sizeof(struct parsed_region_chan_11d));
551                 ret = parse_domain_info_11d(&bss->countryinfo, 0,
552 -                                              &adapter->parsed_region_chan);
553 +                                              &priv->parsed_region_chan);
554  
555                 if (ret == -1) {
556 -                       lbs_deb_11d("11D: Err Parse domain_info from AP..\n");
557 +                       lbs_deb_11d("error parsing domain_info from AP\n");
558                         goto done;
559                 }
560  
561 -               memset(&adapter->domainreg, 0,
562 -                      sizeof(struct wlan_802_11d_domain_reg));
563 -               generate_domain_info_11d(&adapter->parsed_region_chan,
564 -                                     &adapter->domainreg);
565 +               memset(&priv->domainreg, 0,
566 +                      sizeof(struct lbs_802_11d_domain_reg));
567 +               generate_domain_info_11d(&priv->parsed_region_chan,
568 +                                     &priv->domainreg);
569  
570                 ret = set_domain_info_11d(priv);
571  
572                 if (ret) {
573 -                       lbs_deb_11d("11D: Err set domainInfo to FW\n");
574 +                       lbs_deb_11d("error setting domain info\n");
575                         goto done;
576                 }
577         }
578 @@ -692,60 +637,57 @@ done:
579  
580  /**
581   *  @brief This function generates 11D info from user specified regioncode and download to FW
582 - *  @param priv    pointer to wlan_private
583 + *  @param priv    pointer to struct lbs_private
584   *  @return       0; -1
585   */
586 -int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
587 +int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv)
588  {
589         int ret;
590 -       wlan_adapter *adapter = priv->adapter;
591         struct region_channel *region_chan;
592         u8 j;
593  
594         lbs_deb_enter(LBS_DEB_11D);
595 -       lbs_deb_11d("11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
596 +       lbs_deb_11d("curbssparams.band %d\n", priv->curbssparams.band);
597  
598 -       if (priv->adapter->enable11d) {
599 +       if (priv->enable11d) {
600                 /* update parsed_region_chan_11; dnld domaininf to FW */
601  
602 -               for (j = 0; j < sizeof(adapter->region_channel) /
603 -                    sizeof(adapter->region_channel[0]); j++) {
604 -                       region_chan = &adapter->region_channel[j];
605 +               for (j = 0; j < ARRAY_SIZE(priv->region_channel); j++) {
606 +                       region_chan = &priv->region_channel[j];
607  
608 -                       lbs_deb_11d("11D:[%d] region_chan->band[%d]\n", j,
609 +                       lbs_deb_11d("%d region_chan->band %d\n", j,
610                                region_chan->band);
611  
612                         if (!region_chan || !region_chan->valid
613                             || !region_chan->CFP)
614                                 continue;
615 -                       if (region_chan->band != adapter->curbssparams.band)
616 +                       if (region_chan->band != priv->curbssparams.band)
617                                 continue;
618                         break;
619                 }
620  
621 -               if (j >= sizeof(adapter->region_channel) /
622 -                   sizeof(adapter->region_channel[0])) {
623 -                       lbs_deb_11d("11D:region_chan not found. band[%d]\n",
624 -                              adapter->curbssparams.band);
625 +               if (j >= ARRAY_SIZE(priv->region_channel)) {
626 +                       lbs_deb_11d("region_chan not found, band %d\n",
627 +                              priv->curbssparams.band);
628                         ret = -1;
629                         goto done;
630                 }
631  
632 -               memset(&adapter->parsed_region_chan, 0,
633 +               memset(&priv->parsed_region_chan, 0,
634                        sizeof(struct parsed_region_chan_11d));
635 -               wlan_generate_parsed_region_chan_11d(region_chan,
636 -                                                    &adapter->
637 +               lbs_generate_parsed_region_chan_11d(region_chan,
638 +                                                    &priv->
639                                                      parsed_region_chan);
640  
641 -               memset(&adapter->domainreg, 0,
642 -                      sizeof(struct wlan_802_11d_domain_reg));
643 -               generate_domain_info_11d(&adapter->parsed_region_chan,
644 -                                        &adapter->domainreg);
645 +               memset(&priv->domainreg, 0,
646 +                      sizeof(struct lbs_802_11d_domain_reg));
647 +               generate_domain_info_11d(&priv->parsed_region_chan,
648 +                                        &priv->domainreg);
649  
650                 ret = set_domain_info_11d(priv);
651  
652                 if (ret) {
653 -                       lbs_deb_11d("11D: Err set domainInfo to FW\n");
654 +                       lbs_deb_11d("error setting domain info\n");
655                         goto done;
656                 }
657  
658 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/11d.h linux-2.6.22-300/drivers/net/wireless/libertas/11d.h
659 --- linux-2.6.22-250/drivers/net/wireless/libertas/11d.h        2007-07-08 19:32:17.000000000 -0400
660 +++ linux-2.6.22-300/drivers/net/wireless/libertas/11d.h        2008-06-05 18:10:06.000000000 -0400
661 @@ -2,8 +2,8 @@
662    * This header file contains data structures and
663    * function declarations of 802.11d
664    */
665 -#ifndef _WLAN_11D_
666 -#define _WLAN_11D_
667 +#ifndef _LBS_11D_
668 +#define _LBS_11D_
669  
670  #include "types.h"
671  #include "defs.h"
672 @@ -52,7 +52,7 @@ struct cmd_ds_802_11d_domain_info {
673  } __attribute__ ((packed));
674  
675  /** domain regulatory information */
676 -struct wlan_802_11d_domain_reg {
677 +struct lbs_802_11d_domain_reg {
678         /** country Code*/
679         u8 countrycode[COUNTRY_CODE_LEN];
680         /** No. of subband*/
681 @@ -78,30 +78,28 @@ struct region_code_mapping {
682         u8 code;
683  };
684  
685 -u8 libertas_get_scan_type_11d(u8 chan,
686 -                         struct parsed_region_chan_11d *parsed_region_chan);
687 +struct lbs_private;
688  
689 -u32 libertas_chan_2_freq(u8 chan, u8 band);
690 +u8 lbs_get_scan_type_11d(u8 chan,
691 +                         struct parsed_region_chan_11d *parsed_region_chan);
692  
693 -enum state_11d libertas_get_state_11d(wlan_private * priv);
694 +u32 lbs_chan_2_freq(u8 chan, u8 band);
695  
696 -void libertas_init_11d(wlan_private * priv);
697 +void lbs_init_11d(struct lbs_private *priv);
698  
699 -int libertas_set_universaltable(wlan_private * priv, u8 band);
700 +int lbs_set_universaltable(struct lbs_private *priv, u8 band);
701  
702 -int libertas_cmd_802_11d_domain_info(wlan_private * priv,
703 +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
704                                  struct cmd_ds_command *cmd, u16 cmdno,
705                                  u16 cmdOption);
706  
707 -int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
708 -
709 -int libertas_ret_802_11d_domain_info(wlan_private * priv,
710 +int lbs_ret_802_11d_domain_info(struct lbs_private *priv,
711                                  struct cmd_ds_command *resp);
712  
713  struct bss_descriptor;
714 -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
715 +int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
716                                          struct bss_descriptor * bss);
717  
718 -int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
719 +int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv);
720  
721 -#endif                         /* _WLAN_11D_ */
722 +#endif
723 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/assoc.c linux-2.6.22-300/drivers/net/wireless/libertas/assoc.c
724 --- linux-2.6.22-250/drivers/net/wireless/libertas/assoc.c      2007-07-08 19:32:17.000000000 -0400
725 +++ linux-2.6.22-300/drivers/net/wireless/libertas/assoc.c      2008-06-05 18:10:06.000000000 -0400
726 @@ -9,38 +9,16 @@
727  #include "decl.h"
728  #include "hostcmd.h"
729  #include "host.h"
730 +#include "cmd.h"
731  
732  
733  static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
734  static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
735  
736 -static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
737 -{
738 -       lbs_deb_assoc(
739 -              "#### Association Request: %s\n"
740 -              "       flags:      0x%08lX\n"
741 -              "       SSID:       '%s'\n"
742 -              "       channel:    %d\n"
743 -              "       band:       %d\n"
744 -              "       mode:       %d\n"
745 -              "       BSSID:      " MAC_FMT "\n"
746 -              "       Encryption:%s%s%s\n"
747 -              "       auth:       %d\n",
748 -              extra, assoc_req->flags,
749 -              escape_essid(assoc_req->ssid, assoc_req->ssid_len),
750 -              assoc_req->channel, assoc_req->band, assoc_req->mode,
751 -              MAC_ARG(assoc_req->bssid),
752 -              assoc_req->secinfo.WPAenabled ? " WPA" : "",
753 -              assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
754 -              assoc_req->secinfo.wep_enabled ? " WEP" : "",
755 -              assoc_req->secinfo.auth_mode);
756 -}
757  
758 -
759 -static int assoc_helper_essid(wlan_private *priv,
760 +static int assoc_helper_essid(struct lbs_private *priv,
761                                struct assoc_request * assoc_req)
762  {
763 -       wlan_adapter *adapter = priv->adapter;
764         int ret = 0;
765         struct bss_descriptor * bss;
766         int channel = -1;
767 @@ -54,20 +32,17 @@ static int assoc_helper_essid(wlan_priva
768         if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
769                 channel = assoc_req->channel;
770  
771 -       lbs_deb_assoc("New SSID requested: '%s'\n",
772 +       lbs_deb_assoc("SSID '%s' requested\n",
773                       escape_essid(assoc_req->ssid, assoc_req->ssid_len));
774         if (assoc_req->mode == IW_MODE_INFRA) {
775 -               if (adapter->prescan) {
776 -                       libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
777 -                               assoc_req->ssid_len, 0);
778 -               }
779 +               lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
780 +                       assoc_req->ssid_len, 0);
781  
782 -               bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
783 +               bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
784                                 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
785                 if (bss != NULL) {
786 -                       lbs_deb_assoc("SSID found in scan list, associating\n");
787                         memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
788 -                       ret = wlan_associate(priv, assoc_req);
789 +                       ret = lbs_associate(priv, assoc_req);
790                 } else {
791                         lbs_deb_assoc("SSID not found; cannot associate\n");
792                 }
793 @@ -75,23 +50,23 @@ static int assoc_helper_essid(wlan_priva
794                 /* Scan for the network, do not save previous results.  Stale
795                  *   scan data will cause us to join a non-existant adhoc network
796                  */
797 -               libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
798 +               lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
799                         assoc_req->ssid_len, 1);
800  
801                 /* Search for the requested SSID in the scan table */
802 -               bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
803 +               bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
804                                 assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
805                 if (bss != NULL) {
806                         lbs_deb_assoc("SSID found, will join\n");
807                         memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
808 -                       libertas_join_adhoc_network(priv, assoc_req);
809 +                       lbs_join_adhoc_network(priv, assoc_req);
810                 } else {
811                         /* else send START command */
812                         lbs_deb_assoc("SSID not found, creating adhoc network\n");
813                         memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
814                                 IW_ESSID_MAX_SIZE);
815                         assoc_req->bss.ssid_len = assoc_req->ssid_len;
816 -                       libertas_start_adhoc_network(priv, assoc_req);
817 +                       lbs_start_adhoc_network(priv, assoc_req);
818                 }
819         }
820  
821 @@ -100,31 +75,31 @@ static int assoc_helper_essid(wlan_priva
822  }
823  
824  
825 -static int assoc_helper_bssid(wlan_private *priv,
826 +static int assoc_helper_bssid(struct lbs_private *priv,
827                                struct assoc_request * assoc_req)
828  {
829 -       wlan_adapter *adapter = priv->adapter;
830         int ret = 0;
831         struct bss_descriptor * bss;
832 +       DECLARE_MAC_BUF(mac);
833  
834 -       lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT,
835 -               MAC_ARG(assoc_req->bssid));
836 +       lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %s",
837 +               print_mac(mac, assoc_req->bssid));
838  
839         /* Search for index position in list for requested MAC */
840 -       bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid,
841 +       bss = lbs_find_bssid_in_list(priv, assoc_req->bssid,
842                             assoc_req->mode);
843         if (bss == NULL) {
844 -               lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, "
845 -                       "cannot associate.\n", MAC_ARG(assoc_req->bssid));
846 +               lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, "
847 +                       "cannot associate.\n", print_mac(mac, assoc_req->bssid));
848                 goto out;
849         }
850  
851         memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
852         if (assoc_req->mode == IW_MODE_INFRA) {
853 -               ret = wlan_associate(priv, assoc_req);
854 -               lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret);
855 +               ret = lbs_associate(priv, assoc_req);
856 +               lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret);
857         } else if (assoc_req->mode == IW_MODE_ADHOC) {
858 -               libertas_join_adhoc_network(priv, assoc_req);
859 +               lbs_join_adhoc_network(priv, assoc_req);
860         }
861  
862  out:
863 @@ -133,11 +108,13 @@ out:
864  }
865  
866  
867 -static int assoc_helper_associate(wlan_private *priv,
868 +static int assoc_helper_associate(struct lbs_private *priv,
869                                    struct assoc_request * assoc_req)
870  {
871         int ret = 0, done = 0;
872  
873 +       lbs_deb_enter(LBS_DEB_ASSOC);
874 +
875         /* If we're given and 'any' BSSID, try associating based on SSID */
876  
877         if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
878 @@ -145,44 +122,38 @@ static int assoc_helper_associate(wlan_p
879                     && compare_ether_addr(bssid_off, assoc_req->bssid)) {
880                         ret = assoc_helper_bssid(priv, assoc_req);
881                         done = 1;
882 -                       if (ret) {
883 -                               lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
884 -                       }
885                 }
886         }
887  
888         if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
889                 ret = assoc_helper_essid(priv, assoc_req);
890 -               if (ret) {
891 -                       lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
892 -               }
893         }
894  
895 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
896         return ret;
897  }
898  
899  
900 -static int assoc_helper_mode(wlan_private *priv,
901 +static int assoc_helper_mode(struct lbs_private *priv,
902                               struct assoc_request * assoc_req)
903  {
904 -       wlan_adapter *adapter = priv->adapter;
905         int ret = 0;
906  
907         lbs_deb_enter(LBS_DEB_ASSOC);
908  
909 -       if (assoc_req->mode == adapter->mode)
910 +       if (assoc_req->mode == priv->mode)
911                 goto done;
912  
913         if (assoc_req->mode == IW_MODE_INFRA) {
914 -               if (adapter->psstate != PS_STATE_FULL_POWER)
915 -                       libertas_ps_wakeup(priv, cmd_option_waitforrsp);
916 -               adapter->psmode = wlan802_11powermodecam;
917 +               if (priv->psstate != PS_STATE_FULL_POWER)
918 +                       lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
919 +               priv->psmode = LBS802_11POWERMODECAM;
920         }
921  
922 -       adapter->mode = assoc_req->mode;
923 -       ret = libertas_prepare_and_send_command(priv,
924 -                                   cmd_802_11_snmp_mib,
925 -                                   0, cmd_option_waitforrsp,
926 +       priv->mode = assoc_req->mode;
927 +       ret = lbs_prepare_and_send_command(priv,
928 +                                   CMD_802_11_SNMP_MIB,
929 +                                   0, CMD_OPTION_WAITFORRSP,
930                                     OID_802_11_INFRASTRUCTURE_MODE,
931                 /* Shoot me now */  (void *) (size_t) assoc_req->mode);
932  
933 @@ -192,57 +163,77 @@ done:
934  }
935  
936  
937 -static int update_channel(wlan_private * priv)
938 +int lbs_update_channel(struct lbs_private *priv)
939  {
940 -       /* the channel in f/w could be out of sync, get the current channel */
941 -       return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
942 -                                   cmd_opt_802_11_rf_channel_get,
943 -                                   cmd_option_waitforrsp, 0, NULL);
944 +       int ret;
945 +
946 +       /* the channel in f/w could be out of sync; get the current channel */
947 +       lbs_deb_enter(LBS_DEB_ASSOC);
948 +
949 +       ret = lbs_get_channel(priv);
950 +       if (ret > 0) {
951 +               priv->curbssparams.channel = ret;
952 +               ret = 0;
953 +       }
954 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
955 +       return ret;
956  }
957  
958 -void libertas_sync_channel(struct work_struct *work)
959 +void lbs_sync_channel(struct work_struct *work)
960  {
961 -       wlan_private *priv = container_of(work, wlan_private, sync_channel);
962 +       struct lbs_private *priv = container_of(work, struct lbs_private,
963 +               sync_channel);
964  
965 -       if (update_channel(priv) != 0)
966 +       lbs_deb_enter(LBS_DEB_ASSOC);
967 +       if (lbs_update_channel(priv))
968                 lbs_pr_info("Channel synchronization failed.");
969 +       lbs_deb_leave(LBS_DEB_ASSOC);
970  }
971  
972 -static int assoc_helper_channel(wlan_private *priv,
973 +static int assoc_helper_channel(struct lbs_private *priv,
974                                  struct assoc_request * assoc_req)
975  {
976 -       wlan_adapter *adapter = priv->adapter;
977         int ret = 0;
978  
979         lbs_deb_enter(LBS_DEB_ASSOC);
980  
981 -       ret = update_channel(priv);
982 -       if (ret < 0) {
983 -               lbs_deb_assoc("ASSOC: channel: error getting channel.");
984 +       ret = lbs_update_channel(priv);
985 +       if (ret) {
986 +               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
987 +               goto done;
988         }
989  
990 -       if (assoc_req->channel == adapter->curbssparams.channel)
991 +       if (assoc_req->channel == priv->curbssparams.channel)
992                 goto done;
993  
994 -       lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
995 -              adapter->curbssparams.channel, assoc_req->channel);
996 -
997 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
998 -                               cmd_opt_802_11_rf_channel_set,
999 -                               cmd_option_waitforrsp, 0, &assoc_req->channel);
1000 -       if (ret < 0) {
1001 -               lbs_deb_assoc("ASSOC: channel: error setting channel.");
1002 +       if (priv->mesh_dev) {
1003 +               /* Change mesh channel first; 21.p21 firmware won't let
1004 +                  you change channel otherwise (even though it'll return
1005 +                  an error to this */
1006 +               lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
1007 +                               assoc_req->channel);
1008         }
1009  
1010 -       ret = update_channel(priv);
1011 -       if (ret < 0) {
1012 -               lbs_deb_assoc("ASSOC: channel: error getting channel.");
1013 +       lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
1014 +                     priv->curbssparams.channel, assoc_req->channel);
1015 +
1016 +       ret = lbs_set_channel(priv, assoc_req->channel);
1017 +       if (ret < 0)
1018 +               lbs_deb_assoc("ASSOC: channel: error setting channel.\n");
1019 +
1020 +       /* FIXME: shouldn't need to grab the channel _again_ after setting
1021 +        * it since the firmware is supposed to return the new channel, but
1022 +        * whatever... */
1023 +       ret = lbs_update_channel(priv);
1024 +       if (ret) {
1025 +               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
1026 +               goto done;
1027         }
1028  
1029 -       if (assoc_req->channel != adapter->curbssparams.channel) {
1030 -               lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
1031 +       if (assoc_req->channel != priv->curbssparams.channel) {
1032 +               lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
1033                               assoc_req->channel);
1034 -               goto done;
1035 +               goto restore_mesh;
1036         }
1037  
1038         if (   assoc_req->secinfo.wep_enabled
1039 @@ -255,18 +246,22 @@ static int assoc_helper_channel(wlan_pri
1040         }
1041  
1042         /* Must restart/rejoin adhoc networks after channel change */
1043 -       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
1044 +       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
1045  
1046 -done:
1047 + restore_mesh:
1048 +       if (priv->mesh_dev)
1049 +               lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1050 +                               priv->curbssparams.channel);
1051 +
1052 + done:
1053         lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1054         return ret;
1055  }
1056  
1057  
1058 -static int assoc_helper_wep_keys(wlan_private *priv,
1059 +static int assoc_helper_wep_keys(struct lbs_private *priv,
1060                                   struct assoc_request * assoc_req)
1061  {
1062 -       wlan_adapter *adapter = priv->adapter;
1063         int i;
1064         int ret = 0;
1065  
1066 @@ -277,16 +272,16 @@ static int assoc_helper_wep_keys(wlan_pr
1067             || assoc_req->wep_keys[1].len
1068             || assoc_req->wep_keys[2].len
1069             || assoc_req->wep_keys[3].len) {
1070 -               ret = libertas_prepare_and_send_command(priv,
1071 -                                           cmd_802_11_set_wep,
1072 -                                           cmd_act_add,
1073 -                                           cmd_option_waitforrsp,
1074 +               ret = lbs_prepare_and_send_command(priv,
1075 +                                           CMD_802_11_SET_WEP,
1076 +                                           CMD_ACT_ADD,
1077 +                                           CMD_OPTION_WAITFORRSP,
1078                                             0, assoc_req);
1079         } else {
1080 -               ret = libertas_prepare_and_send_command(priv,
1081 -                                           cmd_802_11_set_wep,
1082 -                                           cmd_act_remove,
1083 -                                           cmd_option_waitforrsp,
1084 +               ret = lbs_prepare_and_send_command(priv,
1085 +                                           CMD_802_11_SET_WEP,
1086 +                                           CMD_ACT_REMOVE,
1087 +                                           CMD_OPTION_WAITFORRSP,
1088                                             0, NULL);
1089         }
1090  
1091 @@ -295,45 +290,41 @@ static int assoc_helper_wep_keys(wlan_pr
1092  
1093         /* enable/disable the MAC's WEP packet filter */
1094         if (assoc_req->secinfo.wep_enabled)
1095 -               adapter->currentpacketfilter |= cmd_act_mac_wep_enable;
1096 +               priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1097         else
1098 -               adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable;
1099 -       ret = libertas_set_mac_packet_filter(priv);
1100 -       if (ret)
1101 -               goto out;
1102 +               priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1103 +
1104 +       lbs_set_mac_control(priv);
1105  
1106 -       mutex_lock(&adapter->lock);
1107 +       mutex_lock(&priv->lock);
1108  
1109 -       /* Copy WEP keys into adapter wep key fields */
1110 +       /* Copy WEP keys into priv wep key fields */
1111         for (i = 0; i < 4; i++) {
1112 -               memcpy(&adapter->wep_keys[i], &assoc_req->wep_keys[i],
1113 -                       sizeof(struct WLAN_802_11_KEY));
1114 +               memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i],
1115 +                       sizeof(struct enc_key));
1116         }
1117 -       adapter->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
1118 +       priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
1119  
1120 -       mutex_unlock(&adapter->lock);
1121 +       mutex_unlock(&priv->lock);
1122  
1123  out:
1124         lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1125         return ret;
1126  }
1127  
1128 -static int assoc_helper_secinfo(wlan_private *priv,
1129 +static int assoc_helper_secinfo(struct lbs_private *priv,
1130                                  struct assoc_request * assoc_req)
1131  {
1132 -       wlan_adapter *adapter = priv->adapter;
1133         int ret = 0;
1134         u32 do_wpa;
1135         u32 rsn = 0;
1136  
1137         lbs_deb_enter(LBS_DEB_ASSOC);
1138  
1139 -       memcpy(&adapter->secinfo, &assoc_req->secinfo,
1140 -               sizeof(struct wlan_802_11_security));
1141 +       memcpy(&priv->secinfo, &assoc_req->secinfo,
1142 +               sizeof(struct lbs_802_11_security));
1143  
1144 -       ret = libertas_set_mac_packet_filter(priv);
1145 -       if (ret)
1146 -               goto out;
1147 +       lbs_set_mac_control(priv);
1148  
1149         /* If RSN is already enabled, don't try to enable it again, since
1150          * ENABLE_RSN resets internal state machines and will clobber the
1151 @@ -341,13 +332,13 @@ static int assoc_helper_secinfo(wlan_pri
1152          */
1153  
1154         /* Get RSN enabled/disabled */
1155 -       ret = libertas_prepare_and_send_command(priv,
1156 -                                   cmd_802_11_enable_rsn,
1157 -                                   cmd_act_set,
1158 -                                   cmd_option_waitforrsp,
1159 +       ret = lbs_prepare_and_send_command(priv,
1160 +                                   CMD_802_11_ENABLE_RSN,
1161 +                                   CMD_ACT_GET,
1162 +                                   CMD_OPTION_WAITFORRSP,
1163                                     0, &rsn);
1164         if (ret) {
1165 -               lbs_deb_assoc("Failed to get RSN status: %d", ret);
1166 +               lbs_deb_assoc("Failed to get RSN status: %d\n", ret);
1167                 goto out;
1168         }
1169  
1170 @@ -358,10 +349,10 @@ static int assoc_helper_secinfo(wlan_pri
1171  
1172         /* Set RSN enabled/disabled */
1173         rsn = do_wpa;
1174 -       ret = libertas_prepare_and_send_command(priv,
1175 -                                   cmd_802_11_enable_rsn,
1176 -                                   cmd_act_set,
1177 -                                   cmd_option_waitforrsp,
1178 +       ret = lbs_prepare_and_send_command(priv,
1179 +                                   CMD_802_11_ENABLE_RSN,
1180 +                                   CMD_ACT_SET,
1181 +                                   CMD_OPTION_WAITFORRSP,
1182                                     0, &rsn);
1183  
1184  out:
1185 @@ -370,38 +361,62 @@ out:
1186  }
1187  
1188  
1189 -static int assoc_helper_wpa_keys(wlan_private *priv,
1190 +static int assoc_helper_wpa_keys(struct lbs_private *priv,
1191                                   struct assoc_request * assoc_req)
1192  {
1193         int ret = 0;
1194 +       unsigned int flags = assoc_req->flags;
1195  
1196         lbs_deb_enter(LBS_DEB_ASSOC);
1197  
1198 -       ret = libertas_prepare_and_send_command(priv,
1199 -                                   cmd_802_11_key_material,
1200 -                                   cmd_act_set,
1201 -                                   cmd_option_waitforrsp,
1202 -                                   0, assoc_req);
1203 +       /* Work around older firmware bug where WPA unicast and multicast
1204 +        * keys must be set independently.  Seen in SDIO parts with firmware
1205 +        * version 5.0.11p0.
1206 +        */
1207 +
1208 +       if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
1209 +               clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
1210 +               ret = lbs_prepare_and_send_command(priv,
1211 +                                       CMD_802_11_KEY_MATERIAL,
1212 +                                       CMD_ACT_SET,
1213 +                                       CMD_OPTION_WAITFORRSP,
1214 +                                       0, assoc_req);
1215 +               assoc_req->flags = flags;
1216 +       }
1217 +
1218 +       if (ret)
1219 +               goto out;
1220 +
1221 +       if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
1222 +               clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
1223 +
1224 +               ret = lbs_prepare_and_send_command(priv,
1225 +                                       CMD_802_11_KEY_MATERIAL,
1226 +                                       CMD_ACT_SET,
1227 +                                       CMD_OPTION_WAITFORRSP,
1228 +                                       0, assoc_req);
1229 +               assoc_req->flags = flags;
1230 +       }
1231  
1232 +out:
1233         lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1234         return ret;
1235  }
1236  
1237  
1238 -static int assoc_helper_wpa_ie(wlan_private *priv,
1239 +static int assoc_helper_wpa_ie(struct lbs_private *priv,
1240                                 struct assoc_request * assoc_req)
1241  {
1242 -       wlan_adapter *adapter = priv->adapter;
1243         int ret = 0;
1244  
1245         lbs_deb_enter(LBS_DEB_ASSOC);
1246  
1247         if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1248 -               memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
1249 -               adapter->wpa_ie_len = assoc_req->wpa_ie_len;
1250 +               memcpy(&priv->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
1251 +               priv->wpa_ie_len = assoc_req->wpa_ie_len;
1252         } else {
1253 -               memset(&adapter->wpa_ie, 0, MAX_WPA_IE_LEN);
1254 -               adapter->wpa_ie_len = 0;
1255 +               memset(&priv->wpa_ie, 0, MAX_WPA_IE_LEN);
1256 +               priv->wpa_ie_len = 0;
1257         }
1258  
1259         lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1260 @@ -409,55 +424,68 @@ static int assoc_helper_wpa_ie(wlan_priv
1261  }
1262  
1263  
1264 -static int should_deauth_infrastructure(wlan_adapter *adapter,
1265 +static int should_deauth_infrastructure(struct lbs_private *priv,
1266                                          struct assoc_request * assoc_req)
1267  {
1268 -       if (adapter->connect_status != libertas_connected)
1269 +       int ret = 0;
1270 +
1271 +       lbs_deb_enter(LBS_DEB_ASSOC);
1272 +
1273 +       if (priv->connect_status != LBS_CONNECTED)
1274                 return 0;
1275  
1276         if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
1277 -               lbs_deb_assoc("Deauthenticating due to new SSID in "
1278 -                       " configuration request.\n");
1279 -               return 1;
1280 +               lbs_deb_assoc("Deauthenticating due to new SSID\n");
1281 +               ret = 1;
1282 +               goto out;
1283         }
1284  
1285         if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
1286 -               if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
1287 -                       lbs_deb_assoc("Deauthenticating due to updated security "
1288 -                               "info in configuration request.\n");
1289 -                       return 1;
1290 +               if (priv->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
1291 +                       lbs_deb_assoc("Deauthenticating due to new security\n");
1292 +                       ret = 1;
1293 +                       goto out;
1294                 }
1295         }
1296  
1297         if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1298 -               lbs_deb_assoc("Deauthenticating due to new BSSID in "
1299 -                       " configuration request.\n");
1300 -               return 1;
1301 +               lbs_deb_assoc("Deauthenticating due to new BSSID\n");
1302 +               ret = 1;
1303 +               goto out;
1304         }
1305  
1306         if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
1307 -               lbs_deb_assoc("Deauthenticating due to channel switch.\n");
1308 -               return 1;
1309 +               lbs_deb_assoc("Deauthenticating due to channel switch\n");
1310 +               ret = 1;
1311 +               goto out;
1312         }
1313  
1314         /* FIXME: deal with 'auto' mode somehow */
1315         if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
1316 -               if (assoc_req->mode != IW_MODE_INFRA)
1317 -                       return 1;
1318 +               if (assoc_req->mode != IW_MODE_INFRA) {
1319 +                       lbs_deb_assoc("Deauthenticating due to leaving "
1320 +                               "infra mode\n");
1321 +                       ret = 1;
1322 +                       goto out;
1323 +               }
1324         }
1325  
1326 -       return 0;
1327 +out:
1328 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1329 +       return ret;
1330  }
1331  
1332  
1333 -static int should_stop_adhoc(wlan_adapter *adapter,
1334 +static int should_stop_adhoc(struct lbs_private *priv,
1335                               struct assoc_request * assoc_req)
1336  {
1337 -       if (adapter->connect_status != libertas_connected)
1338 +       lbs_deb_enter(LBS_DEB_ASSOC);
1339 +
1340 +       if (priv->connect_status != LBS_CONNECTED)
1341                 return 0;
1342  
1343 -       if (libertas_ssid_cmp(adapter->curbssparams.ssid,
1344 -                             adapter->curbssparams.ssid_len,
1345 +       if (lbs_ssid_cmp(priv->curbssparams.ssid,
1346 +                             priv->curbssparams.ssid_len,
1347                               assoc_req->ssid, assoc_req->ssid_len) != 0)
1348                 return 1;
1349  
1350 @@ -468,34 +496,53 @@ static int should_stop_adhoc(wlan_adapte
1351         }
1352  
1353         if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
1354 -               if (assoc_req->channel != adapter->curbssparams.channel)
1355 +               if (assoc_req->channel != priv->curbssparams.channel)
1356                         return 1;
1357         }
1358  
1359 +       lbs_deb_leave(LBS_DEB_ASSOC);
1360         return 0;
1361  }
1362  
1363  
1364 -void libertas_association_worker(struct work_struct *work)
1365 +void lbs_association_worker(struct work_struct *work)
1366  {
1367 -       wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
1368 -       wlan_adapter *adapter = priv->adapter;
1369 +       struct lbs_private *priv = container_of(work, struct lbs_private,
1370 +               assoc_work.work);
1371         struct assoc_request * assoc_req = NULL;
1372         int ret = 0;
1373         int find_any_ssid = 0;
1374 +       DECLARE_MAC_BUF(mac);
1375  
1376         lbs_deb_enter(LBS_DEB_ASSOC);
1377  
1378 -       mutex_lock(&adapter->lock);
1379 -       assoc_req = adapter->pending_assoc_req;
1380 -       adapter->pending_assoc_req = NULL;
1381 -       adapter->in_progress_assoc_req = assoc_req;
1382 -       mutex_unlock(&adapter->lock);
1383 +       mutex_lock(&priv->lock);
1384 +       assoc_req = priv->pending_assoc_req;
1385 +       priv->pending_assoc_req = NULL;
1386 +       priv->in_progress_assoc_req = assoc_req;
1387 +       mutex_unlock(&priv->lock);
1388  
1389         if (!assoc_req)
1390                 goto done;
1391  
1392 -       print_assoc_req(__func__, assoc_req);
1393 +       lbs_deb_assoc(
1394 +               "Association Request:\n"
1395 +               "    flags:     0x%08lx\n"
1396 +               "    SSID:      '%s'\n"
1397 +               "    chann:     %d\n"
1398 +               "    band:      %d\n"
1399 +               "    mode:      %d\n"
1400 +               "    BSSID:     %s\n"
1401 +               "    secinfo:  %s%s%s\n"
1402 +               "    auth_mode: %d\n",
1403 +               assoc_req->flags,
1404 +               escape_essid(assoc_req->ssid, assoc_req->ssid_len),
1405 +               assoc_req->channel, assoc_req->band, assoc_req->mode,
1406 +               print_mac(mac, assoc_req->bssid),
1407 +               assoc_req->secinfo.WPAenabled ? " WPA" : "",
1408 +               assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
1409 +               assoc_req->secinfo.wep_enabled ? " WEP" : "",
1410 +               assoc_req->secinfo.auth_mode);
1411  
1412         /* If 'any' SSID was specified, find an SSID to associate with */
1413         if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
1414 @@ -512,7 +559,7 @@ void libertas_association_worker(struct 
1415         if (find_any_ssid) {
1416                 u8 new_mode;
1417  
1418 -               ret = libertas_find_best_network_ssid(priv, assoc_req->ssid,
1419 +               ret = lbs_find_best_network_ssid(priv, assoc_req->ssid,
1420                                 &assoc_req->ssid_len, assoc_req->mode, &new_mode);
1421                 if (ret) {
1422                         lbs_deb_assoc("Could not find best network\n");
1423 @@ -531,18 +578,18 @@ void libertas_association_worker(struct 
1424          * Check if the attributes being changing require deauthentication
1425          * from the currently associated infrastructure access point.
1426          */
1427 -       if (adapter->mode == IW_MODE_INFRA) {
1428 -               if (should_deauth_infrastructure(adapter, assoc_req)) {
1429 -                       ret = libertas_send_deauthentication(priv);
1430 +       if (priv->mode == IW_MODE_INFRA) {
1431 +               if (should_deauth_infrastructure(priv, assoc_req)) {
1432 +                       ret = lbs_send_deauthentication(priv);
1433                         if (ret) {
1434                                 lbs_deb_assoc("Deauthentication due to new "
1435                                         "configuration request failed: %d\n",
1436                                         ret);
1437                         }
1438                 }
1439 -       } else if (adapter->mode == IW_MODE_ADHOC) {
1440 -               if (should_stop_adhoc(adapter, assoc_req)) {
1441 -                       ret = libertas_stop_adhoc_network(priv);
1442 +       } else if (priv->mode == IW_MODE_ADHOC) {
1443 +               if (should_stop_adhoc(priv, assoc_req)) {
1444 +                       ret = lbs_stop_adhoc_network(priv);
1445                         if (ret) {
1446                                 lbs_deb_assoc("Teardown of AdHoc network due to "
1447                                         "new configuration request failed: %d\n",
1448 @@ -555,53 +602,40 @@ void libertas_association_worker(struct 
1449         /* Send the various configuration bits to the firmware */
1450         if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
1451                 ret = assoc_helper_mode(priv, assoc_req);
1452 -               if (ret) {
1453 -lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
1454 +               if (ret)
1455                         goto out;
1456 -               }
1457         }
1458  
1459         if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
1460                 ret = assoc_helper_channel(priv, assoc_req);
1461 -               if (ret) {
1462 -                       lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
1463 -                                     __LINE__, ret);
1464 +               if (ret)
1465                         goto out;
1466 -               }
1467         }
1468  
1469         if (   test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
1470             || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
1471                 ret = assoc_helper_wep_keys(priv, assoc_req);
1472 -               if (ret) {
1473 -lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
1474 +               if (ret)
1475                         goto out;
1476 -               }
1477         }
1478  
1479         if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
1480                 ret = assoc_helper_secinfo(priv, assoc_req);
1481 -               if (ret) {
1482 -lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
1483 +               if (ret)
1484                         goto out;
1485 -               }
1486         }
1487  
1488         if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
1489                 ret = assoc_helper_wpa_ie(priv, assoc_req);
1490 -               if (ret) {
1491 -lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
1492 +               if (ret)
1493                         goto out;
1494 -               }
1495         }
1496  
1497         if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)
1498             || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
1499                 ret = assoc_helper_wpa_keys(priv, assoc_req);
1500 -               if (ret) {
1501 -lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
1502 +               if (ret)
1503                         goto out;
1504 -               }
1505         }
1506  
1507         /* SSID/BSSID should be the _last_ config option set, because they
1508 @@ -613,30 +647,29 @@ lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret 
1509  
1510                 ret = assoc_helper_associate(priv, assoc_req);
1511                 if (ret) {
1512 -                       lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n",
1513 +                       lbs_deb_assoc("ASSOC: association unsuccessful: %d\n",
1514                                 ret);
1515                         success = 0;
1516                 }
1517  
1518 -               if (adapter->connect_status != libertas_connected) {
1519 -                       lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, "
1520 -                               "not connected.\n");
1521 +               if (priv->connect_status != LBS_CONNECTED) {
1522 +                       lbs_deb_assoc("ASSOC: association unsuccessful, "
1523 +                               "not connected\n");
1524                         success = 0;
1525                 }
1526  
1527                 if (success) {
1528 -                       lbs_deb_assoc("ASSOC: association attempt successful. "
1529 -                               "Associated to '%s' (" MAC_FMT ")\n",
1530 -                               escape_essid(adapter->curbssparams.ssid,
1531 -                                            adapter->curbssparams.ssid_len),
1532 -                               MAC_ARG(adapter->curbssparams.bssid));
1533 -                       libertas_prepare_and_send_command(priv,
1534 -                               cmd_802_11_rssi,
1535 -                               0, cmd_option_waitforrsp, 0, NULL);
1536 -
1537 -                       libertas_prepare_and_send_command(priv,
1538 -                               cmd_802_11_get_log,
1539 -                               0, cmd_option_waitforrsp, 0, NULL);
1540 +                       lbs_deb_assoc("ASSOC: associated to '%s', %s\n",
1541 +                               escape_essid(priv->curbssparams.ssid,
1542 +                                            priv->curbssparams.ssid_len),
1543 +                               print_mac(mac, priv->curbssparams.bssid));
1544 +                       lbs_prepare_and_send_command(priv,
1545 +                               CMD_802_11_RSSI,
1546 +                               0, CMD_OPTION_WAITFORRSP, 0, NULL);
1547 +
1548 +                       lbs_prepare_and_send_command(priv,
1549 +                               CMD_802_11_GET_LOG,
1550 +                               0, CMD_OPTION_WAITFORRSP, 0, NULL);
1551                 } else {
1552                         ret = -1;
1553                 }
1554 @@ -648,9 +681,9 @@ out:
1555                         ret);
1556         }
1557  
1558 -       mutex_lock(&adapter->lock);
1559 -       adapter->in_progress_assoc_req = NULL;
1560 -       mutex_unlock(&adapter->lock);
1561 +       mutex_lock(&priv->lock);
1562 +       priv->in_progress_assoc_req = NULL;
1563 +       mutex_unlock(&priv->lock);
1564         kfree(assoc_req);
1565  
1566  done:
1567 @@ -661,14 +694,15 @@ done:
1568  /*
1569   * Caller MUST hold any necessary locks
1570   */
1571 -struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
1572 +struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
1573  {
1574         struct assoc_request * assoc_req;
1575  
1576 -       if (!adapter->pending_assoc_req) {
1577 -               adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
1578 +       lbs_deb_enter(LBS_DEB_ASSOC);
1579 +       if (!priv->pending_assoc_req) {
1580 +               priv->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
1581                                                      GFP_KERNEL);
1582 -               if (!adapter->pending_assoc_req) {
1583 +               if (!priv->pending_assoc_req) {
1584                         lbs_pr_info("Not enough memory to allocate association"
1585                                 " request!\n");
1586                         return NULL;
1587 @@ -678,60 +712,59 @@ struct assoc_request * wlan_get_associat
1588         /* Copy current configuration attributes to the association request,
1589          * but don't overwrite any that are already set.
1590          */
1591 -       assoc_req = adapter->pending_assoc_req;
1592 +       assoc_req = priv->pending_assoc_req;
1593         if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
1594 -               memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid,
1595 +               memcpy(&assoc_req->ssid, &priv->curbssparams.ssid,
1596                        IW_ESSID_MAX_SIZE);
1597 -               assoc_req->ssid_len = adapter->curbssparams.ssid_len;
1598 +               assoc_req->ssid_len = priv->curbssparams.ssid_len;
1599         }
1600  
1601         if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
1602 -               assoc_req->channel = adapter->curbssparams.channel;
1603 +               assoc_req->channel = priv->curbssparams.channel;
1604  
1605         if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
1606 -               assoc_req->band = adapter->curbssparams.band;
1607 +               assoc_req->band = priv->curbssparams.band;
1608  
1609         if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
1610 -               assoc_req->mode = adapter->mode;
1611 +               assoc_req->mode = priv->mode;
1612  
1613         if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1614 -               memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
1615 +               memcpy(&assoc_req->bssid, priv->curbssparams.bssid,
1616                         ETH_ALEN);
1617         }
1618  
1619         if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) {
1620                 int i;
1621                 for (i = 0; i < 4; i++) {
1622 -                       memcpy(&assoc_req->wep_keys[i], &adapter->wep_keys[i],
1623 -                               sizeof(struct WLAN_802_11_KEY));
1624 +                       memcpy(&assoc_req->wep_keys[i], &priv->wep_keys[i],
1625 +                               sizeof(struct enc_key));
1626                 }
1627         }
1628  
1629         if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags))
1630 -               assoc_req->wep_tx_keyidx = adapter->wep_tx_keyidx;
1631 +               assoc_req->wep_tx_keyidx = priv->wep_tx_keyidx;
1632  
1633         if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
1634 -               memcpy(&assoc_req->wpa_mcast_key, &adapter->wpa_mcast_key,
1635 -                       sizeof(struct WLAN_802_11_KEY));
1636 +               memcpy(&assoc_req->wpa_mcast_key, &priv->wpa_mcast_key,
1637 +                       sizeof(struct enc_key));
1638         }
1639  
1640         if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
1641 -               memcpy(&assoc_req->wpa_unicast_key, &adapter->wpa_unicast_key,
1642 -                       sizeof(struct WLAN_802_11_KEY));
1643 +               memcpy(&assoc_req->wpa_unicast_key, &priv->wpa_unicast_key,
1644 +                       sizeof(struct enc_key));
1645         }
1646  
1647         if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
1648 -               memcpy(&assoc_req->secinfo, &adapter->secinfo,
1649 -                       sizeof(struct wlan_802_11_security));
1650 +               memcpy(&assoc_req->secinfo, &priv->secinfo,
1651 +                       sizeof(struct lbs_802_11_security));
1652         }
1653  
1654         if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
1655 -               memcpy(&assoc_req->wpa_ie, &adapter->wpa_ie,
1656 +               memcpy(&assoc_req->wpa_ie, &priv->wpa_ie,
1657                         MAX_WPA_IE_LEN);
1658 -               assoc_req->wpa_ie_len = adapter->wpa_ie_len;
1659 +               assoc_req->wpa_ie_len = priv->wpa_ie_len;
1660         }
1661  
1662 -       print_assoc_req(__func__, assoc_req);
1663 -
1664 +       lbs_deb_leave(LBS_DEB_ASSOC);
1665         return assoc_req;
1666  }
1667 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/assoc.h linux-2.6.22-300/drivers/net/wireless/libertas/assoc.h
1668 --- linux-2.6.22-250/drivers/net/wireless/libertas/assoc.h      2007-07-08 19:32:17.000000000 -0400
1669 +++ linux-2.6.22-300/drivers/net/wireless/libertas/assoc.h      2008-06-05 18:10:06.000000000 -0400
1670 @@ -1,32 +1,12 @@
1671  /* Copyright (C) 2006, Red Hat, Inc. */
1672  
1673 -#ifndef _WLAN_ASSOC_H_
1674 -#define _WLAN_ASSOC_H_
1675 +#ifndef _LBS_ASSOC_H_
1676 +#define _LBS_ASSOC_H_
1677  
1678  #include "dev.h"
1679  
1680 -void libertas_association_worker(struct work_struct *work);
1681 +void lbs_association_worker(struct work_struct *work);
1682 +struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
1683 +void lbs_sync_channel(struct work_struct *work);
1684  
1685 -struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
1686 -
1687 -void libertas_sync_channel(struct work_struct *work);
1688 -
1689 -#define ASSOC_DELAY (HZ / 2)
1690 -static inline void wlan_postpone_association_work(wlan_private *priv)
1691 -{
1692 -       if (priv->adapter->surpriseremoved)
1693 -               return;
1694 -       cancel_delayed_work(&priv->assoc_work);
1695 -       queue_delayed_work(priv->assoc_thread, &priv->assoc_work, ASSOC_DELAY);
1696 -}
1697 -
1698 -static inline void wlan_cancel_association_work(wlan_private *priv)
1699 -{
1700 -       cancel_delayed_work(&priv->assoc_work);
1701 -       if (priv->adapter->pending_assoc_req) {
1702 -               kfree(priv->adapter->pending_assoc_req);
1703 -               priv->adapter->pending_assoc_req = NULL;
1704 -       }
1705 -}
1706 -
1707 -#endif /* _WLAN_ASSOC_H */
1708 +#endif /* _LBS_ASSOC_H */
1709 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/cmd.c linux-2.6.22-300/drivers/net/wireless/libertas/cmd.c
1710 --- linux-2.6.22-250/drivers/net/wireless/libertas/cmd.c        2008-07-17 00:17:57.000000000 -0400
1711 +++ linux-2.6.22-300/drivers/net/wireless/libertas/cmd.c        2008-06-05 18:10:06.000000000 -0400
1712 @@ -4,6 +4,7 @@
1713    */
1714  
1715  #include <net/iw_handler.h>
1716 +#include <net/ieee80211.h>
1717  #include "host.h"
1718  #include "hostcmd.h"
1719  #include "decl.h"
1720 @@ -11,79 +12,195 @@
1721  #include "dev.h"
1722  #include "join.h"
1723  #include "wext.h"
1724 +#include "cmd.h"
1725  
1726 -static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
1727 +static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
1728 +static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
1729 +                   struct cmd_ctrl_node *ptempnode,
1730 +                   void *pdata_buf);
1731  
1732 -static u16 commands_allowed_in_ps[] = {
1733 -       cmd_802_11_rssi,
1734 -};
1735  
1736  /**
1737 - *  @brief This function checks if the commans is allowed
1738 - *  in PS mode not.
1739 + *  @brief Simple callback that copies response back into command
1740   *
1741 - *  @param command the command ID
1742 - *  @return       TRUE or FALSE
1743 + *  @param priv        A pointer to struct lbs_private structure
1744 + *  @param extra       A pointer to the original command structure for which
1745 + *                      'resp' is a response
1746 + *  @param resp         A pointer to the command response
1747 + *
1748 + *  @return            0 on success, error on failure
1749   */
1750 -static u8 is_command_allowed_in_ps(__le16 command)
1751 +int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
1752 +                    struct cmd_header *resp)
1753  {
1754 -       int i;
1755 +       struct cmd_header *buf = (void *)extra;
1756 +       uint16_t copy_len;
1757  
1758 -       for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) {
1759 -               if (command == cpu_to_le16(commands_allowed_in_ps[i]))
1760 -                       return 1;
1761 -       }
1762 +       copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
1763 +       memcpy(buf, resp, copy_len);
1764 +       return 0;
1765 +}
1766 +EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
1767  
1768 +/**
1769 + *  @brief Simple callback that ignores the result. Use this if
1770 + *  you just want to send a command to the hardware, but don't
1771 + *  care for the result.
1772 + *
1773 + *  @param priv         ignored
1774 + *  @param extra        ignored
1775 + *  @param resp         ignored
1776 + *
1777 + *  @return            0 for success
1778 + */
1779 +static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
1780 +                    struct cmd_header *resp)
1781 +{
1782         return 0;
1783  }
1784  
1785 -static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd)
1786 +
1787 +/**
1788 + *  @brief Checks whether a command is allowed in Power Save mode
1789 + *
1790 + *  @param command the command ID
1791 + *  @return       1 if allowed, 0 if not allowed
1792 + */
1793 +static u8 is_command_allowed_in_ps(u16 cmd)
1794  {
1795 -       struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
1796 +       switch (cmd) {
1797 +       case CMD_802_11_RSSI:
1798 +               return 1;
1799 +       default:
1800 +               break;
1801 +       }
1802 +       return 0;
1803 +}
1804 +
1805 +/**
1806 + *  @brief Updates the hardware details like MAC address and regulatory region
1807 + *
1808 + *  @param priv        A pointer to struct lbs_private structure
1809 + *
1810 + *  @return            0 on success, error on failure
1811 + */
1812 +int lbs_update_hw_spec(struct lbs_private *priv)
1813 +{
1814 +       struct cmd_ds_get_hw_spec cmd;
1815 +       int ret = -1;
1816 +       u32 i;
1817 +       DECLARE_MAC_BUF(mac);
1818  
1819         lbs_deb_enter(LBS_DEB_CMD);
1820  
1821 -       cmd->command = cpu_to_le16(cmd_get_hw_spec);
1822 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
1823 -       memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN);
1824 +       memset(&cmd, 0, sizeof(cmd));
1825 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1826 +       memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
1827 +       ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
1828 +       if (ret)
1829 +               goto out;
1830 +
1831 +       priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
1832 +       memcpy(priv->fwreleasenumber, cmd.fwreleasenumber, 4);
1833 +
1834 +       lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
1835 +                   priv->fwreleasenumber[2], priv->fwreleasenumber[1],
1836 +                   priv->fwreleasenumber[0], priv->fwreleasenumber[3]);
1837 +       lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
1838 +                   print_mac(mac, cmd.permanentaddr));
1839 +       lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
1840 +                   cmd.hwifversion, cmd.version);
1841 +
1842 +       /* Clamp region code to 8-bit since FW spec indicates that it should
1843 +        * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
1844 +        * returns non-zero high 8 bits here.
1845 +        */
1846 +       priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
1847  
1848 +       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
1849 +               /* use the region code to search for the index */
1850 +               if (priv->regioncode == lbs_region_code_to_index[i])
1851 +                       break;
1852 +       }
1853 +
1854 +       /* if it's unidentified region code, use the default (USA) */
1855 +       if (i >= MRVDRV_MAX_REGION_CODE) {
1856 +               priv->regioncode = 0x10;
1857 +               lbs_pr_info("unidentified region code; using the default (USA)\n");
1858 +       }
1859 +
1860 +       if (priv->current_addr[0] == 0xff)
1861 +               memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
1862 +
1863 +       memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
1864 +       if (priv->mesh_dev)
1865 +               memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
1866 +
1867 +       if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
1868 +               ret = -1;
1869 +               goto out;
1870 +       }
1871 +
1872 +       if (lbs_set_universaltable(priv, 0)) {
1873 +               ret = -1;
1874 +               goto out;
1875 +       }
1876 +
1877 +out:
1878         lbs_deb_leave(LBS_DEB_CMD);
1879 -       return 0;
1880 +       return ret;
1881  }
1882  
1883 -static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
1884 +int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
1885 +{
1886 +       struct cmd_ds_host_sleep cmd_config;
1887 +       int ret;
1888 +
1889 +       cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
1890 +       cmd_config.criteria = cpu_to_le32(criteria);
1891 +       cmd_config.gpio = priv->wol_gpio;
1892 +       cmd_config.gap = priv->wol_gap;
1893 +
1894 +       ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
1895 +       if (!ret) {
1896 +               lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
1897 +               priv->wol_criteria = criteria;
1898 +       } else {
1899 +               lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
1900 +       }
1901 +
1902 +       return ret;
1903 +}
1904 +EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
1905 +
1906 +static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
1907                                    struct cmd_ds_command *cmd,
1908                                    u16 cmd_action)
1909  {
1910         struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
1911 -       wlan_adapter *adapter = priv->adapter;
1912  
1913         lbs_deb_enter(LBS_DEB_CMD);
1914  
1915 -       cmd->command = cpu_to_le16(cmd_802_11_ps_mode);
1916 +       cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
1917         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
1918                                 S_DS_GEN);
1919         psm->action = cpu_to_le16(cmd_action);
1920         psm->multipledtim = 0;
1921         switch (cmd_action) {
1922 -       case cmd_subcmd_enter_ps:
1923 +       case CMD_SUBCMD_ENTER_PS:
1924                 lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
1925 -               lbs_deb_cmd("locallisteninterval = %d\n",
1926 -                      adapter->locallisteninterval);
1927  
1928 -               psm->locallisteninterval =
1929 -                   cpu_to_le16(adapter->locallisteninterval);
1930 -               psm->nullpktinterval =
1931 -                   cpu_to_le16(adapter->nullpktinterval);
1932 +               psm->locallisteninterval = 0;
1933 +               psm->nullpktinterval = 0;
1934                 psm->multipledtim =
1935 -                   cpu_to_le16(priv->adapter->multipledtim);
1936 +                   cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
1937                 break;
1938  
1939 -       case cmd_subcmd_exit_ps:
1940 +       case CMD_SUBCMD_EXIT_PS:
1941                 lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
1942                 break;
1943  
1944 -       case cmd_subcmd_sleep_confirmed:
1945 +       case CMD_SUBCMD_SLEEP_CONFIRMED:
1946                 lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
1947                 break;
1948  
1949 @@ -95,13 +212,15 @@ static int wlan_cmd_802_11_ps_mode(wlan_
1950         return 0;
1951  }
1952  
1953 -static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
1954 +static int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
1955                                               struct cmd_ds_command *cmd,
1956                                               u16 cmd_action, void *pdata_buf)
1957  {
1958         u16 *timeout = pdata_buf;
1959  
1960 -       cmd->command = cpu_to_le16(cmd_802_11_inactivity_timeout);
1961 +       lbs_deb_enter(LBS_DEB_CMD);
1962 +
1963 +       cmd->command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT);
1964         cmd->size =
1965             cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout)
1966                              + S_DS_GEN);
1967 @@ -113,104 +232,104 @@ static int wlan_cmd_802_11_inactivity_ti
1968         else
1969                 cmd->params.inactivity_timeout.timeout = 0;
1970  
1971 +       lbs_deb_leave(LBS_DEB_CMD);
1972         return 0;
1973  }
1974  
1975 -static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
1976 +static int lbs_cmd_802_11_sleep_params(struct lbs_private *priv,
1977                                         struct cmd_ds_command *cmd,
1978                                         u16 cmd_action)
1979  {
1980 -       wlan_adapter *adapter = priv->adapter;
1981         struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
1982  
1983         lbs_deb_enter(LBS_DEB_CMD);
1984  
1985         cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
1986                                 S_DS_GEN);
1987 -       cmd->command = cpu_to_le16(cmd_802_11_sleep_params);
1988 +       cmd->command = cpu_to_le16(CMD_802_11_SLEEP_PARAMS);
1989  
1990 -       if (cmd_action == cmd_act_get) {
1991 -               memset(&adapter->sp, 0, sizeof(struct sleep_params));
1992 +       if (cmd_action == CMD_ACT_GET) {
1993 +               memset(&priv->sp, 0, sizeof(struct sleep_params));
1994                 memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params));
1995                 sp->action = cpu_to_le16(cmd_action);
1996 -       } else if (cmd_action == cmd_act_set) {
1997 +       } else if (cmd_action == CMD_ACT_SET) {
1998                 sp->action = cpu_to_le16(cmd_action);
1999 -               sp->error = cpu_to_le16(adapter->sp.sp_error);
2000 -               sp->offset = cpu_to_le16(adapter->sp.sp_offset);
2001 -               sp->stabletime = cpu_to_le16(adapter->sp.sp_stabletime);
2002 -               sp->calcontrol = (u8) adapter->sp.sp_calcontrol;
2003 -               sp->externalsleepclk = (u8) adapter->sp.sp_extsleepclk;
2004 -               sp->reserved = cpu_to_le16(adapter->sp.sp_reserved);
2005 +               sp->error = cpu_to_le16(priv->sp.sp_error);
2006 +               sp->offset = cpu_to_le16(priv->sp.sp_offset);
2007 +               sp->stabletime = cpu_to_le16(priv->sp.sp_stabletime);
2008 +               sp->calcontrol = (u8) priv->sp.sp_calcontrol;
2009 +               sp->externalsleepclk = (u8) priv->sp.sp_extsleepclk;
2010 +               sp->reserved = cpu_to_le16(priv->sp.sp_reserved);
2011         }
2012  
2013         lbs_deb_leave(LBS_DEB_CMD);
2014         return 0;
2015  }
2016  
2017 -static int wlan_cmd_802_11_set_wep(wlan_private * priv,
2018 +static int lbs_cmd_802_11_set_wep(struct lbs_private *priv,
2019                                     struct cmd_ds_command *cmd,
2020                                     u32 cmd_act,
2021                                     void * pdata_buf)
2022  {
2023         struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep;
2024 -       wlan_adapter *adapter = priv->adapter;
2025         int ret = 0;
2026         struct assoc_request * assoc_req = pdata_buf;
2027  
2028         lbs_deb_enter(LBS_DEB_CMD);
2029  
2030 -       cmd->command = cpu_to_le16(cmd_802_11_set_wep);
2031 +       cmd->command = cpu_to_le16(CMD_802_11_SET_WEP);
2032         cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);
2033  
2034 -       if (cmd_act == cmd_act_add) {
2035 +       if (cmd_act == CMD_ACT_ADD) {
2036                 int i;
2037  
2038                 if (!assoc_req) {
2039 -                       lbs_deb_cmd("Invalid association request!");
2040 +                       lbs_deb_cmd("Invalid association request!\n");
2041                         ret = -1;
2042                         goto done;
2043                 }
2044  
2045 -               wep->action = cpu_to_le16(cmd_act_add);
2046 +               wep->action = cpu_to_le16(CMD_ACT_ADD);
2047  
2048                 /* default tx key index */
2049                 wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
2050 -                                                 (u32)cmd_WEP_KEY_INDEX_MASK));
2051 -
2052 -               lbs_deb_cmd("Tx key Index: %u\n", le16_to_cpu(wep->keyindex));
2053 +                                                 (u32)CMD_WEP_KEY_INDEX_MASK));
2054  
2055                 /* Copy key types and material to host command structure */
2056                 for (i = 0; i < 4; i++) {
2057 -                       struct WLAN_802_11_KEY * pkey = &assoc_req->wep_keys[i];
2058 +                       struct enc_key * pkey = &assoc_req->wep_keys[i];
2059  
2060                         switch (pkey->len) {
2061                         case KEY_LEN_WEP_40:
2062 -                               wep->keytype[i] = cmd_type_wep_40_bit;
2063 +                               wep->keytype[i] = CMD_TYPE_WEP_40_BIT;
2064                                 memmove(&wep->keymaterial[i], pkey->key,
2065                                         pkey->len);
2066 +                               lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
2067                                 break;
2068                         case KEY_LEN_WEP_104:
2069 -                               wep->keytype[i] = cmd_type_wep_104_bit;
2070 +                               wep->keytype[i] = CMD_TYPE_WEP_104_BIT;
2071                                 memmove(&wep->keymaterial[i], pkey->key,
2072                                         pkey->len);
2073 +                               lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
2074                                 break;
2075                         case 0:
2076                                 break;
2077                         default:
2078 -                               lbs_deb_cmd("Invalid WEP key %d length of %d\n",
2079 +                               lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
2080                                        i, pkey->len);
2081                                 ret = -1;
2082                                 goto done;
2083                                 break;
2084                         }
2085                 }
2086 -       } else if (cmd_act == cmd_act_remove) {
2087 +       } else if (cmd_act == CMD_ACT_REMOVE) {
2088                 /* ACT_REMOVE clears _all_ WEP keys */
2089 -               wep->action = cpu_to_le16(cmd_act_remove);
2090 +               wep->action = cpu_to_le16(CMD_ACT_REMOVE);
2091  
2092                 /* default tx key index */
2093 -               wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx &
2094 -                                                 (u32)cmd_WEP_KEY_INDEX_MASK));
2095 +               wep->keyindex = cpu_to_le16((u16)(priv->wep_tx_keyidx &
2096 +                                                 (u32)CMD_WEP_KEY_INDEX_MASK));
2097 +               lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
2098         }
2099  
2100         ret = 0;
2101 @@ -220,7 +339,7 @@ done:
2102         return ret;
2103  }
2104  
2105 -static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
2106 +static int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv,
2107                                       struct cmd_ds_command *cmd,
2108                                       u16 cmd_action,
2109                                       void * pdata_buf)
2110 @@ -230,15 +349,16 @@ static int wlan_cmd_802_11_enable_rsn(wl
2111  
2112         lbs_deb_enter(LBS_DEB_CMD);
2113  
2114 -       cmd->command = cpu_to_le16(cmd_802_11_enable_rsn);
2115 +       cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN);
2116         cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
2117         penableRSN->action = cpu_to_le16(cmd_action);
2118  
2119 -       if (cmd_action == cmd_act_set) {
2120 +       if (cmd_action == CMD_ACT_SET) {
2121                 if (*enable)
2122 -                       penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
2123 +                       penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN);
2124                 else
2125 -                       penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
2126 +                       penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN);
2127 +               lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
2128         }
2129  
2130         lbs_deb_leave(LBS_DEB_CMD);
2131 @@ -246,10 +366,56 @@ static int wlan_cmd_802_11_enable_rsn(wl
2132  }
2133  
2134  
2135 +static ssize_t lbs_tlv_size(const u8 *tlv, u16 size)
2136 +{
2137 +       ssize_t pos = 0;
2138 +       struct mrvlietypesheader *tlv_h;
2139 +       while (pos < size) {
2140 +               u16 length;
2141 +               tlv_h = (struct mrvlietypesheader *) tlv;
2142 +               if (tlv_h->len == 0)
2143 +                       return pos;
2144 +               length = le16_to_cpu(tlv_h->len) +
2145 +                       sizeof(struct mrvlietypesheader);
2146 +               pos += length;
2147 +               tlv += length;
2148 +       }
2149 +       return pos;
2150 +}
2151 +
2152 +
2153 +static void lbs_cmd_802_11_subscribe_event(struct lbs_private *priv,
2154 +       struct cmd_ds_command *cmd, u16 cmd_action,
2155 +       void *pdata_buf)
2156 +{
2157 +       struct cmd_ds_802_11_subscribe_event *events =
2158 +               (struct cmd_ds_802_11_subscribe_event *) pdata_buf;
2159 +
2160 +       /* pdata_buf points to a struct cmd_ds_802_11_subscribe_event and room
2161 +        * for various Marvell TLVs */
2162 +
2163 +       lbs_deb_enter(LBS_DEB_CMD);
2164 +
2165 +       cmd->size = cpu_to_le16(sizeof(*events)
2166 +                       - sizeof(events->tlv)
2167 +                       + S_DS_GEN);
2168 +       cmd->params.subscribe_event.action = cpu_to_le16(cmd_action);
2169 +       if (cmd_action == CMD_ACT_GET) {
2170 +               cmd->params.subscribe_event.events = 0;
2171 +       } else {
2172 +               ssize_t sz = lbs_tlv_size(events->tlv, sizeof(events->tlv));
2173 +               cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sz);
2174 +               cmd->params.subscribe_event.events = events->events;
2175 +               memcpy(cmd->params.subscribe_event.tlv, events->tlv, sz);
2176 +       }
2177 +
2178 +       lbs_deb_leave(LBS_DEB_CMD);
2179 +}
2180 +
2181  static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
2182 -                            struct WLAN_802_11_KEY * pkey)
2183 +                            struct enc_key * pkey)
2184  {
2185 -       pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
2186 +       lbs_deb_enter(LBS_DEB_CMD);
2187  
2188         if (pkey->flags & KEY_INFO_WPA_ENABLED) {
2189                 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
2190 @@ -262,15 +428,17 @@ static void set_one_wpa_key(struct MrvlI
2191         }
2192  
2193         pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
2194 +       pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
2195         pkeyparamset->keylen = cpu_to_le16(pkey->len);
2196         memcpy(pkeyparamset->key, pkey->key, pkey->len);
2197         pkeyparamset->length = cpu_to_le16(  sizeof(pkeyparamset->keytypeid)
2198                                                 + sizeof(pkeyparamset->keyinfo)
2199                                                 + sizeof(pkeyparamset->keylen)
2200                                                 + sizeof(pkeyparamset->key));
2201 +       lbs_deb_leave(LBS_DEB_CMD);
2202  }
2203  
2204 -static int wlan_cmd_802_11_key_material(wlan_private * priv,
2205 +static int lbs_cmd_802_11_key_material(struct lbs_private *priv,
2206                                         struct cmd_ds_command *cmd,
2207                                         u16 cmd_action,
2208                                         u32 cmd_oid, void *pdata_buf)
2209 @@ -283,10 +451,10 @@ static int wlan_cmd_802_11_key_material(
2210  
2211         lbs_deb_enter(LBS_DEB_CMD);
2212  
2213 -       cmd->command = cpu_to_le16(cmd_802_11_key_material);
2214 +       cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL);
2215         pkeymaterial->action = cpu_to_le16(cmd_action);
2216  
2217 -       if (cmd_action == cmd_act_get) {
2218 +       if (cmd_action == CMD_ACT_GET) {
2219                 cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action));
2220                 ret = 0;
2221                 goto done;
2222 @@ -317,61 +485,67 @@ done:
2223         return ret;
2224  }
2225  
2226 -static int wlan_cmd_802_11_reset(wlan_private * priv,
2227 +static int lbs_cmd_802_11_reset(struct lbs_private *priv,
2228                                  struct cmd_ds_command *cmd, int cmd_action)
2229  {
2230         struct cmd_ds_802_11_reset *reset = &cmd->params.reset;
2231  
2232 -       cmd->command = cpu_to_le16(cmd_802_11_reset);
2233 +       lbs_deb_enter(LBS_DEB_CMD);
2234 +
2235 +       cmd->command = cpu_to_le16(CMD_802_11_RESET);
2236         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
2237         reset->action = cpu_to_le16(cmd_action);
2238  
2239 +       lbs_deb_leave(LBS_DEB_CMD);
2240         return 0;
2241  }
2242  
2243 -static int wlan_cmd_802_11_get_log(wlan_private * priv,
2244 +static int lbs_cmd_802_11_get_log(struct lbs_private *priv,
2245                                    struct cmd_ds_command *cmd)
2246  {
2247 -       cmd->command = cpu_to_le16(cmd_802_11_get_log);
2248 +       lbs_deb_enter(LBS_DEB_CMD);
2249 +       cmd->command = cpu_to_le16(CMD_802_11_GET_LOG);
2250         cmd->size =
2251                 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN);
2252  
2253 +       lbs_deb_leave(LBS_DEB_CMD);
2254         return 0;
2255  }
2256  
2257 -static int wlan_cmd_802_11_get_stat(wlan_private * priv,
2258 +static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
2259                                     struct cmd_ds_command *cmd)
2260  {
2261 -       cmd->command = cpu_to_le16(cmd_802_11_get_stat);
2262 +       lbs_deb_enter(LBS_DEB_CMD);
2263 +       cmd->command = cpu_to_le16(CMD_802_11_GET_STAT);
2264         cmd->size =
2265             cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN);
2266  
2267 +       lbs_deb_leave(LBS_DEB_CMD);
2268         return 0;
2269  }
2270  
2271 -static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
2272 +static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
2273                                     struct cmd_ds_command *cmd,
2274                                     int cmd_action,
2275                                     int cmd_oid, void *pdata_buf)
2276  {
2277         struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib;
2278 -       wlan_adapter *adapter = priv->adapter;
2279         u8 ucTemp;
2280  
2281         lbs_deb_enter(LBS_DEB_CMD);
2282  
2283         lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
2284  
2285 -       cmd->command = cpu_to_le16(cmd_802_11_snmp_mib);
2286 +       cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB);
2287         cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN);
2288  
2289         switch (cmd_oid) {
2290         case OID_802_11_INFRASTRUCTURE_MODE:
2291         {
2292                 u8 mode = (u8) (size_t) pdata_buf;
2293 -               pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
2294 -               pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i);
2295 -               pSNMPMIB->bufsize = sizeof(u8);
2296 +               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
2297 +               pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
2298 +               pSNMPMIB->bufsize = cpu_to_le16(sizeof(u8));
2299                 if (mode == IW_MODE_ADHOC) {
2300                         ucTemp = SNMP_MIB_VALUE_ADHOC;
2301                 } else {
2302 @@ -388,11 +562,11 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2303                 {
2304                         u32 ulTemp;
2305  
2306 -                       pSNMPMIB->oid = cpu_to_le16((u16) dot11d_i);
2307 +                       pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);
2308  
2309 -                       if (cmd_action == cmd_act_set) {
2310 -                               pSNMPMIB->querytype = cmd_act_set;
2311 -                               pSNMPMIB->bufsize = sizeof(u16);
2312 +                       if (cmd_action == CMD_ACT_SET) {
2313 +                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
2314 +                               pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
2315                                 ulTemp = *(u32 *)pdata_buf;
2316                                 *((__le16 *)(pSNMPMIB->value)) =
2317                                     cpu_to_le16((u16) ulTemp);
2318 @@ -404,12 +578,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2319                 {
2320                         u32 ulTemp;
2321  
2322 -                       pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i);
2323 +                       pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I);
2324  
2325 -                       if (cmd_action == cmd_act_get) {
2326 -                               pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
2327 -                       } else if (cmd_action == cmd_act_set) {
2328 -                               pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
2329 +                       if (cmd_action == CMD_ACT_GET) {
2330 +                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
2331 +                       } else if (cmd_action == CMD_ACT_SET) {
2332 +                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
2333                                 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
2334                                 ulTemp = *((u32 *) pdata_buf);
2335                                 *((__le16 *)(pSNMPMIB->value)) =
2336 @@ -424,12 +598,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2337                 {
2338  
2339                         u32 ulTemp;
2340 -                       pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i);
2341 +                       pSNMPMIB->oid = cpu_to_le16(RTSTHRESH_I);
2342  
2343 -                       if (cmd_action == cmd_act_get) {
2344 -                               pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
2345 -                       } else if (cmd_action == cmd_act_set) {
2346 -                               pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
2347 +                       if (cmd_action == CMD_ACT_GET) {
2348 +                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
2349 +                       } else if (cmd_action == CMD_ACT_SET) {
2350 +                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
2351                                 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
2352                                 ulTemp = *((u32 *)pdata_buf);
2353                                 *(__le16 *)(pSNMPMIB->value) =
2354 @@ -439,15 +613,15 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2355                         break;
2356                 }
2357         case OID_802_11_TX_RETRYCOUNT:
2358 -               pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i);
2359 +               pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I);
2360  
2361 -               if (cmd_action == cmd_act_get) {
2362 -                       pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
2363 -               } else if (cmd_action == cmd_act_set) {
2364 -                       pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
2365 +               if (cmd_action == CMD_ACT_GET) {
2366 +                       pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
2367 +               } else if (cmd_action == CMD_ACT_SET) {
2368 +                       pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
2369                         pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
2370                         *((__le16 *)(pSNMPMIB->value)) =
2371 -                           cpu_to_le16((u16) adapter->txretrycount);
2372 +                           cpu_to_le16((u16) priv->txretrycount);
2373                 }
2374  
2375                 break;
2376 @@ -461,7 +635,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2377                le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));
2378  
2379         lbs_deb_cmd(
2380 -              "SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n",
2381 +              "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n",
2382                le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
2383                le16_to_cpu(pSNMPMIB->bufsize),
2384                le16_to_cpu(*(__le16 *) pSNMPMIB->value));
2385 @@ -470,11 +644,10 @@ static int wlan_cmd_802_11_snmp_mib(wlan
2386         return 0;
2387  }
2388  
2389 -static int wlan_cmd_802_11_radio_control(wlan_private * priv,
2390 +static int lbs_cmd_802_11_radio_control(struct lbs_private *priv,
2391                                          struct cmd_ds_command *cmd,
2392                                          int cmd_action)
2393  {
2394 -       wlan_adapter *adapter = priv->adapter;
2395         struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio;
2396  
2397         lbs_deb_enter(LBS_DEB_CMD);
2398 @@ -482,26 +655,26 @@ static int wlan_cmd_802_11_radio_control
2399         cmd->size =
2400             cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) +
2401                              S_DS_GEN);
2402 -       cmd->command = cpu_to_le16(cmd_802_11_radio_control);
2403 +       cmd->command = cpu_to_le16(CMD_802_11_RADIO_CONTROL);
2404  
2405         pradiocontrol->action = cpu_to_le16(cmd_action);
2406  
2407 -       switch (adapter->preamble) {
2408 -       case cmd_type_short_preamble:
2409 +       switch (priv->preamble) {
2410 +       case CMD_TYPE_SHORT_PREAMBLE:
2411                 pradiocontrol->control = cpu_to_le16(SET_SHORT_PREAMBLE);
2412                 break;
2413  
2414 -       case cmd_type_long_preamble:
2415 +       case CMD_TYPE_LONG_PREAMBLE:
2416                 pradiocontrol->control = cpu_to_le16(SET_LONG_PREAMBLE);
2417                 break;
2418  
2419 -       case cmd_type_auto_preamble:
2420 +       case CMD_TYPE_AUTO_PREAMBLE:
2421         default:
2422                 pradiocontrol->control = cpu_to_le16(SET_AUTO_PREAMBLE);
2423                 break;
2424         }
2425  
2426 -       if (adapter->radioon)
2427 +       if (priv->radioon)
2428                 pradiocontrol->control |= cpu_to_le16(TURN_ON_RF);
2429         else
2430                 pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF);
2431 @@ -510,7 +683,7 @@ static int wlan_cmd_802_11_radio_control
2432         return 0;
2433  }
2434  
2435 -static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
2436 +static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv,
2437                                        struct cmd_ds_command *cmd,
2438                                        u16 cmd_action, void *pdata_buf)
2439  {
2440 @@ -521,7 +694,7 @@ static int wlan_cmd_802_11_rf_tx_power(w
2441  
2442         cmd->size =
2443             cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN);
2444 -       cmd->command = cpu_to_le16(cmd_802_11_rf_tx_power);
2445 +       cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER);
2446         prtp->action = cpu_to_le16(cmd_action);
2447  
2448         lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
2449 @@ -529,23 +702,23 @@ static int wlan_cmd_802_11_rf_tx_power(w
2450                     le16_to_cpu(prtp->action));
2451  
2452         switch (cmd_action) {
2453 -       case cmd_act_tx_power_opt_get:
2454 -               prtp->action = cpu_to_le16(cmd_act_get);
2455 +       case CMD_ACT_TX_POWER_OPT_GET:
2456 +               prtp->action = cpu_to_le16(CMD_ACT_GET);
2457                 prtp->currentlevel = 0;
2458                 break;
2459  
2460 -       case cmd_act_tx_power_opt_set_high:
2461 -               prtp->action = cpu_to_le16(cmd_act_set);
2462 -               prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_high);
2463 +       case CMD_ACT_TX_POWER_OPT_SET_HIGH:
2464 +               prtp->action = cpu_to_le16(CMD_ACT_SET);
2465 +               prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH);
2466                 break;
2467  
2468 -       case cmd_act_tx_power_opt_set_mid:
2469 -               prtp->action = cpu_to_le16(cmd_act_set);
2470 -               prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_mid);
2471 +       case CMD_ACT_TX_POWER_OPT_SET_MID:
2472 +               prtp->action = cpu_to_le16(CMD_ACT_SET);
2473 +               prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID);
2474                 break;
2475  
2476 -       case cmd_act_tx_power_opt_set_low:
2477 -               prtp->action = cpu_to_le16(cmd_act_set);
2478 +       case CMD_ACT_TX_POWER_OPT_SET_LOW:
2479 +               prtp->action = cpu_to_le16(CMD_ACT_SET);
2480                 prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
2481                 break;
2482         }
2483 @@ -554,148 +727,224 @@ static int wlan_cmd_802_11_rf_tx_power(w
2484         return 0;
2485  }
2486  
2487 -static int wlan_cmd_802_11_rf_antenna(wlan_private * priv,
2488 +static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv,
2489                                       struct cmd_ds_command *cmd,
2490                                       u16 cmd_action, void *pdata_buf)
2491  {
2492 -       struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant;
2493 +       struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor;
2494  
2495 -       cmd->command = cpu_to_le16(cmd_802_11_rf_antenna);
2496 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
2497 -                               S_DS_GEN);
2498 +       cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE);
2499 +       cmd->size =
2500 +           cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) +
2501 +                            S_DS_GEN);
2502  
2503 -       rant->action = cpu_to_le16(cmd_action);
2504 -       if ((cmd_action == cmd_act_set_rx) || (cmd_action == cmd_act_set_tx)) {
2505 -               rant->antennamode = cpu_to_le16((u16) (*(u32 *) pdata_buf));
2506 +       monitor->action = cpu_to_le16(cmd_action);
2507 +       if (cmd_action == CMD_ACT_SET) {
2508 +               monitor->mode =
2509 +                   cpu_to_le16((u16) (*(u32 *) pdata_buf));
2510         }
2511  
2512         return 0;
2513  }
2514  
2515 -static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
2516 +static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
2517                                               struct cmd_ds_command *cmd,
2518                                               u16 cmd_action)
2519  {
2520         struct cmd_ds_802_11_rate_adapt_rateset
2521         *rateadapt = &cmd->params.rateset;
2522 -       wlan_adapter *adapter = priv->adapter;
2523  
2524 +       lbs_deb_enter(LBS_DEB_CMD);
2525         cmd->size =
2526             cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset)
2527                              + S_DS_GEN);
2528 -       cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset);
2529 -
2530 -       lbs_deb_enter(LBS_DEB_CMD);
2531 +       cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET);
2532  
2533         rateadapt->action = cpu_to_le16(cmd_action);
2534 -       rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto);
2535 -       rateadapt->bitmap = cpu_to_le16(adapter->ratebitmap);
2536 +       rateadapt->enablehwauto = cpu_to_le16(priv->enablehwauto);
2537 +       rateadapt->bitmap = cpu_to_le16(priv->ratebitmap);
2538  
2539         lbs_deb_leave(LBS_DEB_CMD);
2540         return 0;
2541  }
2542  
2543 -static int wlan_cmd_802_11_data_rate(wlan_private * priv,
2544 -                                    struct cmd_ds_command *cmd,
2545 -                                    u16 cmd_action)
2546 +/**
2547 + *  @brief Get the current data rate
2548 + *
2549 + *  @param priv        A pointer to struct lbs_private structure
2550 + *
2551 + *  @return            The data rate on success, error on failure
2552 + */
2553 +int lbs_get_data_rate(struct lbs_private *priv)
2554  {
2555 -       struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
2556 -       wlan_adapter *adapter = priv->adapter;
2557 +       struct cmd_ds_802_11_data_rate cmd;
2558 +       int ret = -1;
2559  
2560         lbs_deb_enter(LBS_DEB_CMD);
2561  
2562 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
2563 -                            S_DS_GEN);
2564 +       memset(&cmd, 0, sizeof(cmd));
2565 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2566 +       cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
2567 +
2568 +       ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
2569 +       if (ret)
2570 +               goto out;
2571  
2572 -       cmd->command = cpu_to_le16(cmd_802_11_data_rate);
2573 +       lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
2574  
2575 -       memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate));
2576 +       ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]);
2577 +       lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret);
2578  
2579 -       pdatarate->action = cpu_to_le16(cmd_action);
2580 +out:
2581 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
2582 +       return ret;
2583 +}
2584  
2585 -       if (cmd_action == cmd_act_set_tx_fix_rate) {
2586 -               pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate);
2587 -               lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n",
2588 -                      adapter->datarate);
2589 -       } else if (cmd_action == cmd_act_set_tx_auto) {
2590 -               lbs_deb_cmd("Setting FW for AUTO rate\n");
2591 +/**
2592 + *  @brief Set the data rate
2593 + *
2594 + *  @param priv        A pointer to struct lbs_private structure
2595 + *  @param rate        The desired data rate, or 0 to clear a locked rate
2596 + *
2597 + *  @return            0 on success, error on failure
2598 + */
2599 +int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
2600 +{
2601 +       struct cmd_ds_802_11_data_rate cmd;
2602 +       int ret = 0;
2603 +
2604 +       lbs_deb_enter(LBS_DEB_CMD);
2605 +
2606 +       memset(&cmd, 0, sizeof(cmd));
2607 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2608 +
2609 +       if (rate > 0) {
2610 +               cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
2611 +               cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
2612 +               if (cmd.rates[0] == 0) {
2613 +                       lbs_deb_cmd("DATA_RATE: invalid requested rate of"
2614 +                                   " 0x%02X\n", rate);
2615 +                       ret = 0;
2616 +                       goto out;
2617 +               }
2618 +               lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
2619 +       } else {
2620 +               cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
2621 +               lbs_deb_cmd("DATA_RATE: setting auto\n");
2622         }
2623  
2624 -       lbs_deb_leave(LBS_DEB_CMD);
2625 -       return 0;
2626 +       ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
2627 +       if (ret)
2628 +               goto out;
2629 +
2630 +       lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
2631 +
2632 +       /* FIXME: get actual rates FW can do if this command actually returns
2633 +        * all data rates supported.
2634 +        */
2635 +       priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
2636 +       lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
2637 +
2638 +out:
2639 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
2640 +       return ret;
2641  }
2642  
2643 -static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
2644 -                                     struct cmd_ds_command *cmd,
2645 -                                     u16 cmd_action)
2646 +/**
2647 + *  @brief Get the radio channel
2648 + *
2649 + *  @param priv        A pointer to struct lbs_private structure
2650 + *
2651 + *  @return            The channel on success, error on failure
2652 + */
2653 +int lbs_get_channel(struct lbs_private *priv)
2654  {
2655 -       struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
2656 -       wlan_adapter *adapter = priv->adapter;
2657 +       struct cmd_ds_802_11_rf_channel cmd;
2658 +       int ret = 0;
2659  
2660 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
2661 -                            S_DS_GEN);
2662 -       cmd->command = cpu_to_le16(cmd_mac_multicast_adr);
2663 +       lbs_deb_enter(LBS_DEB_CMD);
2664  
2665 -       pMCastAdr->action = cpu_to_le16(cmd_action);
2666 -       pMCastAdr->nr_of_adrs =
2667 -           cpu_to_le16((u16) adapter->nr_of_multicastmacaddr);
2668 -       memcpy(pMCastAdr->maclist, adapter->multicastlist,
2669 -              adapter->nr_of_multicastmacaddr * ETH_ALEN);
2670 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2671 +       cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
2672  
2673 -       return 0;
2674 +       ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
2675 +       if (ret)
2676 +               goto out;
2677 +
2678 +       ret = le16_to_cpu(cmd.channel);
2679 +       lbs_deb_cmd("current radio channel is %d\n", ret);
2680 +
2681 +out:
2682 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
2683 +       return ret;
2684  }
2685  
2686 -static int wlan_cmd_802_11_rf_channel(wlan_private * priv,
2687 -                                     struct cmd_ds_command *cmd,
2688 -                                     int option, void *pdata_buf)
2689 +/**
2690 + *  @brief Set the radio channel
2691 + *
2692 + *  @param priv        A pointer to struct lbs_private structure
2693 + *  @param channel     The desired channel, or 0 to clear a locked channel
2694 + *
2695 + *  @return            0 on success, error on failure
2696 + */
2697 +int lbs_set_channel(struct lbs_private *priv, u8 channel)
2698  {
2699 -       struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel;
2700 -
2701 -       cmd->command = cpu_to_le16(cmd_802_11_rf_channel);
2702 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) +
2703 -                               S_DS_GEN);
2704 +       struct cmd_ds_802_11_rf_channel cmd;
2705 +       u8 old_channel = priv->curbssparams.channel;
2706 +       int ret = 0;
2707  
2708 -       if (option == cmd_opt_802_11_rf_channel_set) {
2709 -               rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf));
2710 -       }
2711 +       lbs_deb_enter(LBS_DEB_CMD);
2712  
2713 -       rfchan->action = cpu_to_le16(option);
2714 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2715 +       cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
2716 +       cmd.channel = cpu_to_le16(channel);
2717 +
2718 +       ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
2719 +       if (ret)
2720 +               goto out;
2721 +
2722 +       priv->curbssparams.channel = (uint8_t) le16_to_cpu(cmd.channel);
2723 +       lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
2724 +               priv->curbssparams.channel);
2725  
2726 -       return 0;
2727 +out:
2728 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
2729 +       return ret;
2730  }
2731  
2732 -static int wlan_cmd_802_11_rssi(wlan_private * priv,
2733 +static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
2734                                 struct cmd_ds_command *cmd)
2735  {
2736 -       wlan_adapter *adapter = priv->adapter;
2737  
2738 -       cmd->command = cpu_to_le16(cmd_802_11_rssi);
2739 +       lbs_deb_enter(LBS_DEB_CMD);
2740 +       cmd->command = cpu_to_le16(CMD_802_11_RSSI);
2741         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
2742 -       cmd->params.rssi.N = cpu_to_le16(priv->adapter->bcn_avg_factor);
2743 +       cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
2744  
2745         /* reset Beacon SNR/NF/RSSI values */
2746 -       adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
2747 -       adapter->SNR[TYPE_BEACON][TYPE_AVG] = 0;
2748 -       adapter->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
2749 -       adapter->NF[TYPE_BEACON][TYPE_AVG] = 0;
2750 -       adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
2751 -       adapter->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
2752 +       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
2753 +       priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
2754 +       priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
2755 +       priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
2756 +       priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
2757 +       priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
2758  
2759 +       lbs_deb_leave(LBS_DEB_CMD);
2760         return 0;
2761  }
2762  
2763 -static int wlan_cmd_reg_access(wlan_private * priv,
2764 +static int lbs_cmd_reg_access(struct lbs_private *priv,
2765                                struct cmd_ds_command *cmdptr,
2766                                u8 cmd_action, void *pdata_buf)
2767  {
2768 -       struct wlan_offset_value *offval;
2769 +       struct lbs_offset_value *offval;
2770  
2771         lbs_deb_enter(LBS_DEB_CMD);
2772  
2773 -       offval = (struct wlan_offset_value *)pdata_buf;
2774 +       offval = (struct lbs_offset_value *)pdata_buf;
2775  
2776 -       switch (cmdptr->command) {
2777 -       case cmd_mac_reg_access:
2778 +       switch (le16_to_cpu(cmdptr->command)) {
2779 +       case CMD_MAC_REG_ACCESS:
2780                 {
2781                         struct cmd_ds_mac_reg_access *macreg;
2782  
2783 @@ -713,7 +962,7 @@ static int wlan_cmd_reg_access(wlan_priv
2784                         break;
2785                 }
2786  
2787 -       case cmd_bbp_reg_access:
2788 +       case CMD_BBP_REG_ACCESS:
2789                 {
2790                         struct cmd_ds_bbp_reg_access *bbpreg;
2791  
2792 @@ -732,7 +981,7 @@ static int wlan_cmd_reg_access(wlan_priv
2793                         break;
2794                 }
2795  
2796 -       case cmd_rf_reg_access:
2797 +       case CMD_RF_REG_ACCESS:
2798                 {
2799                         struct cmd_ds_rf_reg_access *rfreg;
2800  
2801 @@ -759,37 +1008,38 @@ static int wlan_cmd_reg_access(wlan_priv
2802         return 0;
2803  }
2804  
2805 -static int wlan_cmd_802_11_mac_address(wlan_private * priv,
2806 +static int lbs_cmd_802_11_mac_address(struct lbs_private *priv,
2807                                        struct cmd_ds_command *cmd,
2808                                        u16 cmd_action)
2809  {
2810 -       wlan_adapter *adapter = priv->adapter;
2811  
2812 -       cmd->command = cpu_to_le16(cmd_802_11_mac_address);
2813 +       lbs_deb_enter(LBS_DEB_CMD);
2814 +       cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS);
2815         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
2816                              S_DS_GEN);
2817         cmd->result = 0;
2818  
2819         cmd->params.macadd.action = cpu_to_le16(cmd_action);
2820  
2821 -       if (cmd_action == cmd_act_set) {
2822 +       if (cmd_action == CMD_ACT_SET) {
2823                 memcpy(cmd->params.macadd.macadd,
2824 -                      adapter->current_addr, ETH_ALEN);
2825 -               lbs_dbg_hex("SET_CMD: MAC ADDRESS-", adapter->current_addr, 6);
2826 +                      priv->current_addr, ETH_ALEN);
2827 +               lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", priv->current_addr, 6);
2828         }
2829  
2830 +       lbs_deb_leave(LBS_DEB_CMD);
2831         return 0;
2832  }
2833  
2834 -static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
2835 +static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv,
2836                                          struct cmd_ds_command *cmd,
2837                                          int cmd_action, void *pdata_buf)
2838  {
2839 -       struct wlan_ioctl_regrdwr *ea = pdata_buf;
2840 +       struct lbs_ioctl_regrdwr *ea = pdata_buf;
2841  
2842         lbs_deb_enter(LBS_DEB_CMD);
2843  
2844 -       cmd->command = cpu_to_le16(cmd_802_11_eeprom_access);
2845 +       cmd->command = cpu_to_le16(CMD_802_11_EEPROM_ACCESS);
2846         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
2847                                 S_DS_GEN);
2848         cmd->result = 0;
2849 @@ -799,54 +1049,56 @@ static int wlan_cmd_802_11_eeprom_access
2850         cmd->params.rdeeprom.bytecount = cpu_to_le16(ea->NOB);
2851         cmd->params.rdeeprom.value = 0;
2852  
2853 +       lbs_deb_leave(LBS_DEB_CMD);
2854         return 0;
2855  }
2856  
2857 -static int wlan_cmd_bt_access(wlan_private * priv,
2858 +static int lbs_cmd_bt_access(struct lbs_private *priv,
2859                                struct cmd_ds_command *cmd,
2860                                u16 cmd_action, void *pdata_buf)
2861  {
2862         struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
2863 -       lbs_deb_cmd("BT CMD(%d)\n", cmd_action);
2864 +       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
2865  
2866 -       cmd->command = cpu_to_le16(cmd_bt_access);
2867 +       cmd->command = cpu_to_le16(CMD_BT_ACCESS);
2868         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN);
2869         cmd->result = 0;
2870         bt_access->action = cpu_to_le16(cmd_action);
2871  
2872         switch (cmd_action) {
2873 -       case cmd_act_bt_access_add:
2874 +       case CMD_ACT_BT_ACCESS_ADD:
2875                 memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
2876 -               lbs_dbg_hex("BT_ADD: blinded mac address-", bt_access->addr1, 6);
2877 +               lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", bt_access->addr1, 6);
2878                 break;
2879 -       case cmd_act_bt_access_del:
2880 +       case CMD_ACT_BT_ACCESS_DEL:
2881                 memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
2882 -               lbs_dbg_hex("BT_DEL: blinded mac address-", bt_access->addr1, 6);
2883 +               lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", bt_access->addr1, 6);
2884                 break;
2885 -       case cmd_act_bt_access_list:
2886 +       case CMD_ACT_BT_ACCESS_LIST:
2887                 bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
2888                 break;
2889 -       case cmd_act_bt_access_reset:
2890 +       case CMD_ACT_BT_ACCESS_RESET:
2891                 break;
2892 -       case cmd_act_bt_access_set_invert:
2893 +       case CMD_ACT_BT_ACCESS_SET_INVERT:
2894                 bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
2895                 break;
2896 -       case cmd_act_bt_access_get_invert:
2897 +       case CMD_ACT_BT_ACCESS_GET_INVERT:
2898                 break;
2899         default:
2900                 break;
2901         }
2902 +       lbs_deb_leave(LBS_DEB_CMD);
2903         return 0;
2904  }
2905  
2906 -static int wlan_cmd_fwt_access(wlan_private * priv,
2907 +static int lbs_cmd_fwt_access(struct lbs_private *priv,
2908                                struct cmd_ds_command *cmd,
2909                                u16 cmd_action, void *pdata_buf)
2910  {
2911         struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
2912 -       lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
2913 +       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
2914  
2915 -       cmd->command = cpu_to_le16(cmd_fwt_access);
2916 +       cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
2917         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN);
2918         cmd->result = 0;
2919  
2920 @@ -857,244 +1109,290 @@ static int wlan_cmd_fwt_access(wlan_priv
2921  
2922         fwt_access->action = cpu_to_le16(cmd_action);
2923  
2924 +       lbs_deb_leave(LBS_DEB_CMD);
2925         return 0;
2926  }
2927  
2928 -static int wlan_cmd_mesh_access(wlan_private * priv,
2929 -                               struct cmd_ds_command *cmd,
2930 -                               u16 cmd_action, void *pdata_buf)
2931 +int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
2932 +                   struct cmd_ds_mesh_access *cmd)
2933  {
2934 -       struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
2935 -       lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
2936 +       int ret;
2937  
2938 -       cmd->command = cpu_to_le16(cmd_mesh_access);
2939 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
2940 -       cmd->result = 0;
2941 +       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
2942  
2943 -       if (pdata_buf)
2944 -               memcpy(mesh_access, pdata_buf, sizeof(*mesh_access));
2945 -       else
2946 -               memset(mesh_access, 0, sizeof(*mesh_access));
2947 +       cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
2948 +       cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
2949 +       cmd->hdr.result = 0;
2950  
2951 -       mesh_access->action = cpu_to_le16(cmd_action);
2952 +       cmd->action = cpu_to_le16(cmd_action);
2953  
2954 -       return 0;
2955 +       ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
2956 +
2957 +       lbs_deb_leave(LBS_DEB_CMD);
2958 +       return ret;
2959  }
2960 +EXPORT_SYMBOL_GPL(lbs_mesh_access);
2961  
2962 -void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
2963 +int lbs_mesh_config_send(struct lbs_private *priv,
2964 +                        struct cmd_ds_mesh_config *cmd,
2965 +                        uint16_t action, uint16_t type)
2966  {
2967 -       unsigned long flags;
2968 -       struct cmd_ds_command *cmdptr;
2969 +       int ret;
2970  
2971         lbs_deb_enter(LBS_DEB_CMD);
2972  
2973 -       if (!cmdnode) {
2974 -               lbs_deb_cmd("QUEUE_CMD: cmdnode is NULL\n");
2975 -               goto done;
2976 -       }
2977 +       cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
2978 +       cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
2979 +       cmd->hdr.result = 0;
2980  
2981 -       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
2982 -       if (!cmdptr) {
2983 -               lbs_deb_cmd("QUEUE_CMD: cmdptr is NULL\n");
2984 -               goto done;
2985 -       }
2986 +       cmd->type = cpu_to_le16(type);
2987 +       cmd->action = cpu_to_le16(action);
2988  
2989 -       /* Exit_PS command needs to be queued in the header always. */
2990 -       if (cmdptr->command == cmd_802_11_ps_mode) {
2991 -               struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
2992 -               if (psm->action == cpu_to_le16(cmd_subcmd_exit_ps)) {
2993 -                       if (adapter->psstate != PS_STATE_FULL_POWER)
2994 -                               addtail = 0;
2995 -               }
2996 +       ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
2997 +
2998 +       lbs_deb_leave(LBS_DEB_CMD);
2999 +       return ret;
3000 +}
3001 +
3002 +/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
3003 + * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
3004 + * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
3005 + * lbs_mesh_config_send.
3006 + */
3007 +int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
3008 +{
3009 +       struct cmd_ds_mesh_config cmd;
3010 +       struct mrvl_meshie *ie;
3011 +
3012 +       memset(&cmd, 0, sizeof(cmd));
3013 +       cmd.channel = cpu_to_le16(chan);
3014 +       ie = (struct mrvl_meshie *)cmd.data;
3015 +
3016 +       switch (action) {
3017 +       case CMD_ACT_MESH_CONFIG_START:
3018 +               ie->hdr.id = MFIE_TYPE_GENERIC;
3019 +               ie->val.oui[0] = 0x00;
3020 +               ie->val.oui[1] = 0x50;
3021 +               ie->val.oui[2] = 0x43;
3022 +               ie->val.type = MARVELL_MESH_IE_TYPE;
3023 +               ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
3024 +               ie->val.version = MARVELL_MESH_IE_VERSION;
3025 +               ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
3026 +               ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
3027 +               ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
3028 +               ie->val.mesh_id_len = priv->mesh_ssid_len;
3029 +               memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
3030 +               ie->hdr.len = sizeof(struct mrvl_meshie_val) -
3031 +                       IW_ESSID_MAX_SIZE + priv->mesh_ssid_len;
3032 +               cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
3033 +               break;
3034 +       case CMD_ACT_MESH_CONFIG_STOP:
3035 +               break;
3036 +       default:
3037 +               return -1;
3038         }
3039 +       lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
3040 +                   action, priv->mesh_tlv, chan,
3041 +                   escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
3042  
3043 -       spin_lock_irqsave(&adapter->driver_lock, flags);
3044 +       return lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
3045 +}
3046  
3047 -       if (addtail)
3048 -               list_add_tail((struct list_head *)cmdnode,
3049 -                             &adapter->cmdpendingq);
3050 -       else
3051 -               list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
3052 +static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
3053 +                               struct cmd_ds_command *cmd,
3054 +                               u16 cmd_action)
3055 +{
3056 +       struct cmd_ds_802_11_beacon_control
3057 +               *bcn_ctrl = &cmd->params.bcn_ctrl;
3058  
3059 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
3060 +       lbs_deb_enter(LBS_DEB_CMD);
3061 +       cmd->size =
3062 +           cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
3063 +                            + S_DS_GEN);
3064 +       cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
3065  
3066 -       lbs_deb_cmd("QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
3067 -              cmdnode,
3068 -              le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command));
3069 +       bcn_ctrl->action = cpu_to_le16(cmd_action);
3070 +       bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
3071 +       bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
3072  
3073 -done:
3074         lbs_deb_leave(LBS_DEB_CMD);
3075 +       return 0;
3076  }
3077  
3078 -/*
3079 - * TODO: Fix the issue when DownloadcommandToStation is being called the
3080 - * second time when the command timesout. All the cmdptr->xxx are in little
3081 - * endian and therefore all the comparissions will fail.
3082 - * For now - we are not performing the endian conversion the second time - but
3083 - * for PS and DEEP_SLEEP we need to worry
3084 - */
3085 -static int DownloadcommandToStation(wlan_private * priv,
3086 -                                   struct cmd_ctrl_node *cmdnode)
3087 +static void lbs_queue_cmd(struct lbs_private *priv,
3088 +                         struct cmd_ctrl_node *cmdnode)
3089  {
3090         unsigned long flags;
3091 -       struct cmd_ds_command *cmdptr;
3092 -       wlan_adapter *adapter = priv->adapter;
3093 -       int ret = 0;
3094 -       u16 cmdsize;
3095 -       u16 command;
3096 +       int addtail = 1;
3097  
3098 -       lbs_deb_enter(LBS_DEB_CMD);
3099 +       lbs_deb_enter(LBS_DEB_HOST);
3100  
3101 -       if (!adapter || !cmdnode) {
3102 -               lbs_deb_cmd("DNLD_CMD: adapter = %p, cmdnode = %p\n",
3103 -                      adapter, cmdnode);
3104 -               if (cmdnode) {
3105 -                       spin_lock_irqsave(&adapter->driver_lock, flags);
3106 -                       __libertas_cleanup_and_insert_cmd(priv, cmdnode);
3107 -                       spin_unlock_irqrestore(&adapter->driver_lock, flags);
3108 -               }
3109 -               ret = -1;
3110 +       if (!cmdnode) {
3111 +               lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
3112                 goto done;
3113         }
3114 -
3115 -       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
3116 -
3117 -
3118 -       spin_lock_irqsave(&adapter->driver_lock, flags);
3119 -       if (!cmdptr || !cmdptr->size) {
3120 -               lbs_deb_cmd("DNLD_CMD: cmdptr is Null or cmd size is Zero, "
3121 -                      "Not sending\n");
3122 -               __libertas_cleanup_and_insert_cmd(priv, cmdnode);
3123 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
3124 -               ret = -1;
3125 +       if (!cmdnode->cmdbuf->size) {
3126 +               lbs_deb_host("DNLD_CMD: cmd size is zero\n");
3127                 goto done;
3128         }
3129 +       cmdnode->result = 0;
3130  
3131 -       adapter->cur_cmd = cmdnode;
3132 -       adapter->cur_cmd_retcode = 0;
3133 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
3134 -       lbs_deb_cmd("DNLD_CMD:: Before download, size of cmd = %d\n",
3135 -                   le16_to_cpu(cmdptr->size));
3136 -
3137 -       cmdsize = cmdptr->size;
3138 -
3139 -       command = cpu_to_le16(cmdptr->command);
3140 -
3141 -       cmdnode->cmdwaitqwoken = 0;
3142 -       cmdsize = cpu_to_le16(cmdsize);
3143 -
3144 -       ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
3145 +       /* Exit_PS command needs to be queued in the header always. */
3146 +       if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
3147 +               struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
3148  
3149 -       if (ret != 0) {
3150 -               lbs_deb_cmd("DNLD_CMD: Host to Card failed\n");
3151 -               spin_lock_irqsave(&adapter->driver_lock, flags);
3152 -               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
3153 -               adapter->cur_cmd = NULL;
3154 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
3155 -               ret = -1;
3156 -               goto done;
3157 +               if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
3158 +                       if (priv->psstate != PS_STATE_FULL_POWER)
3159 +                               addtail = 0;
3160 +               }
3161         }
3162  
3163 -       lbs_deb_cmd("DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
3164 -       lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize);
3165 +       spin_lock_irqsave(&priv->driver_lock, flags);
3166  
3167 -       /* Setup the timer after transmit command */
3168 -       if (command == cmd_802_11_scan || command == cmd_802_11_authenticate
3169 -           || command == cmd_802_11_associate)
3170 -               mod_timer(&adapter->command_timer, jiffies + (10*HZ));
3171 +       if (addtail)
3172 +               list_add_tail(&cmdnode->list, &priv->cmdpendingq);
3173         else
3174 -               mod_timer(&adapter->command_timer, jiffies + (5*HZ));
3175 +               list_add(&cmdnode->list, &priv->cmdpendingq);
3176  
3177 -       ret = 0;
3178 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
3179 +
3180 +       lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
3181 +                    le16_to_cpu(cmdnode->cmdbuf->command));
3182  
3183  done:
3184 -       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
3185 -       return ret;
3186 +       lbs_deb_leave(LBS_DEB_HOST);
3187  }
3188  
3189 -static int wlan_cmd_mac_control(wlan_private * priv,
3190 -                               struct cmd_ds_command *cmd)
3191 +static void lbs_submit_command(struct lbs_private *priv,
3192 +                              struct cmd_ctrl_node *cmdnode)
3193  {
3194 -       struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
3195 +       unsigned long flags;
3196 +       struct cmd_header *cmd;
3197 +       uint16_t cmdsize;
3198 +       uint16_t command;
3199 +       int timeo = 5 * HZ;
3200 +       int ret;
3201 +
3202 +       lbs_deb_enter(LBS_DEB_HOST);
3203 +
3204 +       cmd = cmdnode->cmdbuf;
3205 +
3206 +       spin_lock_irqsave(&priv->driver_lock, flags);
3207 +       priv->cur_cmd = cmdnode;
3208 +       priv->cur_cmd_retcode = 0;
3209 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
3210 +
3211 +       cmdsize = le16_to_cpu(cmd->size);
3212 +       command = le16_to_cpu(cmd->command);
3213 +
3214 +       /* These commands take longer */
3215 +       if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
3216 +           command == CMD_802_11_AUTHENTICATE)
3217 +               timeo = 10 * HZ;
3218 +
3219 +       lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n",
3220 +                    command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
3221 +       lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
3222  
3223 -       lbs_deb_enter(LBS_DEB_CMD);
3224 +       ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
3225  
3226 -       cmd->command = cpu_to_le16(cmd_mac_control);
3227 -       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
3228 -       mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);
3229 +       if (ret) {
3230 +               lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
3231 +               /* Let the timer kick in and retry, and potentially reset
3232 +                  the whole thing if the condition persists */
3233 +               timeo = HZ;
3234 +       }
3235  
3236 -       lbs_deb_cmd("wlan_cmd_mac_control(): action=0x%X size=%d\n",
3237 -                   le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
3238 +       /* Setup the timer after transmit command */
3239 +       mod_timer(&priv->command_timer, jiffies + timeo);
3240  
3241 -       lbs_deb_leave(LBS_DEB_CMD);
3242 -       return 0;
3243 +       lbs_deb_leave(LBS_DEB_HOST);
3244  }
3245  
3246  /**
3247   *  This function inserts command node to cmdfreeq
3248 - *  after cleans it. Requires adapter->driver_lock held.
3249 + *  after cleans it. Requires priv->driver_lock held.
3250   */
3251 -void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
3252 +static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
3253 +                                        struct cmd_ctrl_node *cmdnode)
3254  {
3255 -       wlan_adapter *adapter = priv->adapter;
3256 +       lbs_deb_enter(LBS_DEB_HOST);
3257  
3258 -       if (!ptempcmd)
3259 -               goto done;
3260 +       if (!cmdnode)
3261 +               goto out;
3262  
3263 -       cleanup_cmdnode(ptempcmd);
3264 -       list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq);
3265 -done:
3266 -       return;
3267 +       cmdnode->callback = NULL;
3268 +       cmdnode->callback_arg = 0;
3269 +
3270 +       memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
3271 +
3272 +       list_add_tail(&cmdnode->list, &priv->cmdfreeq);
3273 + out:
3274 +       lbs_deb_leave(LBS_DEB_HOST);
3275  }
3276  
3277 -void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
3278 +static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
3279 +       struct cmd_ctrl_node *ptempcmd)
3280  {
3281         unsigned long flags;
3282  
3283 -       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
3284 -       __libertas_cleanup_and_insert_cmd(priv, ptempcmd);
3285 -       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
3286 +       spin_lock_irqsave(&priv->driver_lock, flags);
3287 +       __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
3288 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
3289 +}
3290 +
3291 +void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
3292 +                         int result)
3293 +{
3294 +       if (cmd == priv->cur_cmd)
3295 +               priv->cur_cmd_retcode = result;
3296 +
3297 +       cmd->result = result;
3298 +       cmd->cmdwaitqwoken = 1;
3299 +       wake_up_interruptible(&cmd->cmdwait_q);
3300 +
3301 +       if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
3302 +               __lbs_cleanup_and_insert_cmd(priv, cmd);
3303 +       priv->cur_cmd = NULL;
3304  }
3305  
3306 -int libertas_set_radio_control(wlan_private * priv)
3307 +int lbs_set_radio_control(struct lbs_private *priv)
3308  {
3309         int ret = 0;
3310  
3311         lbs_deb_enter(LBS_DEB_CMD);
3312  
3313 -       ret = libertas_prepare_and_send_command(priv,
3314 -                                   cmd_802_11_radio_control,
3315 -                                   cmd_act_set,
3316 -                                   cmd_option_waitforrsp, 0, NULL);
3317 +       ret = lbs_prepare_and_send_command(priv,
3318 +                                   CMD_802_11_RADIO_CONTROL,
3319 +                                   CMD_ACT_SET,
3320 +                                   CMD_OPTION_WAITFORRSP, 0, NULL);
3321  
3322 -       lbs_deb_cmd("RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
3323 -              priv->adapter->radioon, priv->adapter->preamble);
3324 +       lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n",
3325 +              priv->radioon, priv->preamble);
3326  
3327         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
3328         return ret;
3329  }
3330  
3331 -int libertas_set_mac_packet_filter(wlan_private * priv)
3332 +void lbs_set_mac_control(struct lbs_private *priv)
3333  {
3334 -       int ret = 0;
3335 +       struct cmd_ds_mac_control cmd;
3336  
3337         lbs_deb_enter(LBS_DEB_CMD);
3338  
3339 -       lbs_deb_cmd("libertas_set_mac_packet_filter value = %x\n",
3340 -              priv->adapter->currentpacketfilter);
3341 +       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
3342 +       cmd.action = cpu_to_le16(priv->mac_control);
3343 +       cmd.reserved = 0;
3344  
3345 -       /* Send MAC control command to station */
3346 -       ret = libertas_prepare_and_send_command(priv,
3347 -                                   cmd_mac_control, 0, 0, 0, NULL);
3348 +       lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
3349  
3350 -       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
3351 -       return ret;
3352 +       lbs_deb_leave(LBS_DEB_CMD);
3353  }
3354  
3355  /**
3356   *  @brief This function prepare the command before send to firmware.
3357   *
3358 - *  @param priv                A pointer to wlan_private structure
3359 + *  @param priv                A pointer to struct lbs_private structure
3360   *  @param cmd_no      command number
3361   *  @param cmd_action  command action: GET or SET
3362   *  @param wait_option wait option: wait response or not
3363 @@ -1102,194 +1400,166 @@ int libertas_set_mac_packet_filter(wlan_
3364   *  @param pdata_buf   A pointer to informaion buffer
3365   *  @return            0 or -1
3366   */
3367 -int libertas_prepare_and_send_command(wlan_private * priv,
3368 +int lbs_prepare_and_send_command(struct lbs_private *priv,
3369                           u16 cmd_no,
3370                           u16 cmd_action,
3371                           u16 wait_option, u32 cmd_oid, void *pdata_buf)
3372  {
3373         int ret = 0;
3374 -       wlan_adapter *adapter = priv->adapter;
3375         struct cmd_ctrl_node *cmdnode;
3376         struct cmd_ds_command *cmdptr;
3377         unsigned long flags;
3378  
3379 -       lbs_deb_enter(LBS_DEB_CMD);
3380 +       lbs_deb_enter(LBS_DEB_HOST);
3381  
3382 -       if (!adapter) {
3383 -               lbs_deb_cmd("PREP_CMD: adapter is Null\n");
3384 +       if (!priv) {
3385 +               lbs_deb_host("PREP_CMD: priv is NULL\n");
3386                 ret = -1;
3387                 goto done;
3388         }
3389  
3390 -       if (adapter->surpriseremoved) {
3391 -               lbs_deb_cmd("PREP_CMD: Card is Removed\n");
3392 +       if (priv->surpriseremoved) {
3393 +               lbs_deb_host("PREP_CMD: card removed\n");
3394                 ret = -1;
3395                 goto done;
3396         }
3397  
3398 -       cmdnode = libertas_get_free_cmd_ctrl_node(priv);
3399 +       cmdnode = lbs_get_cmd_ctrl_node(priv);
3400  
3401         if (cmdnode == NULL) {
3402 -               lbs_deb_cmd("PREP_CMD: No free cmdnode\n");
3403 +               lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
3404  
3405                 /* Wake up main thread to execute next command */
3406 -               wake_up_interruptible(&priv->mainthread.waitq);
3407 +               wake_up_interruptible(&priv->waitq);
3408                 ret = -1;
3409                 goto done;
3410         }
3411  
3412 -       libertas_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf);
3413 +       lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
3414  
3415 -       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
3416 +       cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
3417  
3418 -       lbs_deb_cmd("PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
3419 -              cmdptr, cmd_no);
3420 -
3421 -       if (!cmdptr) {
3422 -               lbs_deb_cmd("PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
3423 -               libertas_cleanup_and_insert_cmd(priv, cmdnode);
3424 -               ret = -1;
3425 -               goto done;
3426 -       }
3427 +       lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
3428  
3429         /* Set sequence number, command and INT option */
3430 -       adapter->seqnum++;
3431 -       cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
3432 +       priv->seqnum++;
3433 +       cmdptr->seqnum = cpu_to_le16(priv->seqnum);
3434  
3435         cmdptr->command = cpu_to_le16(cmd_no);
3436         cmdptr->result = 0;
3437  
3438         switch (cmd_no) {
3439 -       case cmd_get_hw_spec:
3440 -               ret = wlan_cmd_hw_spec(priv, cmdptr);
3441 -               break;
3442 -       case cmd_802_11_ps_mode:
3443 -               ret = wlan_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
3444 +       case CMD_802_11_PS_MODE:
3445 +               ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
3446                 break;
3447  
3448 -       case cmd_802_11_scan:
3449 -               ret = libertas_cmd_80211_scan(priv, cmdptr, pdata_buf);
3450 +       case CMD_802_11_SCAN:
3451 +               ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf);
3452                 break;
3453  
3454 -       case cmd_mac_control:
3455 -               ret = wlan_cmd_mac_control(priv, cmdptr);
3456 +       case CMD_802_11_ASSOCIATE:
3457 +       case CMD_802_11_REASSOCIATE:
3458 +               ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
3459                 break;
3460  
3461 -       case cmd_802_11_associate:
3462 -       case cmd_802_11_reassociate:
3463 -               ret = libertas_cmd_80211_associate(priv, cmdptr, pdata_buf);
3464 +       case CMD_802_11_DEAUTHENTICATE:
3465 +               ret = lbs_cmd_80211_deauthenticate(priv, cmdptr);
3466                 break;
3467  
3468 -       case cmd_802_11_deauthenticate:
3469 -               ret = libertas_cmd_80211_deauthenticate(priv, cmdptr);
3470 +       case CMD_802_11_SET_WEP:
3471 +               ret = lbs_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf);
3472                 break;
3473  
3474 -       case cmd_802_11_set_wep:
3475 -               ret = wlan_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf);
3476 +       case CMD_802_11_AD_HOC_START:
3477 +               ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
3478                 break;
3479 -
3480 -       case cmd_802_11_ad_hoc_start:
3481 -               ret = libertas_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
3482 -               break;
3483 -       case cmd_code_dnld:
3484 +       case CMD_CODE_DNLD:
3485                 break;
3486  
3487 -       case cmd_802_11_reset:
3488 -               ret = wlan_cmd_802_11_reset(priv, cmdptr, cmd_action);
3489 +       case CMD_802_11_RESET:
3490 +               ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action);
3491                 break;
3492  
3493 -       case cmd_802_11_get_log:
3494 -               ret = wlan_cmd_802_11_get_log(priv, cmdptr);
3495 +       case CMD_802_11_GET_LOG:
3496 +               ret = lbs_cmd_802_11_get_log(priv, cmdptr);
3497                 break;
3498  
3499 -       case cmd_802_11_authenticate:
3500 -               ret = libertas_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
3501 +       case CMD_802_11_AUTHENTICATE:
3502 +               ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
3503                 break;
3504  
3505 -       case cmd_802_11_get_stat:
3506 -               ret = wlan_cmd_802_11_get_stat(priv, cmdptr);
3507 +       case CMD_802_11_GET_STAT:
3508 +               ret = lbs_cmd_802_11_get_stat(priv, cmdptr);
3509                 break;
3510  
3511 -       case cmd_802_11_snmp_mib:
3512 -               ret = wlan_cmd_802_11_snmp_mib(priv, cmdptr,
3513 +       case CMD_802_11_SNMP_MIB:
3514 +               ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr,
3515                                                cmd_action, cmd_oid, pdata_buf);
3516                 break;
3517  
3518 -       case cmd_mac_reg_access:
3519 -       case cmd_bbp_reg_access:
3520 -       case cmd_rf_reg_access:
3521 -               ret = wlan_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
3522 -               break;
3523 -
3524 -       case cmd_802_11_rf_channel:
3525 -               ret = wlan_cmd_802_11_rf_channel(priv, cmdptr,
3526 -                                                cmd_action, pdata_buf);
3527 +       case CMD_MAC_REG_ACCESS:
3528 +       case CMD_BBP_REG_ACCESS:
3529 +       case CMD_RF_REG_ACCESS:
3530 +               ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
3531                 break;
3532  
3533 -       case cmd_802_11_rf_tx_power:
3534 -               ret = wlan_cmd_802_11_rf_tx_power(priv, cmdptr,
3535 +       case CMD_802_11_RF_TX_POWER:
3536 +               ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr,
3537                                                   cmd_action, pdata_buf);
3538                 break;
3539  
3540 -       case cmd_802_11_radio_control:
3541 -               ret = wlan_cmd_802_11_radio_control(priv, cmdptr, cmd_action);
3542 -               break;
3543 -
3544 -       case cmd_802_11_rf_antenna:
3545 -               ret = wlan_cmd_802_11_rf_antenna(priv, cmdptr,
3546 -                                                cmd_action, pdata_buf);
3547 +       case CMD_802_11_RADIO_CONTROL:
3548 +               ret = lbs_cmd_802_11_radio_control(priv, cmdptr, cmd_action);
3549                 break;
3550  
3551 -       case cmd_802_11_data_rate:
3552 -               ret = wlan_cmd_802_11_data_rate(priv, cmdptr, cmd_action);
3553 -               break;
3554 -       case cmd_802_11_rate_adapt_rateset:
3555 -               ret = wlan_cmd_802_11_rate_adapt_rateset(priv,
3556 +       case CMD_802_11_RATE_ADAPT_RATESET:
3557 +               ret = lbs_cmd_802_11_rate_adapt_rateset(priv,
3558                                                          cmdptr, cmd_action);
3559                 break;
3560  
3561 -       case cmd_mac_multicast_adr:
3562 -               ret = wlan_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
3563 +       case CMD_802_11_MONITOR_MODE:
3564 +               ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr,
3565 +                                         cmd_action, pdata_buf);
3566                 break;
3567  
3568 -       case cmd_802_11_ad_hoc_join:
3569 -               ret = libertas_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
3570 +       case CMD_802_11_AD_HOC_JOIN:
3571 +               ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
3572                 break;
3573  
3574 -       case cmd_802_11_rssi:
3575 -               ret = wlan_cmd_802_11_rssi(priv, cmdptr);
3576 +       case CMD_802_11_RSSI:
3577 +               ret = lbs_cmd_802_11_rssi(priv, cmdptr);
3578                 break;
3579  
3580 -       case cmd_802_11_ad_hoc_stop:
3581 -               ret = libertas_cmd_80211_ad_hoc_stop(priv, cmdptr);
3582 +       case CMD_802_11_AD_HOC_STOP:
3583 +               ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
3584                 break;
3585  
3586 -       case cmd_802_11_enable_rsn:
3587 -               ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
3588 +       case CMD_802_11_ENABLE_RSN:
3589 +               ret = lbs_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
3590                                 pdata_buf);
3591                 break;
3592  
3593 -       case cmd_802_11_key_material:
3594 -               ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action,
3595 +       case CMD_802_11_KEY_MATERIAL:
3596 +               ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action,
3597                                 cmd_oid, pdata_buf);
3598                 break;
3599  
3600 -       case cmd_802_11_pairwise_tsc:
3601 +       case CMD_802_11_PAIRWISE_TSC:
3602                 break;
3603 -       case cmd_802_11_group_tsc:
3604 +       case CMD_802_11_GROUP_TSC:
3605                 break;
3606  
3607 -       case cmd_802_11_mac_address:
3608 -               ret = wlan_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
3609 +       case CMD_802_11_MAC_ADDRESS:
3610 +               ret = lbs_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
3611                 break;
3612  
3613 -       case cmd_802_11_eeprom_access:
3614 -               ret = wlan_cmd_802_11_eeprom_access(priv, cmdptr,
3615 +       case CMD_802_11_EEPROM_ACCESS:
3616 +               ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr,
3617                                                     cmd_action, pdata_buf);
3618                 break;
3619  
3620 -       case cmd_802_11_set_afc:
3621 -       case cmd_802_11_get_afc:
3622 +       case CMD_802_11_SET_AFC:
3623 +       case CMD_802_11_GET_AFC:
3624  
3625                 cmdptr->command = cpu_to_le16(cmd_no);
3626                 cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
3627 @@ -1301,22 +1571,22 @@ int libertas_prepare_and_send_command(wl
3628                 ret = 0;
3629                 goto done;
3630  
3631 -       case cmd_802_11d_domain_info:
3632 -               ret = libertas_cmd_802_11d_domain_info(priv, cmdptr,
3633 +       case CMD_802_11D_DOMAIN_INFO:
3634 +               ret = lbs_cmd_802_11d_domain_info(priv, cmdptr,
3635                                                    cmd_no, cmd_action);
3636                 break;
3637  
3638 -       case cmd_802_11_sleep_params:
3639 -               ret = wlan_cmd_802_11_sleep_params(priv, cmdptr, cmd_action);
3640 +       case CMD_802_11_SLEEP_PARAMS:
3641 +               ret = lbs_cmd_802_11_sleep_params(priv, cmdptr, cmd_action);
3642                 break;
3643 -       case cmd_802_11_inactivity_timeout:
3644 -               ret = wlan_cmd_802_11_inactivity_timeout(priv, cmdptr,
3645 +       case CMD_802_11_INACTIVITY_TIMEOUT:
3646 +               ret = lbs_cmd_802_11_inactivity_timeout(priv, cmdptr,
3647                                                          cmd_action, pdata_buf);
3648 -               libertas_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf);
3649 +               lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
3650                 break;
3651  
3652 -       case cmd_802_11_tpc_cfg:
3653 -               cmdptr->command = cpu_to_le16(cmd_802_11_tpc_cfg);
3654 +       case CMD_802_11_TPC_CFG:
3655 +               cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
3656                 cmdptr->size =
3657                     cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
3658                                      S_DS_GEN);
3659 @@ -1326,7 +1596,7 @@ int libertas_prepare_and_send_command(wl
3660  
3661                 ret = 0;
3662                 break;
3663 -       case cmd_802_11_led_gpio_ctrl:
3664 +       case CMD_802_11_LED_GPIO_CTRL:
3665                 {
3666                         struct mrvlietypes_ledgpio *gpio =
3667                             (struct mrvlietypes_ledgpio*)
3668 @@ -1337,19 +1607,24 @@ int libertas_prepare_and_send_command(wl
3669                                 sizeof(struct cmd_ds_802_11_led_ctrl));
3670  
3671                         cmdptr->command =
3672 -                           cpu_to_le16(cmd_802_11_led_gpio_ctrl);
3673 +                           cpu_to_le16(CMD_802_11_LED_GPIO_CTRL);
3674  
3675  #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
3676                         cmdptr->size =
3677 -                           cpu_to_le16(gpio->header.len + S_DS_GEN +
3678 -                                            ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
3679 -                       gpio->header.len = cpu_to_le16(gpio->header.len);
3680 +                           cpu_to_le16(le16_to_cpu(gpio->header.len)
3681 +                               + S_DS_GEN
3682 +                               + ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
3683 +                       gpio->header.len = gpio->header.len;
3684  
3685                         ret = 0;
3686                         break;
3687                 }
3688 -       case cmd_802_11_pwr_cfg:
3689 -               cmdptr->command = cpu_to_le16(cmd_802_11_pwr_cfg);
3690 +       case CMD_802_11_SUBSCRIBE_EVENT:
3691 +               lbs_cmd_802_11_subscribe_event(priv, cmdptr,
3692 +                       cmd_action, pdata_buf);
3693 +               break;
3694 +       case CMD_802_11_PWR_CFG:
3695 +               cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG);
3696                 cmdptr->size =
3697                     cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) +
3698                                      S_DS_GEN);
3699 @@ -1358,170 +1633,147 @@ int libertas_prepare_and_send_command(wl
3700  
3701                 ret = 0;
3702                 break;
3703 -       case cmd_bt_access:
3704 -               ret = wlan_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
3705 +       case CMD_BT_ACCESS:
3706 +               ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
3707                 break;
3708  
3709 -       case cmd_fwt_access:
3710 -               ret = wlan_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
3711 +       case CMD_FWT_ACCESS:
3712 +               ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
3713                 break;
3714  
3715 -       case cmd_mesh_access:
3716 -               ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
3717 -               break;
3718 -
3719 -       case cmd_get_tsf:
3720 -               cmdptr->command = cpu_to_le16(cmd_get_tsf);
3721 +       case CMD_GET_TSF:
3722 +               cmdptr->command = cpu_to_le16(CMD_GET_TSF);
3723                 cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
3724                                            S_DS_GEN);
3725                 ret = 0;
3726                 break;
3727 -       case cmd_802_11_tx_rate_query:
3728 -               cmdptr->command = cpu_to_le16(cmd_802_11_tx_rate_query);
3729 -               cmdptr->size = cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
3730 -                                          S_DS_GEN);
3731 -               adapter->txrate = 0;
3732 -               ret = 0;
3733 +       case CMD_802_11_BEACON_CTRL:
3734 +               ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
3735                 break;
3736         default:
3737 -               lbs_deb_cmd("PREP_CMD: unknown command- %#x\n", cmd_no);
3738 +               lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no);
3739                 ret = -1;
3740                 break;
3741         }
3742  
3743         /* return error, since the command preparation failed */
3744         if (ret != 0) {
3745 -               lbs_deb_cmd("PREP_CMD: command preparation failed\n");
3746 -               libertas_cleanup_and_insert_cmd(priv, cmdnode);
3747 +               lbs_deb_host("PREP_CMD: command preparation failed\n");
3748 +               lbs_cleanup_and_insert_cmd(priv, cmdnode);
3749                 ret = -1;
3750                 goto done;
3751         }
3752  
3753         cmdnode->cmdwaitqwoken = 0;
3754  
3755 -       libertas_queue_cmd(adapter, cmdnode, 1);
3756 -       adapter->nr_cmd_pending++;
3757 -       wake_up_interruptible(&priv->mainthread.waitq);
3758 +       lbs_queue_cmd(priv, cmdnode);
3759 +       wake_up_interruptible(&priv->waitq);
3760  
3761 -       if (wait_option & cmd_option_waitforrsp) {
3762 -               lbs_deb_cmd("PREP_CMD: Wait for CMD response\n");
3763 +       if (wait_option & CMD_OPTION_WAITFORRSP) {
3764 +               lbs_deb_host("PREP_CMD: wait for response\n");
3765                 might_sleep();
3766                 wait_event_interruptible(cmdnode->cmdwait_q,
3767                                          cmdnode->cmdwaitqwoken);
3768         }
3769  
3770 -       spin_lock_irqsave(&adapter->driver_lock, flags);
3771 -       if (adapter->cur_cmd_retcode) {
3772 -               lbs_deb_cmd("PREP_CMD: command failed with return code=%d\n",
3773 -                      adapter->cur_cmd_retcode);
3774 -               adapter->cur_cmd_retcode = 0;
3775 +       spin_lock_irqsave(&priv->driver_lock, flags);
3776 +       if (priv->cur_cmd_retcode) {
3777 +               lbs_deb_host("PREP_CMD: command failed with return code %d\n",
3778 +                      priv->cur_cmd_retcode);
3779 +               priv->cur_cmd_retcode = 0;
3780                 ret = -1;
3781         }
3782 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
3783 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
3784  
3785  done:
3786 -       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
3787 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
3788         return ret;
3789  }
3790 -EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command);
3791 +EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
3792  
3793  /**
3794   *  @brief This function allocates the command buffer and link
3795   *  it to command free queue.
3796   *
3797 - *  @param priv                A pointer to wlan_private structure
3798 + *  @param priv                A pointer to struct lbs_private structure
3799   *  @return            0 or -1
3800   */
3801 -int libertas_allocate_cmd_buffer(wlan_private * priv)
3802 +int lbs_allocate_cmd_buffer(struct lbs_private *priv)
3803  {
3804         int ret = 0;
3805 -       u32 ulbufsize;
3806 +       u32 bufsize;
3807         u32 i;
3808 -       struct cmd_ctrl_node *tempcmd_array;
3809 -       u8 *ptempvirtualaddr;
3810 -       wlan_adapter *adapter = priv->adapter;
3811 +       struct cmd_ctrl_node *cmdarray;
3812  
3813 -       lbs_deb_enter(LBS_DEB_CMD);
3814 +       lbs_deb_enter(LBS_DEB_HOST);
3815  
3816 -       /* Allocate and initialize cmdCtrlNode */
3817 -       ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
3818 -
3819 -       if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {
3820 -               lbs_deb_cmd(
3821 -                      "ALLOC_CMD_BUF: failed to allocate tempcmd_array\n");
3822 +       /* Allocate and initialize the command array */
3823 +       bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
3824 +       if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
3825 +               lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
3826                 ret = -1;
3827                 goto done;
3828         }
3829 -       adapter->cmd_array = tempcmd_array;
3830 +       priv->cmd_array = cmdarray;
3831  
3832 -       /* Allocate and initialize command buffers */
3833 -       ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
3834 -       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
3835 -               if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {
3836 -                       lbs_deb_cmd(
3837 -                              "ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n");
3838 +       /* Allocate and initialize each command buffer in the command array */
3839 +       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
3840 +               cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
3841 +               if (!cmdarray[i].cmdbuf) {
3842 +                       lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
3843                         ret = -1;
3844                         goto done;
3845                 }
3846 -
3847 -               /* Update command buffer virtual */
3848 -               tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
3849         }
3850  
3851 -       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
3852 -               init_waitqueue_head(&tempcmd_array[i].cmdwait_q);
3853 -               libertas_cleanup_and_insert_cmd(priv, &tempcmd_array[i]);
3854 +       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
3855 +               init_waitqueue_head(&cmdarray[i].cmdwait_q);
3856 +               lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
3857         }
3858 -
3859         ret = 0;
3860  
3861  done:
3862 -       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
3863 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
3864         return ret;
3865  }
3866  
3867  /**
3868   *  @brief This function frees the command buffer.
3869   *
3870 - *  @param priv                A pointer to wlan_private structure
3871 + *  @param priv                A pointer to struct lbs_private structure
3872   *  @return            0 or -1
3873   */
3874 -int libertas_free_cmd_buffer(wlan_private * priv)
3875 +int lbs_free_cmd_buffer(struct lbs_private *priv)
3876  {
3877 -       u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */
3878 +       struct cmd_ctrl_node *cmdarray;
3879         unsigned int i;
3880 -       struct cmd_ctrl_node *tempcmd_array;
3881 -       wlan_adapter *adapter = priv->adapter;
3882  
3883 -       lbs_deb_enter(LBS_DEB_CMD);
3884 +       lbs_deb_enter(LBS_DEB_HOST);
3885  
3886         /* need to check if cmd array is allocated or not */
3887 -       if (adapter->cmd_array == NULL) {
3888 -               lbs_deb_cmd("FREE_CMD_BUF: cmd_array is Null\n");
3889 +       if (priv->cmd_array == NULL) {
3890 +               lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
3891                 goto done;
3892         }
3893  
3894 -       tempcmd_array = adapter->cmd_array;
3895 +       cmdarray = priv->cmd_array;
3896  
3897         /* Release shared memory buffers */
3898 -       ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
3899 -       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
3900 -               if (tempcmd_array[i].bufvirtualaddr) {
3901 -                       lbs_deb_cmd("Free all the array\n");
3902 -                       kfree(tempcmd_array[i].bufvirtualaddr);
3903 -                       tempcmd_array[i].bufvirtualaddr = NULL;
3904 +       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
3905 +               if (cmdarray[i].cmdbuf) {
3906 +                       kfree(cmdarray[i].cmdbuf);
3907 +                       cmdarray[i].cmdbuf = NULL;
3908                 }
3909         }
3910  
3911         /* Release cmd_ctrl_node */
3912 -       if (adapter->cmd_array) {
3913 -               lbs_deb_cmd("Free cmd_array\n");
3914 -               kfree(adapter->cmd_array);
3915 -               adapter->cmd_array = NULL;
3916 +       if (priv->cmd_array) {
3917 +               kfree(priv->cmd_array);
3918 +               priv->cmd_array = NULL;
3919         }
3920  
3921  done:
3922 -       lbs_deb_leave(LBS_DEB_CMD);
3923 +       lbs_deb_leave(LBS_DEB_HOST);
3924         return 0;
3925  }
3926  
3927 @@ -1529,39 +1781,33 @@ done:
3928   *  @brief This function gets a free command node if available in
3929   *  command free queue.
3930   *
3931 - *  @param priv                A pointer to wlan_private structure
3932 + *  @param priv                A pointer to struct lbs_private structure
3933   *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
3934   */
3935 -struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
3936 +static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
3937  {
3938         struct cmd_ctrl_node *tempnode;
3939 -       wlan_adapter *adapter = priv->adapter;
3940         unsigned long flags;
3941  
3942 -       if (!adapter)
3943 +       lbs_deb_enter(LBS_DEB_HOST);
3944 +
3945 +       if (!priv)
3946                 return NULL;
3947  
3948 -       spin_lock_irqsave(&adapter->driver_lock, flags);
3949 +       spin_lock_irqsave(&priv->driver_lock, flags);
3950  
3951 -       if (!list_empty(&adapter->cmdfreeq)) {
3952 -               tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
3953 -               list_del((struct list_head *)tempnode);
3954 +       if (!list_empty(&priv->cmdfreeq)) {
3955 +               tempnode = list_first_entry(&priv->cmdfreeq,
3956 +                                           struct cmd_ctrl_node, list);
3957 +               list_del(&tempnode->list);
3958         } else {
3959 -               lbs_deb_cmd("GET_CMD_NODE: cmd_ctrl_node is not available\n");
3960 +               lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
3961                 tempnode = NULL;
3962         }
3963  
3964 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
3965 -
3966 -       if (tempnode) {
3967 -               /*
3968 -               lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode available\n");
3969 -               lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode Address = %p\n",
3970 -                      tempnode);
3971 -               */
3972 -               cleanup_cmdnode(tempnode);
3973 -       }
3974 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
3975  
3976 +       lbs_deb_leave(LBS_DEB_HOST);
3977         return tempnode;
3978  }
3979  
3980 @@ -1571,46 +1817,28 @@ struct cmd_ctrl_node *libertas_get_free_
3981   *  @param ptempnode   A pointer to cmdCtrlNode structure
3982   *  @return            n/a
3983   */
3984 -static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
3985 -{
3986 -       if (!ptempnode)
3987 -               return;
3988 -       ptempnode->cmdwaitqwoken = 1;
3989 -       wake_up_interruptible(&ptempnode->cmdwait_q);
3990 -       ptempnode->status = 0;
3991 -       ptempnode->cmd_oid = (u32) 0;
3992 -       ptempnode->wait_option = 0;
3993 -       ptempnode->pdata_buf = NULL;
3994 -
3995 -       if (ptempnode->bufvirtualaddr != NULL)
3996 -               memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
3997 -       return;
3998 -}
3999  
4000  /**
4001   *  @brief This function initializes the command node.
4002   *
4003 - *  @param priv                A pointer to wlan_private structure
4004 + *  @param priv                A pointer to struct lbs_private structure
4005   *  @param ptempnode   A pointer to cmd_ctrl_node structure
4006 - *  @param cmd_oid     cmd oid: treated as sub command
4007 - *  @param wait_option wait option: wait response or not
4008   *  @param pdata_buf   A pointer to informaion buffer
4009   *  @return            0 or -1
4010   */
4011 -void libertas_set_cmd_ctrl_node(wlan_private * priv,
4012 -                   struct cmd_ctrl_node *ptempnode,
4013 -                   u32 cmd_oid, u16 wait_option, void *pdata_buf)
4014 +static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
4015 +                                 struct cmd_ctrl_node *ptempnode,
4016 +                                 void *pdata_buf)
4017  {
4018 -       lbs_deb_enter(LBS_DEB_CMD);
4019 +       lbs_deb_enter(LBS_DEB_HOST);
4020  
4021         if (!ptempnode)
4022                 return;
4023  
4024 -       ptempnode->cmd_oid = cmd_oid;
4025 -       ptempnode->wait_option = wait_option;
4026 -       ptempnode->pdata_buf = pdata_buf;
4027 +       ptempnode->callback = NULL;
4028 +       ptempnode->callback_arg = (unsigned long)pdata_buf;
4029  
4030 -       lbs_deb_leave(LBS_DEB_CMD);
4031 +       lbs_deb_leave(LBS_DEB_HOST);
4032  }
4033  
4034  /**
4035 @@ -1618,59 +1846,58 @@ void libertas_set_cmd_ctrl_node(wlan_pri
4036   *  pending queue. It will put fimware back to PS mode
4037   *  if applicable.
4038   *
4039 - *  @param priv     A pointer to wlan_private structure
4040 + *  @param priv     A pointer to struct lbs_private structure
4041   *  @return       0 or -1
4042   */
4043 -int libertas_execute_next_command(wlan_private * priv)
4044 +int lbs_execute_next_command(struct lbs_private *priv)
4045  {
4046 -       wlan_adapter *adapter = priv->adapter;
4047         struct cmd_ctrl_node *cmdnode = NULL;
4048 -       struct cmd_ds_command *cmdptr;
4049 +       struct cmd_header *cmd;
4050         unsigned long flags;
4051         int ret = 0;
4052  
4053 -       lbs_deb_enter(LBS_DEB_CMD);
4054 -
4055 -       spin_lock_irqsave(&adapter->driver_lock, flags);
4056 -
4057 -       if (adapter->cur_cmd) {
4058 -               lbs_pr_alert( "EXEC_NEXT_CMD: there is command in processing!\n");
4059 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
4060 +       /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
4061 +        * only caller to us is lbs_thread() and we get even when a
4062 +        * data packet is received */
4063 +       lbs_deb_enter(LBS_DEB_THREAD);
4064 +
4065 +       spin_lock_irqsave(&priv->driver_lock, flags);
4066 +
4067 +       if (priv->cur_cmd) {
4068 +               lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
4069 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
4070                 ret = -1;
4071                 goto done;
4072         }
4073  
4074 -       if (!list_empty(&adapter->cmdpendingq)) {
4075 -               cmdnode = (struct cmd_ctrl_node *)
4076 -                   adapter->cmdpendingq.next;
4077 +       if (!list_empty(&priv->cmdpendingq)) {
4078 +               cmdnode = list_first_entry(&priv->cmdpendingq,
4079 +                                          struct cmd_ctrl_node, list);
4080         }
4081  
4082 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
4083 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
4084  
4085         if (cmdnode) {
4086 -               lbs_deb_cmd(
4087 -                      "EXEC_NEXT_CMD: Got next command from cmdpendingq\n");
4088 -               cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
4089 -
4090 -               if (is_command_allowed_in_ps(cmdptr->command)) {
4091 -                       if ((adapter->psstate == PS_STATE_SLEEP) ||
4092 -                           (adapter->psstate == PS_STATE_PRE_SLEEP)) {
4093 -                               lbs_deb_cmd(
4094 -                                      "EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n",
4095 -                                      le16_to_cpu(cmdptr->command),
4096 -                                      adapter->psstate);
4097 +               cmd = cmdnode->cmdbuf;
4098 +
4099 +               if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
4100 +                       if ((priv->psstate == PS_STATE_SLEEP) ||
4101 +                           (priv->psstate == PS_STATE_PRE_SLEEP)) {
4102 +                               lbs_deb_host(
4103 +                                      "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
4104 +                                      le16_to_cpu(cmd->command),
4105 +                                      priv->psstate);
4106                                 ret = -1;
4107                                 goto done;
4108                         }
4109 -                       lbs_deb_cmd("EXEC_NEXT_CMD: OK to send command "
4110 -                              "0x%x in psstate %d\n",
4111 -                                   le16_to_cpu(cmdptr->command),
4112 -                                   adapter->psstate);
4113 -               } else if (adapter->psstate != PS_STATE_FULL_POWER) {
4114 +                       lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
4115 +                                    "0x%04x in psstate %d\n",
4116 +                                    le16_to_cpu(cmd->command), priv->psstate);
4117 +               } else if (priv->psstate != PS_STATE_FULL_POWER) {
4118                         /*
4119                          * 1. Non-PS command:
4120                          * Queue it. set needtowakeup to TRUE if current state
4121 -                        * is SLEEP, otherwise call libertas_ps_wakeup to send Exit_PS.
4122 +                        * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
4123                          * 2. PS command but not Exit_PS:
4124                          * Ignore it.
4125                          * 3. PS command Exit_PS:
4126 @@ -1678,18 +1905,17 @@ int libertas_execute_next_command(wlan_p
4127                          * otherwise send this command down to firmware
4128                          * immediately.
4129                          */
4130 -                       if (cmdptr->command !=
4131 -                           cpu_to_le16(cmd_802_11_ps_mode)) {
4132 +                       if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
4133                                 /*  Prepare to send Exit PS,
4134                                  *  this non PS command will be sent later */
4135 -                               if ((adapter->psstate == PS_STATE_SLEEP)
4136 -                                   || (adapter->psstate == PS_STATE_PRE_SLEEP)
4137 +                               if ((priv->psstate == PS_STATE_SLEEP)
4138 +                                   || (priv->psstate == PS_STATE_PRE_SLEEP)
4139                                     ) {
4140                                         /* w/ new scheme, it will not reach here.
4141                                            since it is blocked in main_thread. */
4142 -                                       adapter->needtowakeup = 1;
4143 +                                       priv->needtowakeup = 1;
4144                                 } else
4145 -                                       libertas_ps_wakeup(priv, 0);
4146 +                                       lbs_ps_wakeup(priv, 0);
4147  
4148                                 ret = 0;
4149                                 goto done;
4150 @@ -1698,82 +1924,86 @@ int libertas_execute_next_command(wlan_p
4151                                  * PS command. Ignore it if it is not Exit_PS.
4152                                  * otherwise send it down immediately.
4153                                  */
4154 -                               struct cmd_ds_802_11_ps_mode *psm =
4155 -                                   &cmdptr->params.psmode;
4156 +                               struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
4157  
4158 -                               lbs_deb_cmd(
4159 -                                      "EXEC_NEXT_CMD: PS cmd- action=0x%x\n",
4160 +                               lbs_deb_host(
4161 +                                      "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
4162                                        psm->action);
4163                                 if (psm->action !=
4164 -                                   cpu_to_le16(cmd_subcmd_exit_ps)) {
4165 -                                       lbs_deb_cmd(
4166 -                                              "EXEC_NEXT_CMD: Ignore Enter PS cmd\n");
4167 -                                       list_del((struct list_head *)cmdnode);
4168 -                                       libertas_cleanup_and_insert_cmd(priv, cmdnode);
4169 +                                   cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
4170 +                                       lbs_deb_host(
4171 +                                              "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
4172 +                                       list_del(&cmdnode->list);
4173 +                                       spin_lock_irqsave(&priv->driver_lock, flags);
4174 +                                       lbs_complete_command(priv, cmdnode, 0);
4175 +                                       spin_unlock_irqrestore(&priv->driver_lock, flags);
4176  
4177                                         ret = 0;
4178                                         goto done;
4179                                 }
4180  
4181 -                               if ((adapter->psstate == PS_STATE_SLEEP) ||
4182 -                                   (adapter->psstate == PS_STATE_PRE_SLEEP)) {
4183 -                                       lbs_deb_cmd(
4184 -                                              "EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n");
4185 -                                       list_del((struct list_head *)cmdnode);
4186 -                                       libertas_cleanup_and_insert_cmd(priv, cmdnode);
4187 -                                       adapter->needtowakeup = 1;
4188 +                               if ((priv->psstate == PS_STATE_SLEEP) ||
4189 +                                   (priv->psstate == PS_STATE_PRE_SLEEP)) {
4190 +                                       lbs_deb_host(
4191 +                                              "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
4192 +                                       list_del(&cmdnode->list);
4193 +                                       spin_lock_irqsave(&priv->driver_lock, flags);
4194 +                                       lbs_complete_command(priv, cmdnode, 0);
4195 +                                       spin_unlock_irqrestore(&priv->driver_lock, flags);
4196 +                                       priv->needtowakeup = 1;
4197  
4198                                         ret = 0;
4199                                         goto done;
4200                                 }
4201  
4202 -                               lbs_deb_cmd(
4203 -                                      "EXEC_NEXT_CMD: Sending Exit_PS down...\n");
4204 +                               lbs_deb_host(
4205 +                                      "EXEC_NEXT_CMD: sending EXIT_PS\n");
4206                         }
4207                 }
4208 -               list_del((struct list_head *)cmdnode);
4209 -               lbs_deb_cmd("EXEC_NEXT_CMD: Sending 0x%04X command\n",
4210 -                           le16_to_cpu(cmdptr->command));
4211 -               DownloadcommandToStation(priv, cmdnode);
4212 +               list_del(&cmdnode->list);
4213 +               lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
4214 +                           le16_to_cpu(cmd->command));
4215 +               lbs_submit_command(priv, cmdnode);
4216         } else {
4217                 /*
4218                  * check if in power save mode, if yes, put the device back
4219                  * to PS mode
4220                  */
4221 -               if ((adapter->psmode != wlan802_11powermodecam) &&
4222 -                   (adapter->psstate == PS_STATE_FULL_POWER) &&
4223 -                   (adapter->connect_status == libertas_connected)) {
4224 -                       if (adapter->secinfo.WPAenabled ||
4225 -                           adapter->secinfo.WPA2enabled) {
4226 +               if ((priv->psmode != LBS802_11POWERMODECAM) &&
4227 +                   (priv->psstate == PS_STATE_FULL_POWER) &&
4228 +                   ((priv->connect_status == LBS_CONNECTED) ||
4229 +                   (priv->mesh_connect_status == LBS_CONNECTED))) {
4230 +                       if (priv->secinfo.WPAenabled ||
4231 +                           priv->secinfo.WPA2enabled) {
4232                                 /* check for valid WPA group keys */
4233 -                               if (adapter->wpa_mcast_key.len ||
4234 -                                   adapter->wpa_unicast_key.len) {
4235 -                                       lbs_deb_cmd(
4236 +                               if (priv->wpa_mcast_key.len ||
4237 +                                   priv->wpa_unicast_key.len) {
4238 +                                       lbs_deb_host(
4239                                                "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
4240                                                " go back to PS_SLEEP");
4241 -                                       libertas_ps_sleep(priv, 0);
4242 +                                       lbs_ps_sleep(priv, 0);
4243                                 }
4244                         } else {
4245 -                               lbs_deb_cmd(
4246 -                                      "EXEC_NEXT_CMD: command PendQ is empty,"
4247 -                                      " go back to PS_SLEEP");
4248 -                               libertas_ps_sleep(priv, 0);
4249 +                               lbs_deb_host(
4250 +                                      "EXEC_NEXT_CMD: cmdpendingq empty, "
4251 +                                      "go back to PS_SLEEP");
4252 +                               lbs_ps_sleep(priv, 0);
4253                         }
4254                 }
4255         }
4256  
4257         ret = 0;
4258  done:
4259 -       lbs_deb_leave(LBS_DEB_CMD);
4260 +       lbs_deb_leave(LBS_DEB_THREAD);
4261         return ret;
4262  }
4263  
4264 -void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
4265 +void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
4266  {
4267         union iwreq_data iwrq;
4268         u8 buf[50];
4269  
4270 -       lbs_deb_enter(LBS_DEB_CMD);
4271 +       lbs_deb_enter(LBS_DEB_WEXT);
4272  
4273         memset(&iwrq, 0, sizeof(union iwreq_data));
4274         memset(buf, 0, sizeof(buf));
4275 @@ -1783,136 +2013,227 @@ void libertas_send_iwevcustom_event(wlan
4276         iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
4277  
4278         /* Send Event to upper layer */
4279 -       lbs_deb_cmd("Event Indication string = %s\n", (char *)buf);
4280 -       lbs_deb_cmd("Event Indication String length = %d\n", iwrq.data.length);
4281 +       lbs_deb_wext("event indication string %s\n", (char *)buf);
4282 +       lbs_deb_wext("event indication length %d\n", iwrq.data.length);
4283 +       lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);
4284  
4285 -       lbs_deb_cmd("Sending wireless event IWEVCUSTOM for %s\n", str);
4286         wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
4287  
4288 -       lbs_deb_leave(LBS_DEB_CMD);
4289 +       lbs_deb_leave(LBS_DEB_WEXT);
4290  }
4291  
4292 -static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
4293 +static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size)
4294  {
4295         unsigned long flags;
4296 -       wlan_adapter *adapter = priv->adapter;
4297         int ret = 0;
4298  
4299 -       lbs_deb_enter(LBS_DEB_CMD);
4300 +       lbs_deb_enter(LBS_DEB_HOST);
4301  
4302 -       lbs_deb_cmd("SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
4303 +       lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n",
4304                size);
4305  
4306 -       lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size);
4307 +       lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size);
4308  
4309         ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);
4310 -       priv->dnld_sent = DNLD_RES_RECEIVED;
4311  
4312 -       spin_lock_irqsave(&adapter->driver_lock, flags);
4313 -       if (adapter->intcounter || adapter->currenttxskb)
4314 -               lbs_deb_cmd("SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
4315 -                      adapter->intcounter, adapter->currenttxskb);
4316 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
4317 +       spin_lock_irqsave(&priv->driver_lock, flags);
4318 +       if (priv->intcounter || priv->currenttxskb)
4319 +               lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",
4320 +                      priv->intcounter, priv->currenttxskb);
4321 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
4322  
4323         if (ret) {
4324                 lbs_pr_alert(
4325                        "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");
4326         } else {
4327 -               spin_lock_irqsave(&adapter->driver_lock, flags);
4328 -               if (!adapter->intcounter) {
4329 -                       adapter->psstate = PS_STATE_SLEEP;
4330 +               spin_lock_irqsave(&priv->driver_lock, flags);
4331 +               if (!priv->intcounter) {
4332 +                       priv->psstate = PS_STATE_SLEEP;
4333                 } else {
4334 -                       lbs_deb_cmd("SEND_SLEEPC_CMD: After sent,IntC=%d\n",
4335 -                              adapter->intcounter);
4336 +                       lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",
4337 +                              priv->intcounter);
4338                 }
4339 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
4340 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
4341  
4342 -               lbs_deb_cmd("SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
4343 -               lbs_deb_cmd("+");
4344 +               lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n");
4345         }
4346  
4347 -       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
4348 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
4349         return ret;
4350  }
4351  
4352 -void libertas_ps_sleep(wlan_private * priv, int wait_option)
4353 +void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
4354  {
4355 -       lbs_deb_enter(LBS_DEB_CMD);
4356 +       lbs_deb_enter(LBS_DEB_HOST);
4357  
4358         /*
4359          * PS is currently supported only in Infrastructure mode
4360          * Remove this check if it is to be supported in IBSS mode also
4361          */
4362  
4363 -       libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
4364 -                             cmd_subcmd_enter_ps, wait_option, 0, NULL);
4365 +       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
4366 +                             CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
4367  
4368 -       lbs_deb_leave(LBS_DEB_CMD);
4369 +       lbs_deb_leave(LBS_DEB_HOST);
4370  }
4371  
4372  /**
4373 - *  @brief This function sends Eixt_PS command to firmware.
4374 + *  @brief This function sends Exit_PS command to firmware.
4375   *
4376 - *  @param priv        A pointer to wlan_private structure
4377 + *  @param priv        A pointer to struct lbs_private structure
4378   *  @param wait_option wait response or not
4379   *  @return            n/a
4380   */
4381 -void libertas_ps_wakeup(wlan_private * priv, int wait_option)
4382 +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
4383  {
4384         __le32 Localpsmode;
4385  
4386 -       lbs_deb_enter(LBS_DEB_CMD);
4387 -
4388 -       Localpsmode = cpu_to_le32(wlan802_11powermodecam);
4389 +       lbs_deb_enter(LBS_DEB_HOST);
4390  
4391 -       lbs_deb_cmd("Exit_PS: Localpsmode = %d\n", wlan802_11powermodecam);
4392 +       Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
4393  
4394 -       libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
4395 -                             cmd_subcmd_exit_ps,
4396 +       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
4397 +                             CMD_SUBCMD_EXIT_PS,
4398                               wait_option, 0, &Localpsmode);
4399  
4400 -       lbs_deb_leave(LBS_DEB_CMD);
4401 +       lbs_deb_leave(LBS_DEB_HOST);
4402  }
4403  
4404  /**
4405   *  @brief This function checks condition and prepares to
4406   *  send sleep confirm command to firmware if ok.
4407   *
4408 - *  @param priv        A pointer to wlan_private structure
4409 + *  @param priv        A pointer to struct lbs_private structure
4410   *  @param psmode      Power Saving mode
4411   *  @return            n/a
4412   */
4413 -void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
4414 +void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
4415  {
4416         unsigned long flags =0;
4417 -       wlan_adapter *adapter = priv->adapter;
4418         u8 allowed = 1;
4419  
4420 -       lbs_deb_enter(LBS_DEB_CMD);
4421 +       lbs_deb_enter(LBS_DEB_HOST);
4422  
4423         if (priv->dnld_sent) {
4424                 allowed = 0;
4425 -               lbs_deb_cmd("D");
4426 +               lbs_deb_host("dnld_sent was set\n");
4427         }
4428  
4429 -       spin_lock_irqsave(&adapter->driver_lock, flags);
4430 -       if (adapter->cur_cmd) {
4431 +       spin_lock_irqsave(&priv->driver_lock, flags);
4432 +       if (priv->cur_cmd) {
4433                 allowed = 0;
4434 -               lbs_deb_cmd("C");
4435 +               lbs_deb_host("cur_cmd was set\n");
4436         }
4437 -       if (adapter->intcounter > 0) {
4438 +       if (priv->intcounter > 0) {
4439                 allowed = 0;
4440 -               lbs_deb_cmd("I%d", adapter->intcounter);
4441 +               lbs_deb_host("intcounter %d\n", priv->intcounter);
4442         }
4443 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
4444 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
4445  
4446         if (allowed) {
4447 -               lbs_deb_cmd("Sending libertas_ps_confirm_sleep\n");
4448 -               sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,
4449 +               lbs_deb_host("sending lbs_ps_confirm_sleep\n");
4450 +               sendconfirmsleep(priv, (u8 *) & priv->lbs_ps_confirm_sleep,
4451                                  sizeof(struct PS_CMD_ConfirmSleep));
4452         } else {
4453 -               lbs_deb_cmd("Sleep Confirm has been delayed\n");
4454 +               lbs_deb_host("sleep confirm has been delayed\n");
4455         }
4456  
4457 +       lbs_deb_leave(LBS_DEB_HOST);
4458 +}
4459 +
4460 +
4461 +static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
4462 +       uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
4463 +       int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
4464 +       unsigned long callback_arg)
4465 +{
4466 +       struct cmd_ctrl_node *cmdnode;
4467 +
4468 +       lbs_deb_enter(LBS_DEB_HOST);
4469 +
4470 +       if (priv->surpriseremoved) {
4471 +               lbs_deb_host("PREP_CMD: card removed\n");
4472 +               cmdnode = ERR_PTR(-ENOENT);
4473 +               goto done;
4474 +       }
4475 +
4476 +       cmdnode = lbs_get_cmd_ctrl_node(priv);
4477 +       if (cmdnode == NULL) {
4478 +               lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
4479 +
4480 +               /* Wake up main thread to execute next command */
4481 +               wake_up_interruptible(&priv->waitq);
4482 +               cmdnode = ERR_PTR(-ENOBUFS);
4483 +               goto done;
4484 +       }
4485 +
4486 +       cmdnode->callback = callback;
4487 +       cmdnode->callback_arg = callback_arg;
4488 +
4489 +       /* Copy the incoming command to the buffer */
4490 +       memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
4491 +
4492 +       /* Set sequence number, clean result, move to buffer */
4493 +       priv->seqnum++;
4494 +       cmdnode->cmdbuf->command = cpu_to_le16(command);
4495 +       cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
4496 +       cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
4497 +       cmdnode->cmdbuf->result  = 0;
4498 +
4499 +       lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
4500 +
4501 +       cmdnode->cmdwaitqwoken = 0;
4502 +       lbs_queue_cmd(priv, cmdnode);
4503 +       wake_up_interruptible(&priv->waitq);
4504 +
4505 + done:
4506 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
4507 +       return cmdnode;
4508 +}
4509 +
4510 +void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
4511 +       struct cmd_header *in_cmd, int in_cmd_size)
4512 +{
4513 +       lbs_deb_enter(LBS_DEB_CMD);
4514 +       __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
4515 +               lbs_cmd_async_callback, 0);
4516         lbs_deb_leave(LBS_DEB_CMD);
4517  }
4518 +
4519 +int __lbs_cmd(struct lbs_private *priv, uint16_t command,
4520 +             struct cmd_header *in_cmd, int in_cmd_size,
4521 +             int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
4522 +             unsigned long callback_arg)
4523 +{
4524 +       struct cmd_ctrl_node *cmdnode;
4525 +       unsigned long flags;
4526 +       int ret = 0;
4527 +
4528 +       lbs_deb_enter(LBS_DEB_HOST);
4529 +
4530 +       cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
4531 +                                 callback, callback_arg);
4532 +       if (IS_ERR(cmdnode)) {
4533 +               ret = PTR_ERR(cmdnode);
4534 +               goto done;
4535 +       }
4536 +
4537 +       might_sleep();
4538 +       wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
4539 +
4540 +       spin_lock_irqsave(&priv->driver_lock, flags);
4541 +       ret = cmdnode->result;
4542 +       if (ret)
4543 +               lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
4544 +                           command, ret);
4545 +
4546 +       __lbs_cleanup_and_insert_cmd(priv, cmdnode);
4547 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
4548 +
4549 +done:
4550 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
4551 +       return ret;
4552 +}
4553 +EXPORT_SYMBOL_GPL(__lbs_cmd);
4554 +
4555 +
4556 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/cmd.h linux-2.6.22-300/drivers/net/wireless/libertas/cmd.h
4557 --- linux-2.6.22-250/drivers/net/wireless/libertas/cmd.h        1969-12-31 19:00:00.000000000 -0500
4558 +++ linux-2.6.22-300/drivers/net/wireless/libertas/cmd.h        2008-06-05 18:10:06.000000000 -0400
4559 @@ -0,0 +1,50 @@
4560 +/* Copyright (C) 2007, Red Hat, Inc. */
4561 +
4562 +#ifndef _LBS_CMD_H_
4563 +#define _LBS_CMD_H_
4564 +
4565 +#include "hostcmd.h"
4566 +#include "dev.h"
4567 +
4568 +#define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg)  \
4569 +       __lbs_cmd(priv, cmdnr, &(cmd)->hdr, sizeof(*(cmd)), cb, cb_arg)
4570 +
4571 +
4572 +/* lbs_cmd_with_response() infers the size of the command to be _sent_
4573 +   and requires that the caller sets cmd->size to the (LE) size of
4574 +   the _response_ buffer. */
4575 +#define lbs_cmd_with_response(priv, cmdnr, cmd)        \
4576 +       lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
4577 +
4578 +void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
4579 +       struct cmd_header *in_cmd, int in_cmd_size);
4580 +
4581 +int __lbs_cmd(struct lbs_private *priv, uint16_t command,
4582 +             struct cmd_header *in_cmd, int in_cmd_size,
4583 +             int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
4584 +             unsigned long callback_arg);
4585 +
4586 +int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
4587 +                    struct cmd_header *resp);
4588 +
4589 +int lbs_update_hw_spec(struct lbs_private *priv);
4590 +
4591 +int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
4592 +                   struct cmd_ds_mesh_access *cmd);
4593 +
4594 +int lbs_get_data_rate(struct lbs_private *priv);
4595 +int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
4596 +
4597 +int lbs_get_channel(struct lbs_private *priv);
4598 +int lbs_set_channel(struct lbs_private *priv, u8 channel);
4599 +
4600 +int lbs_mesh_config_send(struct lbs_private *priv,
4601 +                        struct cmd_ds_mesh_config *cmd,
4602 +                        uint16_t action, uint16_t type);
4603 +int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
4604 +
4605 +int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
4606 +int lbs_suspend(struct lbs_private *priv);
4607 +int lbs_resume(struct lbs_private *priv);
4608 +
4609 +#endif /* _LBS_CMD_H */
4610 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/cmdresp.c linux-2.6.22-300/drivers/net/wireless/libertas/cmdresp.c
4611 --- linux-2.6.22-250/drivers/net/wireless/libertas/cmdresp.c    2007-07-08 19:32:17.000000000 -0400
4612 +++ linux-2.6.22-300/drivers/net/wireless/libertas/cmdresp.c    2008-06-05 18:10:06.000000000 -0400
4613 @@ -20,18 +20,17 @@
4614   *  reports disconnect to upper layer, clean tx/rx packets,
4615   *  reset link state etc.
4616   *
4617 - *  @param priv    A pointer to wlan_private structure
4618 + *  @param priv    A pointer to struct lbs_private structure
4619   *  @return       n/a
4620   */
4621 -void libertas_mac_event_disconnected(wlan_private * priv)
4622 +void lbs_mac_event_disconnected(struct lbs_private *priv)
4623  {
4624 -       wlan_adapter *adapter = priv->adapter;
4625         union iwreq_data wrqu;
4626  
4627 -       if (adapter->connect_status != libertas_connected)
4628 +       if (priv->connect_status != LBS_CONNECTED)
4629                 return;
4630  
4631 -       lbs_deb_cmd("Handles disconnect event.\n");
4632 +       lbs_deb_enter(LBS_DEB_ASSOC);
4633  
4634         memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
4635         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4636 @@ -44,64 +43,52 @@ void libertas_mac_event_disconnected(wla
4637         msleep_interruptible(1000);
4638         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4639  
4640 -       /* Free Tx and Rx packets */
4641 -       kfree_skb(priv->adapter->currenttxskb);
4642 -       priv->adapter->currenttxskb = NULL;
4643 -
4644         /* report disconnect to upper layer */
4645         netif_stop_queue(priv->dev);
4646         netif_carrier_off(priv->dev);
4647  
4648 +       /* Free Tx and Rx packets */
4649 +       kfree_skb(priv->currenttxskb);
4650 +       priv->currenttxskb = NULL;
4651 +       priv->tx_pending_len = 0;
4652 +
4653         /* reset SNR/NF/RSSI values */
4654 -       memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
4655 -       memset(adapter->NF, 0x00, sizeof(adapter->NF));
4656 -       memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI));
4657 -       memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
4658 -       memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
4659 -       adapter->nextSNRNF = 0;
4660 -       adapter->numSNRNF = 0;
4661 -       adapter->rxpd_rate = 0;
4662 -       lbs_deb_cmd("Current SSID='%s', ssid length=%u\n",
4663 -                   escape_essid(adapter->curbssparams.ssid,
4664 -                                adapter->curbssparams.ssid_len),
4665 -                   adapter->curbssparams.ssid_len);
4666 -       lbs_deb_cmd("Previous SSID='%s', ssid length=%u\n",
4667 -                   escape_essid(adapter->prev_ssid, adapter->prev_ssid_len),
4668 -                   adapter->prev_ssid_len);
4669 -
4670 -       adapter->connect_status = libertas_disconnected;
4671 -
4672 -       /* Save previous SSID and BSSID for possible reassociation */
4673 -       memcpy(&adapter->prev_ssid, &adapter->curbssparams.ssid,
4674 -              IW_ESSID_MAX_SIZE);
4675 -       adapter->prev_ssid_len = adapter->curbssparams.ssid_len;
4676 -       memcpy(adapter->prev_bssid, adapter->curbssparams.bssid, ETH_ALEN);
4677 +       memset(priv->SNR, 0x00, sizeof(priv->SNR));
4678 +       memset(priv->NF, 0x00, sizeof(priv->NF));
4679 +       memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
4680 +       memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
4681 +       memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
4682 +       priv->nextSNRNF = 0;
4683 +       priv->numSNRNF = 0;
4684 +       priv->connect_status = LBS_DISCONNECTED;
4685  
4686         /* Clear out associated SSID and BSSID since connection is
4687          * no longer valid.
4688          */
4689 -       memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
4690 -       memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
4691 -       adapter->curbssparams.ssid_len = 0;
4692 +       memset(&priv->curbssparams.bssid, 0, ETH_ALEN);
4693 +       memset(&priv->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
4694 +       priv->curbssparams.ssid_len = 0;
4695  
4696 -       if (adapter->psstate != PS_STATE_FULL_POWER) {
4697 +       if (priv->psstate != PS_STATE_FULL_POWER) {
4698                 /* make firmware to exit PS mode */
4699 -               lbs_deb_cmd("Disconnected, so exit PS mode.\n");
4700 -               libertas_ps_wakeup(priv, 0);
4701 +               lbs_deb_cmd("disconnected, so exit PS mode\n");
4702 +               lbs_ps_wakeup(priv, 0);
4703         }
4704 +       lbs_deb_leave(LBS_DEB_CMD);
4705  }
4706  
4707  /**
4708   *  @brief This function handles MIC failure event.
4709   *
4710 - *  @param priv    A pointer to wlan_private structure
4711 + *  @param priv    A pointer to struct lbs_private structure
4712   *  @para  event   the event id
4713   *  @return       n/a
4714   */
4715 -static void handle_mic_failureevent(wlan_private * priv, u32 event)
4716 +static void handle_mic_failureevent(struct lbs_private *priv, u32 event)
4717  {
4718         char buf[50];
4719  
4720 +       lbs_deb_enter(LBS_DEB_CMD);
4721         memset(buf, 0, sizeof(buf));
4722  
4723         sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
4724 @@ -112,42 +99,42 @@ static void handle_mic_failureevent(wlan
4725                 strcat(buf, "multicast ");
4726         }
4727  
4728 -       libertas_send_iwevcustom_event(priv, buf);
4729 +       lbs_send_iwevcustom_event(priv, buf);
4730 +       lbs_deb_leave(LBS_DEB_CMD);
4731  }
4732  
4733 -static int wlan_ret_reg_access(wlan_private * priv,
4734 +static int lbs_ret_reg_access(struct lbs_private *priv,
4735                                u16 type, struct cmd_ds_command *resp)
4736  {
4737         int ret = 0;
4738 -       wlan_adapter *adapter = priv->adapter;
4739  
4740         lbs_deb_enter(LBS_DEB_CMD);
4741  
4742         switch (type) {
4743 -       case cmd_ret_mac_reg_access:
4744 +       case CMD_RET(CMD_MAC_REG_ACCESS):
4745                 {
4746                         struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
4747  
4748 -                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4749 -                       adapter->offsetvalue.value = le32_to_cpu(reg->value);
4750 +                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4751 +                       priv->offsetvalue.value = le32_to_cpu(reg->value);
4752                         break;
4753                 }
4754  
4755 -       case cmd_ret_bbp_reg_access:
4756 +       case CMD_RET(CMD_BBP_REG_ACCESS):
4757                 {
4758                         struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
4759  
4760 -                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4761 -                       adapter->offsetvalue.value = reg->value;
4762 +                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4763 +                       priv->offsetvalue.value = reg->value;
4764                         break;
4765                 }
4766  
4767 -       case cmd_ret_rf_reg_access:
4768 +       case CMD_RET(CMD_RF_REG_ACCESS):
4769                 {
4770                         struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
4771  
4772 -                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4773 -                       adapter->offsetvalue.value = reg->value;
4774 +                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
4775 +                       priv->offsetvalue.value = reg->value;
4776                         break;
4777                 }
4778  
4779 @@ -155,113 +142,50 @@ static int wlan_ret_reg_access(wlan_priv
4780                 ret = -1;
4781         }
4782  
4783 -       lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
4784 -       return ret;
4785 -}
4786 -
4787 -static int wlan_ret_get_hw_spec(wlan_private * priv,
4788 -                               struct cmd_ds_command *resp)
4789 -{
4790 -       u32 i;
4791 -       struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec;
4792 -       wlan_adapter *adapter = priv->adapter;
4793 -       int ret = 0;
4794 -
4795 -       lbs_deb_enter(LBS_DEB_CMD);
4796 -
4797 -       adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
4798 -
4799 -       memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);
4800 -
4801 -       lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n",
4802 -                   adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
4803 -                   adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
4804 -       lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
4805 -              hwspec->permanentaddr[0], hwspec->permanentaddr[1],
4806 -              hwspec->permanentaddr[2], hwspec->permanentaddr[3],
4807 -              hwspec->permanentaddr[4], hwspec->permanentaddr[5]);
4808 -       lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X  version=0x%X\n",
4809 -              hwspec->hwifversion, hwspec->version);
4810 -
4811 -       adapter->regioncode = le16_to_cpu(hwspec->regioncode);
4812 -
4813 -       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
4814 -               /* use the region code to search for the index */
4815 -               if (adapter->regioncode == libertas_region_code_to_index[i]) {
4816 -                       adapter->regiontableindex = (u16) i;
4817 -                       break;
4818 -               }
4819 -       }
4820 -
4821 -       /* if it's unidentified region code, use the default (USA) */
4822 -       if (i >= MRVDRV_MAX_REGION_CODE) {
4823 -               adapter->regioncode = 0x10;
4824 -               adapter->regiontableindex = 0;
4825 -               lbs_pr_info("unidentified region code; using the default (USA)\n");
4826 -       }
4827 -
4828 -       if (adapter->current_addr[0] == 0xff)
4829 -               memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);
4830 -
4831 -       memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
4832 -       if (priv->mesh_dev)
4833 -               memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
4834 -
4835 -       if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
4836 -               ret = -1;
4837 -               goto done;
4838 -       }
4839 -
4840 -       if (libertas_set_universaltable(priv, 0)) {
4841 -               ret = -1;
4842 -               goto done;
4843 -       }
4844 -
4845 -done:
4846 -       lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
4847 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
4848         return ret;
4849  }
4850  
4851 -static int wlan_ret_802_11_sleep_params(wlan_private * priv,
4852 +static int lbs_ret_802_11_sleep_params(struct lbs_private *priv,
4853                                         struct cmd_ds_command *resp)
4854  {
4855         struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
4856 -       wlan_adapter *adapter = priv->adapter;
4857  
4858         lbs_deb_enter(LBS_DEB_CMD);
4859  
4860 -       lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n"
4861 -                   " extsleepclk=%x\n", le16_to_cpu(sp->error),
4862 +       lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, calcontrol 0x%x "
4863 +                   "extsleepclk 0x%x\n", le16_to_cpu(sp->error),
4864                     le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
4865                     sp->calcontrol, sp->externalsleepclk);
4866  
4867 -       adapter->sp.sp_error = le16_to_cpu(sp->error);
4868 -       adapter->sp.sp_offset = le16_to_cpu(sp->offset);
4869 -       adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
4870 -       adapter->sp.sp_calcontrol = sp->calcontrol;
4871 -       adapter->sp.sp_extsleepclk = sp->externalsleepclk;
4872 -       adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
4873 +       priv->sp.sp_error = le16_to_cpu(sp->error);
4874 +       priv->sp.sp_offset = le16_to_cpu(sp->offset);
4875 +       priv->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
4876 +       priv->sp.sp_calcontrol = sp->calcontrol;
4877 +       priv->sp.sp_extsleepclk = sp->externalsleepclk;
4878 +       priv->sp.sp_reserved = le16_to_cpu(sp->reserved);
4879  
4880         lbs_deb_enter(LBS_DEB_CMD);
4881         return 0;
4882  }
4883  
4884 -static int wlan_ret_802_11_stat(wlan_private * priv,
4885 +static int lbs_ret_802_11_stat(struct lbs_private *priv,
4886                                 struct cmd_ds_command *resp)
4887  {
4888 -/*     currently adapter->wlan802_11Stat is unused
4889 +       lbs_deb_enter(LBS_DEB_CMD);
4890 +/*     currently priv->wlan802_11Stat is unused
4891  
4892         struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
4893 -       wlan_adapter *adapter = priv->adapter;
4894  
4895         // TODO Convert it to Big endian befor copy
4896 -       memcpy(&adapter->wlan802_11Stat,
4897 +       memcpy(&priv->wlan802_11Stat,
4898                p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
4899  */
4900 +       lbs_deb_leave(LBS_DEB_CMD);
4901         return 0;
4902  }
4903  
4904 -static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
4905 +static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv,
4906                                     struct cmd_ds_command *resp)
4907  {
4908         struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
4909 @@ -270,29 +194,29 @@ static int wlan_ret_802_11_snmp_mib(wlan
4910  
4911         lbs_deb_enter(LBS_DEB_CMD);
4912  
4913 -       lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
4914 +       lbs_deb_cmd("SNMP_RESP: oid 0x%x, querytype 0x%x\n", oid,
4915                querytype);
4916 -       lbs_deb_cmd("SNMP_RESP: Buf size  = %x\n", le16_to_cpu(smib->bufsize));
4917 +       lbs_deb_cmd("SNMP_RESP: Buf size %d\n", le16_to_cpu(smib->bufsize));
4918  
4919 -       if (querytype == cmd_act_get) {
4920 +       if (querytype == CMD_ACT_GET) {
4921                 switch (oid) {
4922 -               case fragthresh_i:
4923 -                       priv->adapter->fragthsd =
4924 +               case FRAGTHRESH_I:
4925 +                       priv->fragthsd =
4926                                 le16_to_cpu(*((__le16 *)(smib->value)));
4927 -                       lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n",
4928 -                                   priv->adapter->fragthsd);
4929 +                       lbs_deb_cmd("SNMP_RESP: frag threshold %u\n",
4930 +                                   priv->fragthsd);
4931                         break;
4932 -               case rtsthresh_i:
4933 -                       priv->adapter->rtsthsd =
4934 +               case RTSTHRESH_I:
4935 +                       priv->rtsthsd =
4936                                 le16_to_cpu(*((__le16 *)(smib->value)));
4937 -                       lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n",
4938 -                                   priv->adapter->rtsthsd);
4939 +                       lbs_deb_cmd("SNMP_RESP: rts threshold %u\n",
4940 +                                   priv->rtsthsd);
4941                         break;
4942 -               case short_retrylim_i:
4943 -                       priv->adapter->txretrycount =
4944 +               case SHORT_RETRYLIM_I:
4945 +                       priv->txretrycount =
4946                                 le16_to_cpu(*((__le16 *)(smib->value)));
4947 -                       lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n",
4948 -                                   priv->adapter->rtsthsd);
4949 +                       lbs_deb_cmd("SNMP_RESP: tx retry count %u\n",
4950 +                                   priv->rtsthsd);
4951                         break;
4952                 default:
4953                         break;
4954 @@ -303,29 +227,29 @@ static int wlan_ret_802_11_snmp_mib(wlan
4955         return 0;
4956  }
4957  
4958 -static int wlan_ret_802_11_key_material(wlan_private * priv,
4959 +static int lbs_ret_802_11_key_material(struct lbs_private *priv,
4960                                         struct cmd_ds_command *resp)
4961  {
4962         struct cmd_ds_802_11_key_material *pkeymaterial =
4963             &resp->params.keymaterial;
4964 -       wlan_adapter *adapter = priv->adapter;
4965         u16 action = le16_to_cpu(pkeymaterial->action);
4966  
4967         lbs_deb_enter(LBS_DEB_CMD);
4968  
4969         /* Copy the returned key to driver private data */
4970 -       if (action == cmd_act_get) {
4971 +       if (action == CMD_ACT_GET) {
4972                 u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet;
4973                 u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size));
4974  
4975                 while (buf_ptr < resp_end) {
4976                         struct MrvlIEtype_keyParamSet * pkeyparamset =
4977                             (struct MrvlIEtype_keyParamSet *) buf_ptr;
4978 -                       struct WLAN_802_11_KEY * pkey;
4979 -                       u16 key_info = le16_to_cpu(pkeyparamset->keyinfo);
4980 +                       struct enc_key * pkey;
4981                         u16 param_set_len = le16_to_cpu(pkeyparamset->length);
4982 -                       u8 * end;
4983                         u16 key_len = le16_to_cpu(pkeyparamset->keylen);
4984 +                       u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo);
4985 +                       u16 key_type = le16_to_cpu(pkeyparamset->keytypeid);
4986 +                       u8 * end;
4987  
4988                         end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type)
4989                                                   + sizeof (pkeyparamset->length)
4990 @@ -334,20 +258,20 @@ static int wlan_ret_802_11_key_material(
4991                         if (end > resp_end)
4992                                 break;
4993  
4994 -                       if (key_info & KEY_INFO_WPA_UNICAST)
4995 -                               pkey = &adapter->wpa_unicast_key;
4996 -                       else if (key_info & KEY_INFO_WPA_MCAST)
4997 -                               pkey = &adapter->wpa_mcast_key;
4998 +                       if (key_flags & KEY_INFO_WPA_UNICAST)
4999 +                               pkey = &priv->wpa_unicast_key;
5000 +                       else if (key_flags & KEY_INFO_WPA_MCAST)
5001 +                               pkey = &priv->wpa_mcast_key;
5002                         else
5003                                 break;
5004  
5005                         /* Copy returned key into driver */
5006 -                       memset(pkey, 0, sizeof(struct WLAN_802_11_KEY));
5007 +                       memset(pkey, 0, sizeof(struct enc_key));
5008                         if (key_len > sizeof(pkey->key))
5009                                 break;
5010 -                       pkey->type = le16_to_cpu(pkeyparamset->keytypeid);
5011 -                       pkey->flags = le16_to_cpu(pkeyparamset->keyinfo);
5012 -                       pkey->len = le16_to_cpu(pkeyparamset->keylen);
5013 +                       pkey->type = key_type;
5014 +                       pkey->flags = key_flags;
5015 +                       pkey->len = key_len;
5016                         memcpy(pkey->key, pkeyparamset->key, pkey->len);
5017  
5018                         buf_ptr = end + 1;
5019 @@ -358,157 +282,91 @@ static int wlan_ret_802_11_key_material(
5020         return 0;
5021  }
5022  
5023 -static int wlan_ret_802_11_mac_address(wlan_private * priv,
5024 +static int lbs_ret_802_11_mac_address(struct lbs_private *priv,
5025                                        struct cmd_ds_command *resp)
5026  {
5027         struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
5028 -       wlan_adapter *adapter = priv->adapter;
5029  
5030         lbs_deb_enter(LBS_DEB_CMD);
5031  
5032 -       memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
5033 +       memcpy(priv->current_addr, macadd->macadd, ETH_ALEN);
5034  
5035         lbs_deb_enter(LBS_DEB_CMD);
5036         return 0;
5037  }
5038  
5039 -static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
5040 +static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv,
5041                                        struct cmd_ds_command *resp)
5042  {
5043         struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
5044 -       wlan_adapter *adapter = priv->adapter;
5045  
5046         lbs_deb_enter(LBS_DEB_CMD);
5047  
5048 -       adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
5049 -
5050 -       lbs_deb_cmd("Current TxPower Level = %d\n", adapter->txpowerlevel);
5051 -
5052 -       lbs_deb_enter(LBS_DEB_CMD);
5053 -       return 0;
5054 -}
5055 -
5056 -static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
5057 -                                     struct cmd_ds_command *resp)
5058 -{
5059 -       struct cmd_ds_802_11_rf_antenna *pAntenna = &resp->params.rant;
5060 -       wlan_adapter *adapter = priv->adapter;
5061 -       u16 action = le16_to_cpu(pAntenna->action);
5062 -
5063 -       if (action == cmd_act_get_rx)
5064 -               adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode);
5065 -
5066 -       if (action == cmd_act_get_tx)
5067 -               adapter->txantennamode = le16_to_cpu(pAntenna->antennamode);
5068 +       priv->txpowerlevel = le16_to_cpu(rtp->currentlevel);
5069  
5070 -       lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
5071 -              action, le16_to_cpu(pAntenna->antennamode));
5072 +       lbs_deb_cmd("TX power currently %d\n", priv->txpowerlevel);
5073  
5074 +       lbs_deb_leave(LBS_DEB_CMD);
5075         return 0;
5076  }
5077  
5078 -static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
5079 +static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
5080                                               struct cmd_ds_command *resp)
5081  {
5082         struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
5083 -       wlan_adapter *adapter = priv->adapter;
5084  
5085         lbs_deb_enter(LBS_DEB_CMD);
5086  
5087 -       if (rates->action == cmd_act_get) {
5088 -               adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);
5089 -               adapter->ratebitmap = le16_to_cpu(rates->bitmap);
5090 +       if (rates->action == CMD_ACT_GET) {
5091 +               priv->enablehwauto = le16_to_cpu(rates->enablehwauto);
5092 +               priv->ratebitmap = le16_to_cpu(rates->bitmap);
5093         }
5094  
5095 -       lbs_deb_enter(LBS_DEB_CMD);
5096 +       lbs_deb_leave(LBS_DEB_CMD);
5097         return 0;
5098  }
5099  
5100 -static int wlan_ret_802_11_data_rate(wlan_private * priv,
5101 -                                    struct cmd_ds_command *resp)
5102 -{
5103 -       struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
5104 -       wlan_adapter *adapter = priv->adapter;
5105 -       u8 dot11datarate;
5106 -
5107 -       lbs_deb_enter(LBS_DEB_CMD);
5108 -
5109 -       lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
5110 -               (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate));
5111 -
5112 -       dot11datarate = pdatarate->datarate[0];
5113 -       if (pdatarate->action == cpu_to_le16(cmd_act_get_tx_rate)) {
5114 -               memcpy(adapter->libertas_supported_rates, pdatarate->datarate,
5115 -                      sizeof(adapter->libertas_supported_rates));
5116 -       }
5117 -       adapter->datarate = libertas_index_to_data_rate(dot11datarate);
5118 -
5119 -       lbs_deb_enter(LBS_DEB_CMD);
5120 -       return 0;
5121 -}
5122 -
5123 -static int wlan_ret_802_11_rf_channel(wlan_private * priv,
5124 -                                     struct cmd_ds_command *resp)
5125 -{
5126 -       struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
5127 -       wlan_adapter *adapter = priv->adapter;
5128 -       u16 action = le16_to_cpu(rfchannel->action);
5129 -       u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
5130 -
5131 -       lbs_deb_enter(LBS_DEB_CMD);
5132 -
5133 -       if (action == cmd_opt_802_11_rf_channel_get
5134 -           && adapter->curbssparams.channel != newchannel) {
5135 -               lbs_deb_cmd("channel Switch: %d to %d\n",
5136 -                      adapter->curbssparams.channel, newchannel);
5137 -
5138 -               /* Update the channel again */
5139 -               adapter->curbssparams.channel = newchannel;
5140 -       }
5141 -
5142 -       lbs_deb_enter(LBS_DEB_CMD);
5143 -       return 0;
5144 -}
5145 -
5146 -static int wlan_ret_802_11_rssi(wlan_private * priv,
5147 +static int lbs_ret_802_11_rssi(struct lbs_private *priv,
5148                                 struct cmd_ds_command *resp)
5149  {
5150         struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
5151 -       wlan_adapter *adapter = priv->adapter;
5152 +
5153 +       lbs_deb_enter(LBS_DEB_CMD);
5154  
5155         /* store the non average value */
5156 -       adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
5157 -       adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
5158 +       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
5159 +       priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
5160  
5161 -       adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
5162 -       adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
5163 +       priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
5164 +       priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
5165  
5166 -       adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
5167 -           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
5168 -                    adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
5169 +       priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
5170 +           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
5171 +                    priv->NF[TYPE_BEACON][TYPE_NOAVG]);
5172  
5173 -       adapter->RSSI[TYPE_BEACON][TYPE_AVG] =
5174 -           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
5175 -                    adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
5176 +       priv->RSSI[TYPE_BEACON][TYPE_AVG] =
5177 +           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
5178 +                    priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
5179  
5180 -       lbs_deb_cmd("Beacon RSSI value = 0x%x\n",
5181 -              adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
5182 +       lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
5183 +              priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
5184 +              priv->RSSI[TYPE_BEACON][TYPE_AVG]);
5185  
5186 +       lbs_deb_leave(LBS_DEB_CMD);
5187         return 0;
5188  }
5189  
5190 -static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
5191 +static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
5192                                   struct cmd_ds_command *resp)
5193  {
5194 -       wlan_adapter *adapter = priv->adapter;
5195 -       struct wlan_ioctl_regrdwr *pbuf;
5196 -       pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
5197 +       struct lbs_ioctl_regrdwr *pbuf;
5198 +       pbuf = (struct lbs_ioctl_regrdwr *) priv->prdeeprom;
5199  
5200 -       lbs_deb_cmd("eeprom read len=%x\n",
5201 +       lbs_deb_enter_args(LBS_DEB_CMD, "len %d",
5202                le16_to_cpu(resp->params.rdeeprom.bytecount));
5203         if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
5204                 pbuf->NOB = 0;
5205 -               lbs_deb_cmd("eeprom read return length is too big\n");
5206 +               lbs_deb_cmd("EEPROM read length too big\n");
5207                 return -1;
5208         }
5209         pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
5210 @@ -516,454 +374,510 @@ static int wlan_ret_802_11_eeprom_access
5211  
5212                 memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value,
5213                        le16_to_cpu(resp->params.rdeeprom.bytecount));
5214 -               lbs_dbg_hex("adapter", (char *)&pbuf->value,
5215 +               lbs_deb_hex(LBS_DEB_CMD, "EEPROM", (char *)&pbuf->value,
5216                         le16_to_cpu(resp->params.rdeeprom.bytecount));
5217         }
5218 +       lbs_deb_leave(LBS_DEB_CMD);
5219         return 0;
5220  }
5221  
5222 -static int wlan_ret_get_log(wlan_private * priv,
5223 +static int lbs_ret_get_log(struct lbs_private *priv,
5224                             struct cmd_ds_command *resp)
5225  {
5226         struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog;
5227 -       wlan_adapter *adapter = priv->adapter;
5228  
5229         lbs_deb_enter(LBS_DEB_CMD);
5230  
5231         /* Stored little-endian */
5232 -       memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
5233 +       memcpy(&priv->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
5234  
5235 -       lbs_deb_enter(LBS_DEB_CMD);
5236 +       lbs_deb_leave(LBS_DEB_CMD);
5237         return 0;
5238  }
5239  
5240 -static int libertas_ret_802_11_enable_rsn(wlan_private * priv,
5241 +static int lbs_ret_802_11_enable_rsn(struct lbs_private *priv,
5242                                            struct cmd_ds_command *resp)
5243  {
5244         struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn;
5245 -       wlan_adapter *adapter = priv->adapter;
5246 -       u32 * pdata_buf = adapter->cur_cmd->pdata_buf;
5247 +       uint32_t * pdata_buf = (uint32_t *)priv->cur_cmd->callback_arg;
5248  
5249         lbs_deb_enter(LBS_DEB_CMD);
5250  
5251 -       if (enable_rsn->action == cpu_to_le16(cmd_act_get)) {
5252 +       if (enable_rsn->action == cpu_to_le16(CMD_ACT_GET)) {
5253                 if (pdata_buf)
5254 -                       *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable);
5255 +                       *pdata_buf = (uint32_t) le16_to_cpu(enable_rsn->enable);
5256 +       }
5257 +
5258 +       lbs_deb_leave(LBS_DEB_CMD);
5259 +       return 0;
5260 +}
5261 +
5262 +static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv,
5263 +                                       struct cmd_ds_command *resp)
5264 +{
5265 +       struct cmd_ds_802_11_beacon_control *bcn_ctrl =
5266 +           &resp->params.bcn_ctrl;
5267 +
5268 +       lbs_deb_enter(LBS_DEB_CMD);
5269 +
5270 +       if (bcn_ctrl->action == CMD_ACT_GET) {
5271 +               priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
5272 +               priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
5273         }
5274  
5275         lbs_deb_enter(LBS_DEB_CMD);
5276         return 0;
5277  }
5278  
5279 -static inline int handle_cmd_response(u16 respcmd,
5280 -                                     struct cmd_ds_command *resp,
5281 -                                     wlan_private *priv)
5282 +static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv,
5283 +       struct cmd_ds_command *resp)
5284  {
5285 +       struct cmd_ds_802_11_subscribe_event *cmd_event =
5286 +               &resp->params.subscribe_event;
5287 +       struct cmd_ds_802_11_subscribe_event *dst_event =
5288 +               (void *)priv->cur_cmd->callback_arg;
5289 +
5290 +       lbs_deb_enter(LBS_DEB_CMD);
5291 +
5292 +       if (dst_event->action == cpu_to_le16(CMD_ACT_GET)) {
5293 +               dst_event->events = cmd_event->events;
5294 +               memcpy(dst_event->tlv, cmd_event->tlv, sizeof(dst_event->tlv));
5295 +       }
5296 +
5297 +       lbs_deb_leave(LBS_DEB_CMD);
5298 +       return 0;
5299 +}
5300 +
5301 +static inline int handle_cmd_response(struct lbs_private *priv,
5302 +                                     unsigned long dummy,
5303 +                                     struct cmd_header *cmd_response)
5304 +{
5305 +       struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response;
5306         int ret = 0;
5307         unsigned long flags;
5308 -       wlan_adapter *adapter = priv->adapter;
5309 +       uint16_t respcmd = le16_to_cpu(resp->command);
5310  
5311 -       switch (respcmd) {
5312 -       case cmd_ret_mac_reg_access:
5313 -       case cmd_ret_bbp_reg_access:
5314 -       case cmd_ret_rf_reg_access:
5315 -               ret = wlan_ret_reg_access(priv, respcmd, resp);
5316 -               break;
5317 +       lbs_deb_enter(LBS_DEB_HOST);
5318  
5319 -       case cmd_ret_hw_spec_info:
5320 -               ret = wlan_ret_get_hw_spec(priv, resp);
5321 +       switch (respcmd) {
5322 +       case CMD_RET(CMD_MAC_REG_ACCESS):
5323 +       case CMD_RET(CMD_BBP_REG_ACCESS):
5324 +       case CMD_RET(CMD_RF_REG_ACCESS):
5325 +               ret = lbs_ret_reg_access(priv, respcmd, resp);
5326                 break;
5327  
5328 -       case cmd_ret_802_11_scan:
5329 -               ret = libertas_ret_80211_scan(priv, resp);
5330 +       case CMD_RET(CMD_802_11_SCAN):
5331 +               ret = lbs_ret_80211_scan(priv, resp);
5332                 break;
5333  
5334 -       case cmd_ret_802_11_get_log:
5335 -               ret = wlan_ret_get_log(priv, resp);
5336 +       case CMD_RET(CMD_802_11_GET_LOG):
5337 +               ret = lbs_ret_get_log(priv, resp);
5338                 break;
5339  
5340 -       case cmd_ret_802_11_associate:
5341 -       case cmd_ret_802_11_reassociate:
5342 -               ret = libertas_ret_80211_associate(priv, resp);
5343 +       case CMD_RET_802_11_ASSOCIATE:
5344 +       case CMD_RET(CMD_802_11_ASSOCIATE):
5345 +       case CMD_RET(CMD_802_11_REASSOCIATE):
5346 +               ret = lbs_ret_80211_associate(priv, resp);
5347                 break;
5348  
5349 -       case cmd_ret_802_11_disassociate:
5350 -       case cmd_ret_802_11_deauthenticate:
5351 -               ret = libertas_ret_80211_disassociate(priv, resp);
5352 +       case CMD_RET(CMD_802_11_DISASSOCIATE):
5353 +       case CMD_RET(CMD_802_11_DEAUTHENTICATE):
5354 +               ret = lbs_ret_80211_disassociate(priv, resp);
5355                 break;
5356  
5357 -       case cmd_ret_802_11_ad_hoc_start:
5358 -       case cmd_ret_802_11_ad_hoc_join:
5359 -               ret = libertas_ret_80211_ad_hoc_start(priv, resp);
5360 +       case CMD_RET(CMD_802_11_AD_HOC_START):
5361 +       case CMD_RET(CMD_802_11_AD_HOC_JOIN):
5362 +               ret = lbs_ret_80211_ad_hoc_start(priv, resp);
5363                 break;
5364  
5365 -       case cmd_ret_802_11_stat:
5366 -               ret = wlan_ret_802_11_stat(priv, resp);
5367 +       case CMD_RET(CMD_802_11_GET_STAT):
5368 +               ret = lbs_ret_802_11_stat(priv, resp);
5369                 break;
5370  
5371 -       case cmd_ret_802_11_snmp_mib:
5372 -               ret = wlan_ret_802_11_snmp_mib(priv, resp);
5373 +       case CMD_RET(CMD_802_11_SNMP_MIB):
5374 +               ret = lbs_ret_802_11_snmp_mib(priv, resp);
5375                 break;
5376  
5377 -       case cmd_ret_802_11_rf_tx_power:
5378 -               ret = wlan_ret_802_11_rf_tx_power(priv, resp);
5379 +       case CMD_RET(CMD_802_11_RF_TX_POWER):
5380 +               ret = lbs_ret_802_11_rf_tx_power(priv, resp);
5381                 break;
5382  
5383 -       case cmd_ret_802_11_set_afc:
5384 -       case cmd_ret_802_11_get_afc:
5385 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5386 -               memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc,
5387 +       case CMD_RET(CMD_802_11_SET_AFC):
5388 +       case CMD_RET(CMD_802_11_GET_AFC):
5389 +               spin_lock_irqsave(&priv->driver_lock, flags);
5390 +               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc,
5391                         sizeof(struct cmd_ds_802_11_afc));
5392 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5393 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5394  
5395                 break;
5396 -       case cmd_ret_802_11_rf_antenna:
5397 -               ret = wlan_ret_802_11_rf_antenna(priv, resp);
5398 -               break;
5399  
5400 -       case cmd_ret_mac_multicast_adr:
5401 -       case cmd_ret_mac_control:
5402 -       case cmd_ret_802_11_set_wep:
5403 -       case cmd_ret_802_11_reset:
5404 -       case cmd_ret_802_11_authenticate:
5405 -       case cmd_ret_802_11_radio_control:
5406 -       case cmd_ret_802_11_beacon_stop:
5407 +       case CMD_RET(CMD_802_11_SET_WEP):
5408 +       case CMD_RET(CMD_802_11_RESET):
5409 +       case CMD_RET(CMD_802_11_AUTHENTICATE):
5410 +       case CMD_RET(CMD_802_11_RADIO_CONTROL):
5411 +       case CMD_RET(CMD_802_11_BEACON_STOP):
5412                 break;
5413  
5414 -       case cmd_ret_802_11_enable_rsn:
5415 -               ret = libertas_ret_802_11_enable_rsn(priv, resp);
5416 +       case CMD_RET(CMD_802_11_ENABLE_RSN):
5417 +               ret = lbs_ret_802_11_enable_rsn(priv, resp);
5418                 break;
5419  
5420 -       case cmd_ret_802_11_data_rate:
5421 -               ret = wlan_ret_802_11_data_rate(priv, resp);
5422 -               break;
5423 -       case cmd_ret_802_11_rate_adapt_rateset:
5424 -               ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp);
5425 -               break;
5426 -       case cmd_ret_802_11_rf_channel:
5427 -               ret = wlan_ret_802_11_rf_channel(priv, resp);
5428 +       case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
5429 +               ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
5430                 break;
5431  
5432 -       case cmd_ret_802_11_rssi:
5433 -               ret = wlan_ret_802_11_rssi(priv, resp);
5434 +       case CMD_RET(CMD_802_11_RSSI):
5435 +               ret = lbs_ret_802_11_rssi(priv, resp);
5436                 break;
5437  
5438 -       case cmd_ret_802_11_mac_address:
5439 -               ret = wlan_ret_802_11_mac_address(priv, resp);
5440 +       case CMD_RET(CMD_802_11_MAC_ADDRESS):
5441 +               ret = lbs_ret_802_11_mac_address(priv, resp);
5442                 break;
5443  
5444 -       case cmd_ret_802_11_ad_hoc_stop:
5445 -               ret = libertas_ret_80211_ad_hoc_stop(priv, resp);
5446 +       case CMD_RET(CMD_802_11_AD_HOC_STOP):
5447 +               ret = lbs_ret_80211_ad_hoc_stop(priv, resp);
5448                 break;
5449  
5450 -       case cmd_ret_802_11_key_material:
5451 -               lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n");
5452 -               ret = wlan_ret_802_11_key_material(priv, resp);
5453 +       case CMD_RET(CMD_802_11_KEY_MATERIAL):
5454 +               ret = lbs_ret_802_11_key_material(priv, resp);
5455                 break;
5456  
5457 -       case cmd_ret_802_11_eeprom_access:
5458 -               ret = wlan_ret_802_11_eeprom_access(priv, resp);
5459 +       case CMD_RET(CMD_802_11_EEPROM_ACCESS):
5460 +               ret = lbs_ret_802_11_eeprom_access(priv, resp);
5461                 break;
5462  
5463 -       case cmd_ret_802_11d_domain_info:
5464 -               ret = libertas_ret_802_11d_domain_info(priv, resp);
5465 +       case CMD_RET(CMD_802_11D_DOMAIN_INFO):
5466 +               ret = lbs_ret_802_11d_domain_info(priv, resp);
5467                 break;
5468  
5469 -       case cmd_ret_802_11_sleep_params:
5470 -               ret = wlan_ret_802_11_sleep_params(priv, resp);
5471 +       case CMD_RET(CMD_802_11_SLEEP_PARAMS):
5472 +               ret = lbs_ret_802_11_sleep_params(priv, resp);
5473                 break;
5474 -       case cmd_ret_802_11_inactivity_timeout:
5475 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5476 -               *((u16 *) adapter->cur_cmd->pdata_buf) =
5477 +       case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT):
5478 +               spin_lock_irqsave(&priv->driver_lock, flags);
5479 +               *((uint16_t *) priv->cur_cmd->callback_arg) =
5480                     le16_to_cpu(resp->params.inactivity_timeout.timeout);
5481 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5482 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5483                 break;
5484  
5485 -       case cmd_ret_802_11_tpc_cfg:
5486 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5487 -               memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg,
5488 +       case CMD_RET(CMD_802_11_TPC_CFG):
5489 +               spin_lock_irqsave(&priv->driver_lock, flags);
5490 +               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
5491                         sizeof(struct cmd_ds_802_11_tpc_cfg));
5492 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5493 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5494                 break;
5495 -       case cmd_ret_802_11_led_gpio_ctrl:
5496 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5497 -               memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio,
5498 +       case CMD_RET(CMD_802_11_LED_GPIO_CTRL):
5499 +               spin_lock_irqsave(&priv->driver_lock, flags);
5500 +               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.ledgpio,
5501                         sizeof(struct cmd_ds_802_11_led_ctrl));
5502 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5503 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5504                 break;
5505 -       case cmd_ret_802_11_pwr_cfg:
5506 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5507 -               memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg,
5508 +       case CMD_RET(CMD_802_11_SUBSCRIBE_EVENT):
5509 +               ret = lbs_ret_802_11_subscribe_event(priv, resp);
5510 +               break;
5511 +
5512 +       case CMD_RET(CMD_802_11_PWR_CFG):
5513 +               spin_lock_irqsave(&priv->driver_lock, flags);
5514 +               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.pwrcfg,
5515                         sizeof(struct cmd_ds_802_11_pwr_cfg));
5516 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5517 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5518  
5519                 break;
5520  
5521 -       case cmd_ret_get_tsf:
5522 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5523 -               memcpy(priv->adapter->cur_cmd->pdata_buf,
5524 +       case CMD_RET(CMD_GET_TSF):
5525 +               spin_lock_irqsave(&priv->driver_lock, flags);
5526 +               memcpy((void *)priv->cur_cmd->callback_arg,
5527                        &resp->params.gettsf.tsfvalue, sizeof(u64));
5528 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5529 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5530                 break;
5531 -       case cmd_ret_bt_access:
5532 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5533 -               if (adapter->cur_cmd->pdata_buf)
5534 -                       memcpy(adapter->cur_cmd->pdata_buf,
5535 +       case CMD_RET(CMD_BT_ACCESS):
5536 +               spin_lock_irqsave(&priv->driver_lock, flags);
5537 +               if (priv->cur_cmd->callback_arg)
5538 +                       memcpy((void *)priv->cur_cmd->callback_arg,
5539                                &resp->params.bt.addr1, 2 * ETH_ALEN);
5540 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5541 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5542                 break;
5543 -       case cmd_ret_fwt_access:
5544 -               spin_lock_irqsave(&adapter->driver_lock, flags);
5545 -               if (adapter->cur_cmd->pdata_buf)
5546 -                       memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt,
5547 +       case CMD_RET(CMD_FWT_ACCESS):
5548 +               spin_lock_irqsave(&priv->driver_lock, flags);
5549 +               if (priv->cur_cmd->callback_arg)
5550 +                       memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt,
5551                                sizeof(resp->params.fwt));
5552 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5553 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5554                 break;
5555 -       case cmd_ret_mesh_access:
5556 -               if (adapter->cur_cmd->pdata_buf)
5557 -                       memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
5558 -                              sizeof(resp->params.mesh));
5559 -               break;
5560 -       case cmd_rte_802_11_tx_rate_query:
5561 -               priv->adapter->txrate = resp->params.txrate.txrate;
5562 +       case CMD_RET(CMD_802_11_BEACON_CTRL):
5563 +               ret = lbs_ret_802_11_bcn_ctrl(priv, resp);
5564                 break;
5565 +
5566         default:
5567 -               lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n",
5568 -                           resp->command);
5569 +               lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n",
5570 +                          le16_to_cpu(resp->command));
5571                 break;
5572         }
5573 +       lbs_deb_leave(LBS_DEB_HOST);
5574         return ret;
5575  }
5576  
5577 -int libertas_process_rx_command(wlan_private * priv)
5578 +int lbs_process_rx_command(struct lbs_private *priv)
5579  {
5580 -       u16 respcmd;
5581 -       struct cmd_ds_command *resp;
5582 -       wlan_adapter *adapter = priv->adapter;
5583 +       uint16_t respcmd, curcmd;
5584 +       struct cmd_header *resp;
5585         int ret = 0;
5586 -       ulong flags;
5587 -       u16 result;
5588 -
5589 -       lbs_deb_enter(LBS_DEB_CMD);
5590 -
5591 -       lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies);
5592 +       unsigned long flags;
5593 +       uint16_t result;
5594  
5595 -       /* Now we got response from FW, cancel the command timer */
5596 -       del_timer(&adapter->command_timer);
5597 +       lbs_deb_enter(LBS_DEB_HOST);
5598  
5599 -       mutex_lock(&adapter->lock);
5600 -       spin_lock_irqsave(&adapter->driver_lock, flags);
5601 +       mutex_lock(&priv->lock);
5602 +       spin_lock_irqsave(&priv->driver_lock, flags);
5603  
5604 -       if (!adapter->cur_cmd) {
5605 -               lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
5606 +       if (!priv->cur_cmd) {
5607 +               lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
5608                 ret = -1;
5609 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5610 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5611                 goto done;
5612         }
5613 -       resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
5614  
5615 -       lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr,
5616 -                   priv->upld_len);
5617 +       resp = (void *)priv->upld_buf;
5618  
5619 -       respcmd = le16_to_cpu(resp->command);
5620 +       curcmd = le16_to_cpu(resp->command);
5621  
5622 +       respcmd = le16_to_cpu(resp->command);
5623         result = le16_to_cpu(resp->result);
5624  
5625 -       lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd,
5626 -                   result, priv->upld_len);
5627 +       lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n",
5628 +                    respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies);
5629 +       lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, priv->upld_len);
5630 +
5631 +       if (resp->seqnum != resp->seqnum) {
5632 +               lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
5633 +                           le16_to_cpu(resp->seqnum), le16_to_cpu(resp->seqnum));
5634 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5635 +               ret = -1;
5636 +               goto done;
5637 +       }
5638 +       if (respcmd != CMD_RET(curcmd) &&
5639 +           respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) {
5640 +               lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
5641 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5642 +               ret = -1;
5643 +               goto done;
5644 +       }
5645  
5646 -       if (!(respcmd & 0x8000)) {
5647 -               lbs_deb_cmd("Invalid response to command!");
5648 -               adapter->cur_cmd_retcode = -1;
5649 -               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
5650 -               adapter->nr_cmd_pending--;
5651 -               adapter->cur_cmd = NULL;
5652 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5653 +       if (resp->result == cpu_to_le16(0x0004)) {
5654 +               /* 0x0004 means -EAGAIN. Drop the response, let it time out
5655 +                  and be resubmitted */
5656 +               lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
5657 +                           le16_to_cpu(resp->command));
5658 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5659                 ret = -1;
5660                 goto done;
5661         }
5662  
5663 +       /* Now we got response from FW, cancel the command timer */
5664 +       del_timer(&priv->command_timer);
5665 +       priv->cmd_timed_out = 0;
5666 +       if (priv->nr_retries) {
5667 +               lbs_pr_info("Received result %x to command %x after %d retries\n",
5668 +                           result, curcmd, priv->nr_retries);
5669 +               priv->nr_retries = 0;
5670 +       }
5671 +
5672         /* Store the response code to cur_cmd_retcode. */
5673 -       adapter->cur_cmd_retcode = result;;
5674 +       priv->cur_cmd_retcode = result;
5675  
5676 -       if (respcmd == cmd_ret_802_11_ps_mode) {
5677 -               struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
5678 +       if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
5679 +               struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
5680                 u16 action = le16_to_cpu(psmode->action);
5681  
5682 -               lbs_deb_cmd(
5683 -                      "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
5684 +               lbs_deb_host(
5685 +                      "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n",
5686                        result, action);
5687  
5688                 if (result) {
5689 -                       lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n",
5690 +                       lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n",
5691                                     result);
5692                         /*
5693                          * We should not re-try enter-ps command in
5694                          * ad-hoc mode. It takes place in
5695 -                        * libertas_execute_next_command().
5696 +                        * lbs_execute_next_command().
5697                          */
5698 -                       if (adapter->mode == IW_MODE_ADHOC &&
5699 -                           action == cmd_subcmd_enter_ps)
5700 -                               adapter->psmode = wlan802_11powermodecam;
5701 -               } else if (action == cmd_subcmd_enter_ps) {
5702 -                       adapter->needtowakeup = 0;
5703 -                       adapter->psstate = PS_STATE_AWAKE;
5704 +                       if (priv->mode == IW_MODE_ADHOC &&
5705 +                           action == CMD_SUBCMD_ENTER_PS)
5706 +                               priv->psmode = LBS802_11POWERMODECAM;
5707 +               } else if (action == CMD_SUBCMD_ENTER_PS) {
5708 +                       priv->needtowakeup = 0;
5709 +                       priv->psstate = PS_STATE_AWAKE;
5710  
5711 -                       lbs_deb_cmd("CMD_RESP: Enter_PS command response\n");
5712 -                       if (adapter->connect_status != libertas_connected) {
5713 +                       lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
5714 +                       if (priv->connect_status != LBS_CONNECTED) {
5715                                 /*
5716                                  * When Deauth Event received before Enter_PS command
5717                                  * response, We need to wake up the firmware.
5718                                  */
5719 -                               lbs_deb_cmd(
5720 -                                      "Disconnected, Going to invoke libertas_ps_wakeup\n");
5721 +                               lbs_deb_host(
5722 +                                      "disconnected, invoking lbs_ps_wakeup\n");
5723  
5724 -                               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5725 -                               mutex_unlock(&adapter->lock);
5726 -                               libertas_ps_wakeup(priv, 0);
5727 -                               mutex_lock(&adapter->lock);
5728 -                               spin_lock_irqsave(&adapter->driver_lock, flags);
5729 +                               spin_unlock_irqrestore(&priv->driver_lock, flags);
5730 +                               mutex_unlock(&priv->lock);
5731 +                               lbs_ps_wakeup(priv, 0);
5732 +                               mutex_lock(&priv->lock);
5733 +                               spin_lock_irqsave(&priv->driver_lock, flags);
5734                         }
5735 -               } else if (action == cmd_subcmd_exit_ps) {
5736 -                       adapter->needtowakeup = 0;
5737 -                       adapter->psstate = PS_STATE_FULL_POWER;
5738 -                       lbs_deb_cmd("CMD_RESP: Exit_PS command response\n");
5739 +               } else if (action == CMD_SUBCMD_EXIT_PS) {
5740 +                       priv->needtowakeup = 0;
5741 +                       priv->psstate = PS_STATE_FULL_POWER;
5742 +                       lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
5743                 } else {
5744 -                       lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action);
5745 +                       lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
5746                 }
5747  
5748 -               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
5749 -               adapter->nr_cmd_pending--;
5750 -               adapter->cur_cmd = NULL;
5751 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5752 +               lbs_complete_command(priv, priv->cur_cmd, result);
5753 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5754  
5755                 ret = 0;
5756                 goto done;
5757         }
5758  
5759 -       if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) {
5760 -               /* Copy the response back to response buffer */
5761 -               memcpy(adapter->cur_cmd->pdata_buf, resp, resp->size);
5762 -
5763 -               adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD;
5764 -       }
5765 -
5766         /* If the command is not successful, cleanup and return failure */
5767         if ((result != 0 || !(respcmd & 0x8000))) {
5768 -               lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n",
5769 -                      respcmd, result);
5770 +               lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
5771 +                      result, respcmd);
5772                 /*
5773                  * Handling errors here
5774                  */
5775                 switch (respcmd) {
5776 -               case cmd_ret_hw_spec_info:
5777 -               case cmd_ret_802_11_reset:
5778 -                       lbs_deb_cmd("CMD_RESP: Reset command failed\n");
5779 +               case CMD_RET(CMD_GET_HW_SPEC):
5780 +               case CMD_RET(CMD_802_11_RESET):
5781 +                       lbs_deb_host("CMD_RESP: reset failed\n");
5782                         break;
5783  
5784                 }
5785 -
5786 -               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
5787 -               adapter->nr_cmd_pending--;
5788 -               adapter->cur_cmd = NULL;
5789 -               spin_unlock_irqrestore(&adapter->driver_lock, flags);
5790 +               lbs_complete_command(priv, priv->cur_cmd, result);
5791 +               spin_unlock_irqrestore(&priv->driver_lock, flags);
5792  
5793                 ret = -1;
5794                 goto done;
5795         }
5796  
5797 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
5798 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
5799  
5800 -       ret = handle_cmd_response(respcmd, resp, priv);
5801 +       if (priv->cur_cmd && priv->cur_cmd->callback) {
5802 +               ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
5803 +                               resp);
5804 +       } else
5805 +               ret = handle_cmd_response(priv, 0, resp);
5806  
5807 -       spin_lock_irqsave(&adapter->driver_lock, flags);
5808 -       if (adapter->cur_cmd) {
5809 +       spin_lock_irqsave(&priv->driver_lock, flags);
5810 +
5811 +       if (priv->cur_cmd) {
5812                 /* Clean up and Put current command back to cmdfreeq */
5813 -               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
5814 -               adapter->nr_cmd_pending--;
5815 -               WARN_ON(adapter->nr_cmd_pending > 128);
5816 -               adapter->cur_cmd = NULL;
5817 +               lbs_complete_command(priv, priv->cur_cmd, result);
5818         }
5819 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
5820 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
5821  
5822  done:
5823 -       mutex_unlock(&adapter->lock);
5824 -       lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
5825 +       mutex_unlock(&priv->lock);
5826 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
5827         return ret;
5828  }
5829  
5830 -int libertas_process_event(wlan_private * priv)
5831 +static int lbs_send_confirmwake(struct lbs_private *priv)
5832  {
5833 +       struct cmd_header *cmd = &priv->lbs_ps_confirm_wake;
5834         int ret = 0;
5835 -       wlan_adapter *adapter = priv->adapter;
5836 -       u32 eventcause;
5837  
5838 -       spin_lock_irq(&adapter->driver_lock);
5839 -       eventcause = adapter->eventcause;
5840 -       spin_unlock_irq(&adapter->driver_lock);
5841 +       lbs_deb_enter(LBS_DEB_HOST);
5842 +
5843 +       cmd->command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
5844 +       cmd->size = cpu_to_le16(sizeof(*cmd));
5845 +       cmd->seqnum = cpu_to_le16(++priv->seqnum);
5846 +       cmd->result = 0;
5847 +
5848 +       lbs_deb_host("SEND_WAKEC_CMD: before download\n");
5849 +
5850 +       lbs_deb_hex(LBS_DEB_HOST, "wake confirm command", (void *)cmd, sizeof(*cmd));
5851 +
5852 +       ret = priv->hw_host_to_card(priv, MVMS_CMD, (void *)cmd, sizeof(*cmd));
5853 +       if (ret)
5854 +               lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");
5855 +
5856 +       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
5857 +       return ret;
5858 +}
5859 +
5860 +int lbs_process_event(struct lbs_private *priv)
5861 +{
5862 +       int ret = 0;
5863 +       u32 eventcause;
5864  
5865         lbs_deb_enter(LBS_DEB_CMD);
5866  
5867 -       lbs_deb_cmd("EVENT Cause %x\n", eventcause);
5868 +       spin_lock_irq(&priv->driver_lock);
5869 +       eventcause = priv->eventcause >> SBI_EVENT_CAUSE_SHIFT;
5870 +       spin_unlock_irq(&priv->driver_lock);
5871  
5872 -       switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
5873 +       lbs_deb_cmd("event cause %d\n", eventcause);
5874 +
5875 +       switch (eventcause) {
5876         case MACREG_INT_CODE_LINK_SENSED:
5877                 lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
5878                 break;
5879  
5880         case MACREG_INT_CODE_DEAUTHENTICATED:
5881 -               lbs_deb_cmd("EVENT: Deauthenticated\n");
5882 -               libertas_mac_event_disconnected(priv);
5883 +               lbs_deb_cmd("EVENT: deauthenticated\n");
5884 +               lbs_mac_event_disconnected(priv);
5885                 break;
5886  
5887         case MACREG_INT_CODE_DISASSOCIATED:
5888 -               lbs_deb_cmd("EVENT: Disassociated\n");
5889 -               libertas_mac_event_disconnected(priv);
5890 +               lbs_deb_cmd("EVENT: disassociated\n");
5891 +               lbs_mac_event_disconnected(priv);
5892                 break;
5893  
5894 -       case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
5895 -               lbs_deb_cmd("EVENT: Link lost\n");
5896 -               libertas_mac_event_disconnected(priv);
5897 +       case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
5898 +               lbs_deb_cmd("EVENT: link lost\n");
5899 +               lbs_mac_event_disconnected(priv);
5900                 break;
5901  
5902         case MACREG_INT_CODE_PS_SLEEP:
5903 -               lbs_deb_cmd("EVENT: SLEEP\n");
5904 -               lbs_deb_cmd("_");
5905 +               lbs_deb_cmd("EVENT: sleep\n");
5906  
5907                 /* handle unexpected PS SLEEP event */
5908 -               if (adapter->psstate == PS_STATE_FULL_POWER) {
5909 +               if (priv->psstate == PS_STATE_FULL_POWER) {
5910                         lbs_deb_cmd(
5911 -                              "EVENT: In FULL POWER mode - ignore PS SLEEP\n");
5912 +                              "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
5913                         break;
5914                 }
5915 -               adapter->psstate = PS_STATE_PRE_SLEEP;
5916 +               priv->psstate = PS_STATE_PRE_SLEEP;
5917  
5918 -               libertas_ps_confirm_sleep(priv, (u16) adapter->psmode);
5919 +               lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
5920  
5921                 break;
5922  
5923 -       case MACREG_INT_CODE_PS_AWAKE:
5924 -               lbs_deb_cmd("EVENT: AWAKE \n");
5925 -               lbs_deb_cmd("|");
5926 +       case MACREG_INT_CODE_HOST_AWAKE:
5927 +               lbs_deb_cmd("EVENT: HOST_AWAKE\n");
5928 +               lbs_send_confirmwake(priv);
5929 +               break;
5930  
5931 +       case MACREG_INT_CODE_PS_AWAKE:
5932 +               lbs_deb_cmd("EVENT: awake\n");
5933                 /* handle unexpected PS AWAKE event */
5934 -               if (adapter->psstate == PS_STATE_FULL_POWER) {
5935 +               if (priv->psstate == PS_STATE_FULL_POWER) {
5936                         lbs_deb_cmd(
5937                                "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
5938                         break;
5939                 }
5940  
5941 -               adapter->psstate = PS_STATE_AWAKE;
5942 +               priv->psstate = PS_STATE_AWAKE;
5943  
5944 -               if (adapter->needtowakeup) {
5945 +               if (priv->needtowakeup) {
5946                         /*
5947                          * wait for the command processing to finish
5948                          * before resuming sending
5949 -                        * adapter->needtowakeup will be set to FALSE
5950 -                        * in libertas_ps_wakeup()
5951 +                        * priv->needtowakeup will be set to FALSE
5952 +                        * in lbs_ps_wakeup()
5953                          */
5954 -                       lbs_deb_cmd("Waking up...\n");
5955 -                       libertas_ps_wakeup(priv, 0);
5956 +                       lbs_deb_cmd("waking up ...\n");
5957 +                       lbs_ps_wakeup(priv, 0);
5958                 }
5959                 break;
5960  
5961 @@ -981,46 +895,51 @@ int libertas_process_event(wlan_private 
5962                 break;
5963  
5964         case MACREG_INT_CODE_ADHOC_BCN_LOST:
5965 -               lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n");
5966 +               lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
5967                 break;
5968  
5969         case MACREG_INT_CODE_RSSI_LOW:
5970 -               lbs_pr_alert( "EVENT: RSSI_LOW\n");
5971 +               lbs_pr_alert("EVENT: rssi low\n");
5972                 break;
5973         case MACREG_INT_CODE_SNR_LOW:
5974 -               lbs_pr_alert( "EVENT: SNR_LOW\n");
5975 +               lbs_pr_alert("EVENT: snr low\n");
5976                 break;
5977         case MACREG_INT_CODE_MAX_FAIL:
5978 -               lbs_pr_alert( "EVENT: MAX_FAIL\n");
5979 +               lbs_pr_alert("EVENT: max fail\n");
5980                 break;
5981         case MACREG_INT_CODE_RSSI_HIGH:
5982 -               lbs_pr_alert( "EVENT: RSSI_HIGH\n");
5983 +               lbs_pr_alert("EVENT: rssi high\n");
5984                 break;
5985         case MACREG_INT_CODE_SNR_HIGH:
5986 -               lbs_pr_alert( "EVENT: SNR_HIGH\n");
5987 +               lbs_pr_alert("EVENT: snr high\n");
5988                 break;
5989  
5990         case MACREG_INT_CODE_MESH_AUTO_STARTED:
5991 -               lbs_pr_alert( "EVENT: MESH_AUTO_STARTED\n");
5992 -               adapter->connect_status = libertas_connected ;
5993 -               if (priv->mesh_open == 1) {
5994 -                       netif_wake_queue(priv->mesh_dev) ;
5995 -                       netif_carrier_on(priv->mesh_dev) ;
5996 +               /* Ignore spurious autostart events if autostart is disabled */
5997 +               if (!priv->mesh_autostart_enabled) {
5998 +                       lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
5999 +                       break;
6000 +               }
6001 +               lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
6002 +               priv->mesh_connect_status = LBS_CONNECTED;
6003 +               if (priv->mesh_open) {
6004 +                       netif_carrier_on(priv->mesh_dev);
6005 +                       if (!priv->tx_pending_len)
6006 +                               netif_wake_queue(priv->mesh_dev);
6007                 }
6008 -               adapter->mode = IW_MODE_ADHOC ;
6009 +               priv->mode = IW_MODE_ADHOC;
6010                 schedule_work(&priv->sync_channel);
6011                 break;
6012  
6013         default:
6014 -               lbs_pr_alert( "EVENT: unknown event id: %#x\n",
6015 -                      eventcause >> SBI_EVENT_CAUSE_SHIFT);
6016 +               lbs_pr_alert("EVENT: unknown event id %d\n", eventcause);
6017                 break;
6018         }
6019  
6020 -       spin_lock_irq(&adapter->driver_lock);
6021 -       adapter->eventcause = 0;
6022 -       spin_unlock_irq(&adapter->driver_lock);
6023 +       spin_lock_irq(&priv->driver_lock);
6024 +       priv->eventcause = 0;
6025 +       spin_unlock_irq(&priv->driver_lock);
6026  
6027 -       lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
6028 +       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
6029         return ret;
6030  }
6031 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/debugfs.c linux-2.6.22-300/drivers/net/wireless/libertas/debugfs.c
6032 --- linux-2.6.22-250/drivers/net/wireless/libertas/debugfs.c    2007-07-08 19:32:17.000000000 -0400
6033 +++ linux-2.6.22-300/drivers/net/wireless/libertas/debugfs.c    2008-06-05 18:10:06.000000000 -0400
6034 @@ -3,6 +3,7 @@
6035  #include <linux/debugfs.h>
6036  #include <linux/delay.h>
6037  #include <linux/mm.h>
6038 +#include <linux/string.h>
6039  #include <net/iw_handler.h>
6040  
6041  #include "dev.h"
6042 @@ -10,14 +11,14 @@
6043  #include "host.h"
6044  #include "debugfs.h"
6045  
6046 -static struct dentry *libertas_dir = NULL;
6047 +static struct dentry *lbs_dir;
6048  static char *szStates[] = {
6049         "Connected",
6050         "Disconnected"
6051  };
6052  
6053  #ifdef PROC_DEBUG
6054 -static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
6055 +static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev);
6056  #endif
6057  
6058  static int open_file_generic(struct inode *inode, struct file *file)
6059 @@ -34,19 +35,19 @@ static ssize_t write_file_dummy(struct f
6060  
6061  static const size_t len = PAGE_SIZE;
6062  
6063 -static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
6064 +static ssize_t lbs_dev_info(struct file *file, char __user *userbuf,
6065                                   size_t count, loff_t *ppos)
6066  {
6067 -       wlan_private *priv = file->private_data;
6068 +       struct lbs_private *priv = file->private_data;
6069         size_t pos = 0;
6070         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6071         char *buf = (char *)addr;
6072         ssize_t res;
6073  
6074         pos += snprintf(buf+pos, len-pos, "state = %s\n",
6075 -                               szStates[priv->adapter->connect_status]);
6076 +                               szStates[priv->connect_status]);
6077         pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
6078 -                               (u32) priv->adapter->regioncode);
6079 +                               (u32) priv->regioncode);
6080  
6081         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6082  
6083 @@ -55,41 +56,41 @@ static ssize_t libertas_dev_info(struct 
6084  }
6085  
6086  
6087 -static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
6088 +static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
6089                                   size_t count, loff_t *ppos)
6090  {
6091 -       wlan_private *priv = file->private_data;
6092 +       struct lbs_private *priv = file->private_data;
6093         size_t pos = 0;
6094         int numscansdone = 0, res;
6095         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6096         char *buf = (char *)addr;
6097 +       DECLARE_MAC_BUF(mac);
6098         struct bss_descriptor * iter_bss;
6099  
6100         pos += snprintf(buf+pos, len-pos,
6101 -               "# | ch  | ss  |       bssid       |   cap    |    TSF   | Qual | SSID \n");
6102 +               "# | ch  | rssi |       bssid       |   cap    | Qual | SSID \n");
6103  
6104 -       mutex_lock(&priv->adapter->lock);
6105 -       list_for_each_entry (iter_bss, &priv->adapter->network_list, list) {
6106 -               u16 cap;
6107 +       mutex_lock(&priv->lock);
6108 +       list_for_each_entry (iter_bss, &priv->network_list, list) {
6109 +               u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS);
6110 +               u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY);
6111 +               u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT);
6112  
6113 -               memcpy(&cap, &iter_bss->cap, sizeof(cap));
6114                 pos += snprintf(buf+pos, len-pos,
6115 -                       "%02u| %03d | %03ld | " MAC_FMT " |",
6116 +                       "%02u| %03d | %04ld | %s |",
6117                         numscansdone, iter_bss->channel, iter_bss->rssi,
6118 -                       MAC_ARG(iter_bss->bssid));
6119 -               pos += snprintf(buf+pos, len-pos, " %04x-", cap);
6120 +                       print_mac(mac, iter_bss->bssid));
6121 +               pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability);
6122                 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
6123 -                               iter_bss->cap.ibss ? 'A' : 'I',
6124 -                               iter_bss->cap.privacy ? 'P' : ' ',
6125 -                               iter_bss->cap.spectrummgmt ? 'S' : ' ');
6126 -               pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf);
6127 -               pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi));
6128 +                               ibss ? 'A' : 'I', privacy ? 'P' : ' ',
6129 +                               spectrum_mgmt ? 'S' : ' ');
6130 +               pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi));
6131                 pos += snprintf(buf+pos, len-pos, " %s\n",
6132                                 escape_essid(iter_bss->ssid, iter_bss->ssid_len));
6133  
6134                 numscansdone++;
6135         }
6136 -       mutex_unlock(&priv->adapter->lock);
6137 +       mutex_unlock(&priv->lock);
6138  
6139         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6140  
6141 @@ -97,11 +98,11 @@ static ssize_t libertas_getscantable(str
6142         return res;
6143  }
6144  
6145 -static ssize_t libertas_sleepparams_write(struct file *file,
6146 +static ssize_t lbs_sleepparams_write(struct file *file,
6147                                 const char __user *user_buf, size_t count,
6148                                 loff_t *ppos)
6149  {
6150 -       wlan_private *priv = file->private_data;
6151 +       struct lbs_private *priv = file->private_data;
6152         ssize_t buf_size, res;
6153         int p1, p2, p3, p4, p5, p6;
6154         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6155 @@ -117,17 +118,17 @@ static ssize_t libertas_sleepparams_writ
6156                 res = -EFAULT;
6157                 goto out_unlock;
6158         }
6159 -       priv->adapter->sp.sp_error = p1;
6160 -       priv->adapter->sp.sp_offset = p2;
6161 -       priv->adapter->sp.sp_stabletime = p3;
6162 -       priv->adapter->sp.sp_calcontrol = p4;
6163 -       priv->adapter->sp.sp_extsleepclk = p5;
6164 -       priv->adapter->sp.sp_reserved = p6;
6165 -
6166 -        res = libertas_prepare_and_send_command(priv,
6167 -                               cmd_802_11_sleep_params,
6168 -                               cmd_act_set,
6169 -                               cmd_option_waitforrsp, 0, NULL);
6170 +       priv->sp.sp_error = p1;
6171 +       priv->sp.sp_offset = p2;
6172 +       priv->sp.sp_stabletime = p3;
6173 +       priv->sp.sp_calcontrol = p4;
6174 +       priv->sp.sp_extsleepclk = p5;
6175 +       priv->sp.sp_reserved = p6;
6176 +
6177 +       res = lbs_prepare_and_send_command(priv,
6178 +                               CMD_802_11_SLEEP_PARAMS,
6179 +                               CMD_ACT_SET,
6180 +                               CMD_OPTION_WAITFORRSP, 0, NULL);
6181  
6182         if (!res)
6183                 res = count;
6184 @@ -139,29 +140,28 @@ out_unlock:
6185         return res;
6186  }
6187  
6188 -static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
6189 +static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
6190                                   size_t count, loff_t *ppos)
6191  {
6192 -       wlan_private *priv = file->private_data;
6193 -       wlan_adapter *adapter = priv->adapter;
6194 +       struct lbs_private *priv = file->private_data;
6195         ssize_t res;
6196         size_t pos = 0;
6197         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6198         char *buf = (char *)addr;
6199  
6200 -        res = libertas_prepare_and_send_command(priv,
6201 -                               cmd_802_11_sleep_params,
6202 -                               cmd_act_get,
6203 -                               cmd_option_waitforrsp, 0, NULL);
6204 +       res = lbs_prepare_and_send_command(priv,
6205 +                               CMD_802_11_SLEEP_PARAMS,
6206 +                               CMD_ACT_GET,
6207 +                               CMD_OPTION_WAITFORRSP, 0, NULL);
6208         if (res) {
6209                 res = -EFAULT;
6210                 goto out_unlock;
6211         }
6212  
6213 -       pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
6214 -                       adapter->sp.sp_offset, adapter->sp.sp_stabletime,
6215 -                       adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
6216 -                       adapter->sp.sp_reserved);
6217 +       pos += snprintf(buf, len, "%d %d %d %d %d %d\n", priv->sp.sp_error,
6218 +                       priv->sp.sp_offset, priv->sp.sp_stabletime,
6219 +                       priv->sp.sp_calcontrol, priv->sp.sp_extsleepclk,
6220 +                       priv->sp.sp_reserved);
6221  
6222         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6223  
6224 @@ -170,10 +170,10 @@ out_unlock:
6225         return res;
6226  }
6227  
6228 -static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
6229 +static ssize_t lbs_extscan(struct file *file, const char __user *userbuf,
6230                                   size_t count, loff_t *ppos)
6231  {
6232 -       wlan_private *priv = file->private_data;
6233 +       struct lbs_private *priv = file->private_data;
6234         ssize_t res, buf_size;
6235         union iwreq_data wrqu;
6236         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6237 @@ -185,7 +185,7 @@ static ssize_t libertas_extscan(struct f
6238                 goto out_unlock;
6239         }
6240  
6241 -       libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
6242 +       lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
6243  
6244         memset(&wrqu, 0, sizeof(union iwreq_data));
6245         wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
6246 @@ -195,45 +195,8 @@ out_unlock:
6247         return count;
6248  }
6249  
6250 -static int libertas_parse_chan(char *buf, size_t count,
6251 -                       struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
6252 -{
6253 -       char *start, *end, *hold, *str;
6254 -       int i = 0;
6255 -
6256 -       start = strstr(buf, "chan=");
6257 -       if (!start)
6258 -               return -EINVAL;
6259 -       start += 5;
6260 -       end = strstr(start, " ");
6261 -       if (!end)
6262 -               end = buf + count;
6263 -       hold = kzalloc((end - start)+1, GFP_KERNEL);
6264 -       if (!hold)
6265 -               return -ENOMEM;
6266 -       strncpy(hold, start, end - start);
6267 -       hold[(end-start)+1] = '\0';
6268 -       while(hold && (str = strsep(&hold, ","))) {
6269 -               int chan;
6270 -               char band, passive = 0;
6271 -               sscanf(str, "%d%c%c", &chan, &band, &passive);
6272 -               scan_cfg->chanlist[i].channumber = chan;
6273 -               scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
6274 -               if (band == 'b' || band == 'g')
6275 -                       scan_cfg->chanlist[i].radiotype = 0;
6276 -               else if (band == 'a')
6277 -                       scan_cfg->chanlist[i].radiotype = 1;
6278 -
6279 -               scan_cfg->chanlist[i].scantime = dur;
6280 -               i++;
6281 -       }
6282 -
6283 -       kfree(hold);
6284 -       return i;
6285 -}
6286 -
6287 -static void libertas_parse_bssid(char *buf, size_t count,
6288 -                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
6289 +static void lbs_parse_bssid(char *buf, size_t count,
6290 +       struct lbs_ioctl_user_scan_cfg *scan_cfg)
6291  {
6292         char *hold;
6293         unsigned int mac[ETH_ALEN];
6294 @@ -246,8 +209,8 @@ static void libertas_parse_bssid(char *b
6295         memcpy(scan_cfg->bssid, mac, ETH_ALEN);
6296  }
6297  
6298 -static void libertas_parse_ssid(char *buf, size_t count,
6299 -                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
6300 +static void lbs_parse_ssid(char *buf, size_t count,
6301 +       struct lbs_ioctl_user_scan_cfg *scan_cfg)
6302  {
6303         char *hold, *end;
6304         ssize_t size;
6305 @@ -256,7 +219,7 @@ static void libertas_parse_ssid(char *bu
6306         if (!hold)
6307                 return;
6308         hold += 5;
6309 -       end = strstr(hold, " ");
6310 +       end = strchr(hold, ' ');
6311         if (!end)
6312                 end = buf + count - 1;
6313  
6314 @@ -266,7 +229,7 @@ static void libertas_parse_ssid(char *bu
6315         return;
6316  }
6317  
6318 -static int libertas_parse_clear(char *buf, size_t count, const char *tag)
6319 +static int lbs_parse_clear(char *buf, size_t count, const char *tag)
6320  {
6321         char *hold;
6322         int val;
6323 @@ -283,8 +246,8 @@ static int libertas_parse_clear(char *bu
6324         return val;
6325  }
6326  
6327 -static int libertas_parse_dur(char *buf, size_t count,
6328 -                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
6329 +static int lbs_parse_dur(char *buf, size_t count,
6330 +       struct lbs_ioctl_user_scan_cfg *scan_cfg)
6331  {
6332         char *hold;
6333         int val;
6334 @@ -298,25 +261,8 @@ static int libertas_parse_dur(char *buf,
6335         return val;
6336  }
6337  
6338 -static void libertas_parse_probes(char *buf, size_t count,
6339 -                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
6340 -{
6341 -       char *hold;
6342 -       int val;
6343 -
6344 -       hold = strstr(buf, "probes=");
6345 -       if (!hold)
6346 -               return;
6347 -       hold += 7;
6348 -       sscanf(hold, "%d", &val);
6349 -
6350 -       scan_cfg->numprobes = val;
6351 -
6352 -       return;
6353 -}
6354 -
6355 -static void libertas_parse_type(char *buf, size_t count,
6356 -                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
6357 +static void lbs_parse_type(char *buf, size_t count,
6358 +       struct lbs_ioctl_user_scan_cfg *scan_cfg)
6359  {
6360         char *hold;
6361         int val;
6362 @@ -336,570 +282,217 @@ static void libertas_parse_type(char *bu
6363         return;
6364  }
6365  
6366 -static ssize_t libertas_setuserscan(struct file *file,
6367 +static ssize_t lbs_setuserscan(struct file *file,
6368                                     const char __user *userbuf,
6369                                     size_t count, loff_t *ppos)
6370  {
6371 -       wlan_private *priv = file->private_data;
6372 +       struct lbs_private *priv = file->private_data;
6373         ssize_t res, buf_size;
6374 -       struct wlan_ioctl_user_scan_cfg *scan_cfg;
6375 +       struct lbs_ioctl_user_scan_cfg *scan_cfg;
6376         union iwreq_data wrqu;
6377         int dur;
6378 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
6379 -       char *buf = (char *)addr;
6380 +       char *buf = (char *)get_zeroed_page(GFP_KERNEL);
6381  
6382 -       scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
6383 -       if (!scan_cfg)
6384 +       if (!buf)
6385                 return -ENOMEM;
6386  
6387         buf_size = min(count, len - 1);
6388         if (copy_from_user(buf, userbuf, buf_size)) {
6389                 res = -EFAULT;
6390 -               goto out_unlock;
6391 +               goto out_buf;
6392         }
6393  
6394 -       scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
6395 +       scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
6396 +       if (!scan_cfg) {
6397 +               res = -ENOMEM;
6398 +               goto out_buf;
6399 +       }
6400 +       res = count;
6401 +
6402 +       scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY;
6403  
6404 -       dur = libertas_parse_dur(buf, count, scan_cfg);
6405 -       libertas_parse_chan(buf, count, scan_cfg, dur);
6406 -       libertas_parse_bssid(buf, count, scan_cfg);
6407 -       scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
6408 -       libertas_parse_ssid(buf, count, scan_cfg);
6409 -       scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
6410 -       libertas_parse_probes(buf, count, scan_cfg);
6411 -       libertas_parse_type(buf, count, scan_cfg);
6412 -
6413 -       wlan_scan_networks(priv, scan_cfg, 1);
6414 -       wait_event_interruptible(priv->adapter->cmd_pending,
6415 -                                !priv->adapter->nr_cmd_pending);
6416 +       dur = lbs_parse_dur(buf, count, scan_cfg);
6417 +       lbs_parse_bssid(buf, count, scan_cfg);
6418 +       scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid=");
6419 +       lbs_parse_ssid(buf, count, scan_cfg);
6420 +       scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid=");
6421 +       lbs_parse_type(buf, count, scan_cfg);
6422 +
6423 +       lbs_scan_networks(priv, scan_cfg, 1);
6424 +       wait_event_interruptible(priv->cmd_pending,
6425 +                                priv->surpriseremoved || !priv->last_scanned_channel);
6426 +
6427 +       if (priv->surpriseremoved)
6428 +               goto out_scan_cfg;
6429  
6430         memset(&wrqu, 0x00, sizeof(union iwreq_data));
6431         wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
6432  
6433 -out_unlock:
6434 -       free_page(addr);
6435 + out_scan_cfg:
6436         kfree(scan_cfg);
6437 -       return count;
6438 + out_buf:
6439 +       free_page((unsigned long)buf);
6440 +       return res;
6441  }
6442  
6443 -static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
6444 -                       struct cmd_ctrl_node **cmdnode,
6445 -                       struct cmd_ds_command **cmd)
6446 -{
6447 -       u16 wait_option = cmd_option_waitforrsp;
6448 -
6449 -       if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
6450 -               lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
6451 -               return -ENOMEM;
6452 -       }
6453 -       if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
6454 -               lbs_deb_debugfs("failed to allocate response buffer!\n");
6455 -               return -ENOMEM;
6456 -       }
6457 -       libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
6458 -       init_waitqueue_head(&(*cmdnode)->cmdwait_q);
6459 -       (*cmdnode)->pdata_buf = *response_buf;
6460 -       (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
6461 -       (*cmdnode)->cmdwaitqwoken = 0;
6462 -       *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
6463 -       (*cmd)->command = cpu_to_le16(cmd_802_11_subscribe_event);
6464 -       (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum);
6465 -       (*cmd)->result = 0;
6466 -       return 0;
6467 -}
6468  
6469 -static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
6470 -                                 size_t count, loff_t *ppos)
6471 +/*
6472 + * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
6473 + * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
6474 + * firmware. Here's an example:
6475 + *     04 01 02 00 00 00 05 01 02 00 00 00 06 01 02 00
6476 + *     00 00 07 01 02 00 3c 00 00 00 00 00 00 00 03 03
6477 + *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6478 + *
6479 + * The 04 01 is the TLV type (here TLV_TYPE_RSSI_LOW), 02 00 is the length,
6480 + * 00 00 are the data bytes of this TLV. For this TLV, their meaning is
6481 + * defined in mrvlietypes_thresholds
6482 + *
6483 + * This function searches in this TLV data chunk for a given TLV type
6484 + * and returns a pointer to the first data byte of the TLV, or to NULL
6485 + * if the TLV hasn't been found.
6486 + */
6487 +static void *lbs_tlv_find(u16 tlv_type, const u8 *tlv, u16 size)
6488  {
6489 -       wlan_private *priv = file->private_data;
6490 -       wlan_adapter *adapter = priv->adapter;
6491 -       struct cmd_ctrl_node *pcmdnode;
6492 -       struct cmd_ds_command *pcmdptr;
6493 -       struct cmd_ds_802_11_subscribe_event *event;
6494 -       void *response_buf;
6495 -       int res, cmd_len;
6496 +       __le16 le_type = cpu_to_le16(tlv_type);
6497         ssize_t pos = 0;
6498 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
6499 -       char *buf = (char *)addr;
6500 -
6501 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6502 -       if (res < 0) {
6503 -               free_page(addr);
6504 -               return res;
6505 -       }
6506 -
6507 -       event = &pcmdptr->params.subscribe_event;
6508 -       event->action = cpu_to_le16(cmd_act_get);
6509 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
6510 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6511 -       wake_up_interruptible(&priv->mainthread.waitq);
6512 -
6513 -       /* Sleep until response is generated by FW */
6514 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6515 -                                pcmdnode->cmdwaitqwoken);
6516 -
6517 -       pcmdptr = response_buf;
6518 -       if (pcmdptr->result) {
6519 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6520 -                          le16_to_cpu(pcmdptr->result));
6521 -               kfree(response_buf);
6522 -               free_page(addr);
6523 -               return 0;
6524 -       }
6525 -
6526 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
6527 -               lbs_pr_err("command response incorrect!\n");
6528 -               kfree(response_buf);
6529 -               free_page(addr);
6530 -               return 0;
6531 -       }
6532 -
6533 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
6534 -       event = (void *)(response_buf + S_DS_GEN);
6535 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
6536 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
6537 -               switch (header->type) {
6538 -               struct mrvlietypes_rssithreshold  *Lowrssi;
6539 -               case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW):
6540 -                       Lowrssi = (void *)(response_buf + cmd_len);
6541 -                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
6542 -                                       Lowrssi->rssivalue,
6543 -                                       Lowrssi->rssifreq,
6544 -                                       (event->events & cpu_to_le16(0x0001))?1:0);
6545 -               default:
6546 -                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
6547 -                       break;
6548 -               }
6549 -       }
6550 -
6551 -       kfree(response_buf);
6552 -       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6553 -       free_page(addr);
6554 -       return res;
6555 +       struct mrvlietypesheader *tlv_h;
6556 +       while (pos < size) {
6557 +               u16 length;
6558 +               tlv_h = (struct mrvlietypesheader *) tlv;
6559 +               if (tlv_h->type == le_type)
6560 +                       return tlv_h;
6561 +               if (tlv_h->len == 0)
6562 +                       return NULL;
6563 +               length = le16_to_cpu(tlv_h->len) +
6564 +                       sizeof(struct mrvlietypesheader);
6565 +               pos += length;
6566 +               tlv += length;
6567 +       }
6568 +       return NULL;
6569  }
6570  
6571 -static u16 libertas_get_events_bitmap(wlan_private *priv)
6572 -{
6573 -       wlan_adapter *adapter = priv->adapter;
6574 -       struct cmd_ctrl_node *pcmdnode;
6575 -       struct cmd_ds_command *pcmdptr;
6576 -       struct cmd_ds_802_11_subscribe_event *event;
6577 -       void *response_buf;
6578 -       int res;
6579 -       u16 event_bitmap;
6580  
6581 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6582 -       if (res < 0)
6583 -               return res;
6584 -
6585 -       event = &pcmdptr->params.subscribe_event;
6586 -       event->action = cpu_to_le16(cmd_act_get);
6587 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
6588 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6589 -       wake_up_interruptible(&priv->mainthread.waitq);
6590 -
6591 -       /* Sleep until response is generated by FW */
6592 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6593 -                                pcmdnode->cmdwaitqwoken);
6594 -
6595 -       pcmdptr = response_buf;
6596 -
6597 -       if (pcmdptr->result) {
6598 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6599 -                          le16_to_cpu(pcmdptr->result));
6600 -               kfree(response_buf);
6601 -               return 0;
6602 -       }
6603 -
6604 -       if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
6605 -               lbs_pr_err("command response incorrect!\n");
6606 -               kfree(response_buf);
6607 -               return 0;
6608 -       }
6609 -
6610 -       event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
6611 -       event_bitmap = le16_to_cpu(event->events);
6612 -       kfree(response_buf);
6613 -       return event_bitmap;
6614 -}
6615 -
6616 -static ssize_t libertas_lowrssi_write(struct file *file,
6617 -                                   const char __user *userbuf,
6618 -                                   size_t count, loff_t *ppos)
6619 +/*
6620 + * This just gets the bitmap of currently subscribed events. Used when
6621 + * adding an additonal event subscription.
6622 + */
6623 +static u16 lbs_get_events_bitmap(struct lbs_private *priv)
6624  {
6625 -       wlan_private *priv = file->private_data;
6626 -       wlan_adapter *adapter = priv->adapter;
6627 -       ssize_t res, buf_size;
6628 -       int value, freq, subscribed, cmd_len;
6629 -       struct cmd_ctrl_node *pcmdnode;
6630 -       struct cmd_ds_command *pcmdptr;
6631 -       struct cmd_ds_802_11_subscribe_event *event;
6632 -       struct mrvlietypes_rssithreshold *rssi_threshold;
6633 -       void *response_buf;
6634 -       u16 event_bitmap;
6635 -       u8 *ptr;
6636 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
6637 -       char *buf = (char *)addr;
6638 -
6639 -       buf_size = min(count, len - 1);
6640 -       if (copy_from_user(buf, userbuf, buf_size)) {
6641 -               res = -EFAULT;
6642 -               goto out_unlock;
6643 -       }
6644 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
6645 -       if (res != 3) {
6646 -               res = -EFAULT;
6647 -               goto out_unlock;
6648 -       }
6649 -
6650 -       event_bitmap = libertas_get_events_bitmap(priv);
6651 +       ssize_t res;
6652  
6653 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6654 -       if (res < 0)
6655 -               goto out_unlock;
6656 +       struct cmd_ds_802_11_subscribe_event *events = kzalloc(
6657 +               sizeof(struct cmd_ds_802_11_subscribe_event),
6658 +               GFP_KERNEL);
6659 +
6660 +       res = lbs_prepare_and_send_command(priv,
6661 +                       CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET,
6662 +                       CMD_OPTION_WAITFORRSP, 0, events);
6663  
6664 -       event = &pcmdptr->params.subscribe_event;
6665 -       event->action = cpu_to_le16(cmd_act_set);
6666 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
6667 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
6668 -               sizeof(struct mrvlietypes_rssithreshold));
6669 -
6670 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
6671 -       ptr = (u8*) pcmdptr+cmd_len;
6672 -       rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
6673 -       rssi_threshold->header.type = cpu_to_le16(0x0104);
6674 -       rssi_threshold->header.len = cpu_to_le16(2);
6675 -       rssi_threshold->rssivalue = value;
6676 -       rssi_threshold->rssifreq = freq;
6677 -       event_bitmap |= subscribed ? 0x0001 : 0x0;
6678 -       event->events = cpu_to_le16(event_bitmap);
6679 -
6680 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6681 -       wake_up_interruptible(&priv->mainthread.waitq);
6682 -
6683 -       /* Sleep until response is generated by FW */
6684 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6685 -                                pcmdnode->cmdwaitqwoken);
6686 -
6687 -       pcmdptr = response_buf;
6688 -
6689 -       if (pcmdptr->result) {
6690 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6691 -                          le16_to_cpu(pcmdptr->result));
6692 -               kfree(response_buf);
6693 -               free_page(addr);
6694 -               return 0;
6695 -       }
6696 -
6697 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
6698 -               lbs_pr_err("command response incorrect!\n");
6699 -               kfree(response_buf);
6700 -               free_page(addr);
6701 +       if (res) {
6702 +               kfree(events);
6703                 return 0;
6704         }
6705 -
6706 -       res = count;
6707 -out_unlock:
6708 -       free_page(addr);
6709 -       return res;
6710 +       return le16_to_cpu(events->events);
6711  }
6712  
6713 -static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
6714 -                                 size_t count, loff_t *ppos)
6715 +
6716 +static ssize_t lbs_threshold_read(
6717 +       u16 tlv_type, u16 event_mask,
6718 +       struct file *file, char __user *userbuf,
6719 +       size_t count, loff_t *ppos)
6720  {
6721 -       wlan_private *priv = file->private_data;
6722 -       wlan_adapter *adapter = priv->adapter;
6723 -       struct cmd_ctrl_node *pcmdnode;
6724 -       struct cmd_ds_command *pcmdptr;
6725 -       struct cmd_ds_802_11_subscribe_event *event;
6726 -       void *response_buf;
6727 -       int res, cmd_len;
6728 -       ssize_t pos = 0;
6729 +       struct lbs_private *priv = file->private_data;
6730 +       ssize_t res = 0;
6731 +       size_t pos = 0;
6732         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6733         char *buf = (char *)addr;
6734 -
6735 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6736 -       if (res < 0) {
6737 -               free_page(addr);
6738 +       u8 value;
6739 +       u8 freq;
6740 +       int events = 0;
6741 +
6742 +       struct cmd_ds_802_11_subscribe_event *subscribed = kzalloc(
6743 +               sizeof(struct cmd_ds_802_11_subscribe_event),
6744 +               GFP_KERNEL);
6745 +       struct mrvlietypes_thresholds *got;
6746 +
6747 +       res = lbs_prepare_and_send_command(priv,
6748 +                       CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET,
6749 +                       CMD_OPTION_WAITFORRSP, 0, subscribed);
6750 +       if (res) {
6751 +               kfree(subscribed);
6752                 return res;
6753         }
6754  
6755 -       event = &pcmdptr->params.subscribe_event;
6756 -       event->action = cpu_to_le16(cmd_act_get);
6757 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
6758 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6759 -       wake_up_interruptible(&priv->mainthread.waitq);
6760 -
6761 -       /* Sleep until response is generated by FW */
6762 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6763 -                                pcmdnode->cmdwaitqwoken);
6764 -
6765 -       pcmdptr = response_buf;
6766 -
6767 -       if (pcmdptr->result) {
6768 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6769 -                          le16_to_cpu(pcmdptr->result));
6770 -               kfree(response_buf);
6771 -               free_page(addr);
6772 -               return 0;
6773 -       }
6774 -
6775 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
6776 -               lbs_pr_err("command response incorrect!\n");
6777 -               kfree(response_buf);
6778 -               free_page(addr);
6779 -               return 0;
6780 -       }
6781 -
6782 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
6783 -       event = (void *)(response_buf + S_DS_GEN);
6784 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
6785 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
6786 -               switch (header->type) {
6787 -               struct mrvlietypes_snrthreshold *LowSnr;
6788 -               case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW):
6789 -                       LowSnr = (void *)(response_buf + cmd_len);
6790 -                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
6791 -                                       LowSnr->snrvalue,
6792 -                                       LowSnr->snrfreq,
6793 -                                       (event->events & cpu_to_le16(0x0002))?1:0);
6794 -               default:
6795 -                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
6796 -                       break;
6797 -               }
6798 -       }
6799 -
6800 -       kfree(response_buf);
6801 +       got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv));
6802 +       if (got) {
6803 +               value = got->value;
6804 +               freq  = got->freq;
6805 +               events = le16_to_cpu(subscribed->events);
6806 +       }
6807 +       kfree(subscribed);
6808 +
6809 +       if (got)
6810 +               pos += snprintf(buf, len, "%d %d %d\n", value, freq,
6811 +                       !!(events & event_mask));
6812  
6813         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6814 -       free_page(addr);
6815 -       return res;
6816 -}
6817 -
6818 -static ssize_t libertas_lowsnr_write(struct file *file,
6819 -                                   const char __user *userbuf,
6820 -                                   size_t count, loff_t *ppos)
6821 -{
6822 -       wlan_private *priv = file->private_data;
6823 -       wlan_adapter *adapter = priv->adapter;
6824 -       ssize_t res, buf_size;
6825 -       int value, freq, subscribed, cmd_len;
6826 -       struct cmd_ctrl_node *pcmdnode;
6827 -       struct cmd_ds_command *pcmdptr;
6828 -       struct cmd_ds_802_11_subscribe_event *event;
6829 -       struct mrvlietypes_snrthreshold *snr_threshold;
6830 -       void *response_buf;
6831 -       u16 event_bitmap;
6832 -       u8 *ptr;
6833 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
6834 -       char *buf = (char *)addr;
6835 -
6836 -       buf_size = min(count, len - 1);
6837 -       if (copy_from_user(buf, userbuf, buf_size)) {
6838 -               res = -EFAULT;
6839 -               goto out_unlock;
6840 -       }
6841 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
6842 -       if (res != 3) {
6843 -               res = -EFAULT;
6844 -               goto out_unlock;
6845 -       }
6846 -
6847 -       event_bitmap = libertas_get_events_bitmap(priv);
6848 -
6849 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6850 -       if (res < 0)
6851 -               goto out_unlock;
6852 -
6853 -       event = &pcmdptr->params.subscribe_event;
6854 -       event->action = cpu_to_le16(cmd_act_set);
6855 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
6856 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
6857 -               sizeof(struct mrvlietypes_snrthreshold));
6858 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
6859 -       ptr = (u8*) pcmdptr+cmd_len;
6860 -       snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
6861 -       snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
6862 -       snr_threshold->header.len = cpu_to_le16(2);
6863 -       snr_threshold->snrvalue = value;
6864 -       snr_threshold->snrfreq = freq;
6865 -       event_bitmap |= subscribed ? 0x0002 : 0x0;
6866 -       event->events = cpu_to_le16(event_bitmap);
6867 -
6868 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6869 -       wake_up_interruptible(&priv->mainthread.waitq);
6870 -
6871 -       /* Sleep until response is generated by FW */
6872 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6873 -                                pcmdnode->cmdwaitqwoken);
6874 -
6875 -       pcmdptr = response_buf;
6876 -
6877 -       if (pcmdptr->result) {
6878 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6879 -                          le16_to_cpu(pcmdptr->result));
6880 -               kfree(response_buf);
6881 -               free_page(addr);
6882 -               return 0;
6883 -       }
6884 -
6885 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
6886 -               lbs_pr_err("command response incorrect!\n");
6887 -               kfree(response_buf);
6888 -               free_page(addr);
6889 -               return 0;
6890 -       }
6891  
6892 -       res = count;
6893 -
6894 -out_unlock:
6895         free_page(addr);
6896         return res;
6897  }
6898  
6899 -static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
6900 -                                 size_t count, loff_t *ppos)
6901 -{
6902 -       wlan_private *priv = file->private_data;
6903 -       wlan_adapter *adapter = priv->adapter;
6904 -       struct cmd_ctrl_node *pcmdnode;
6905 -       struct cmd_ds_command *pcmdptr;
6906 -       struct cmd_ds_802_11_subscribe_event *event;
6907 -       void *response_buf;
6908 -       int res, cmd_len;
6909 -       ssize_t pos = 0;
6910 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
6911 -       char *buf = (char *)addr;
6912 -
6913 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
6914 -       if (res < 0) {
6915 -               free_page(addr);
6916 -               return res;
6917 -       }
6918 -
6919 -       event = &pcmdptr->params.subscribe_event;
6920 -       event->action = cpu_to_le16(cmd_act_get);
6921 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
6922 -       libertas_queue_cmd(adapter, pcmdnode, 1);
6923 -       wake_up_interruptible(&priv->mainthread.waitq);
6924 -
6925 -       /* Sleep until response is generated by FW */
6926 -       wait_event_interruptible(pcmdnode->cmdwait_q,
6927 -                                pcmdnode->cmdwaitqwoken);
6928 -
6929 -       pcmdptr = response_buf;
6930 -
6931 -       if (pcmdptr->result) {
6932 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
6933 -                          le16_to_cpu(pcmdptr->result));
6934 -               kfree(response_buf);
6935 -               free_page(addr);
6936 -               return 0;
6937 -       }
6938 -
6939 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
6940 -               lbs_pr_err("command response incorrect!\n");
6941 -               kfree(response_buf);
6942 -               free_page(addr);
6943 -               return 0;
6944 -       }
6945 -
6946 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
6947 -       event = (void *)(response_buf + S_DS_GEN);
6948 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
6949 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
6950 -               switch (header->type) {
6951 -               struct mrvlietypes_failurecount *failcount;
6952 -               case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT):
6953 -                       failcount = (void *)(response_buf + cmd_len);
6954 -                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
6955 -                                       failcount->failvalue,
6956 -                                       failcount->Failfreq,
6957 -                                       (event->events & cpu_to_le16(0x0004))?1:0);
6958 -               default:
6959 -                       cmd_len += sizeof(struct mrvlietypes_failurecount);
6960 -                       break;
6961 -               }
6962 -       }
6963 -
6964 -       kfree(response_buf);
6965 -       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
6966 -       free_page(addr);
6967 -       return res;
6968 -}
6969  
6970 -static ssize_t libertas_failcount_write(struct file *file,
6971 -                                   const char __user *userbuf,
6972 -                                   size_t count, loff_t *ppos)
6973 +static ssize_t lbs_threshold_write(
6974 +       u16 tlv_type, u16 event_mask,
6975 +       struct file *file,
6976 +       const char __user *userbuf,
6977 +       size_t count, loff_t *ppos)
6978  {
6979 -       wlan_private *priv = file->private_data;
6980 -       wlan_adapter *adapter = priv->adapter;
6981 +       struct lbs_private *priv = file->private_data;
6982         ssize_t res, buf_size;
6983 -       int value, freq, subscribed, cmd_len;
6984 -       struct cmd_ctrl_node *pcmdnode;
6985 -       struct cmd_ds_command *pcmdptr;
6986 -       struct cmd_ds_802_11_subscribe_event *event;
6987 -       struct mrvlietypes_failurecount *failcount;
6988 -       void *response_buf;
6989 -       u16 event_bitmap;
6990 -       u8 *ptr;
6991 +       int value, freq, curr_mask, new_mask;
6992         unsigned long addr = get_zeroed_page(GFP_KERNEL);
6993         char *buf = (char *)addr;
6994 +       struct cmd_ds_802_11_subscribe_event *events;
6995  
6996         buf_size = min(count, len - 1);
6997         if (copy_from_user(buf, userbuf, buf_size)) {
6998                 res = -EFAULT;
6999                 goto out_unlock;
7000         }
7001 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
7002 +       res = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
7003         if (res != 3) {
7004                 res = -EFAULT;
7005                 goto out_unlock;
7006         }
7007 +       curr_mask = lbs_get_events_bitmap(priv);
7008  
7009 -       event_bitmap = libertas_get_events_bitmap(priv);
7010 -
7011 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7012 -       if (res < 0)
7013 -               goto out_unlock;
7014 -
7015 -       event = &pcmdptr->params.subscribe_event;
7016 -       event->action = cpu_to_le16(cmd_act_set);
7017 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
7018 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
7019 -               sizeof(struct mrvlietypes_failurecount));
7020 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7021 -       ptr = (u8*) pcmdptr+cmd_len;
7022 -       failcount = (struct mrvlietypes_failurecount *)(ptr);
7023 -       failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
7024 -       failcount->header.len = cpu_to_le16(2);
7025 -       failcount->failvalue = value;
7026 -       failcount->Failfreq = freq;
7027 -       event_bitmap |= subscribed ? 0x0004 : 0x0;
7028 -       event->events = cpu_to_le16(event_bitmap);
7029 -
7030 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7031 -       wake_up_interruptible(&priv->mainthread.waitq);
7032 -
7033 -       /* Sleep until response is generated by FW */
7034 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7035 -                                pcmdnode->cmdwaitqwoken);
7036 -
7037 -       pcmdptr = (struct cmd_ds_command *)response_buf;
7038 -
7039 -       if (pcmdptr->result) {
7040 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7041 -                          le16_to_cpu(pcmdptr->result));
7042 -               kfree(response_buf);
7043 -               free_page(addr);
7044 -               return 0;
7045 -       }
7046 +       if (new_mask)
7047 +               new_mask = curr_mask | event_mask;
7048 +       else
7049 +               new_mask = curr_mask & ~event_mask;
7050  
7051 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7052 -               lbs_pr_err("command response incorrect!\n");
7053 -               kfree(response_buf);
7054 -               free_page(addr);
7055 -               return 0;
7056 +       /* Now everything is set and we can send stuff down to the firmware */
7057 +       events = kzalloc(
7058 +               sizeof(struct cmd_ds_802_11_subscribe_event),
7059 +               GFP_KERNEL);
7060 +       if (events) {
7061 +               struct mrvlietypes_thresholds *tlv =
7062 +                       (struct mrvlietypes_thresholds *) events->tlv;
7063 +               events->action = cpu_to_le16(CMD_ACT_SET);
7064 +               events->events = cpu_to_le16(new_mask);
7065 +               tlv->header.type = cpu_to_le16(tlv_type);
7066 +               tlv->header.len = cpu_to_le16(
7067 +                       sizeof(struct mrvlietypes_thresholds) -
7068 +                       sizeof(struct mrvlietypesheader));
7069 +               tlv->value = value;
7070 +               if (tlv_type != TLV_TYPE_BCNMISS)
7071 +                       tlv->freq = freq;
7072 +               lbs_prepare_and_send_command(priv,
7073 +                       CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_SET,
7074 +                       CMD_OPTION_WAITFORRSP, 0, events);
7075 +               kfree(events);
7076         }
7077  
7078         res = count;
7079 @@ -908,464 +501,125 @@ out_unlock:
7080         return res;
7081  }
7082  
7083 -static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
7084 -                                 size_t count, loff_t *ppos)
7085 -{
7086 -       wlan_private *priv = file->private_data;
7087 -       wlan_adapter *adapter = priv->adapter;
7088 -       struct cmd_ctrl_node *pcmdnode;
7089 -       struct cmd_ds_command *pcmdptr;
7090 -       struct cmd_ds_802_11_subscribe_event *event;
7091 -       void *response_buf;
7092 -       int res, cmd_len;
7093 -       ssize_t pos = 0;
7094 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7095 -       char *buf = (char *)addr;
7096 -
7097 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7098 -       if (res < 0) {
7099 -               free_page(addr);
7100 -               return res;
7101 -       }
7102 -
7103 -       event = &pcmdptr->params.subscribe_event;
7104 -       event->action = cpu_to_le16(cmd_act_get);
7105 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
7106 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7107 -       wake_up_interruptible(&priv->mainthread.waitq);
7108 -
7109 -       /* Sleep until response is generated by FW */
7110 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7111 -                                pcmdnode->cmdwaitqwoken);
7112 -
7113 -       pcmdptr = response_buf;
7114 -
7115 -       if (pcmdptr->result) {
7116 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7117 -                          le16_to_cpu(pcmdptr->result));
7118 -               free_page(addr);
7119 -               kfree(response_buf);
7120 -               return 0;
7121 -       }
7122 -
7123 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7124 -               lbs_pr_err("command response incorrect!\n");
7125 -               free_page(addr);
7126 -               kfree(response_buf);
7127 -               return 0;
7128 -       }
7129 -
7130 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7131 -       event = (void *)(response_buf + S_DS_GEN);
7132 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
7133 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
7134 -               switch (header->type) {
7135 -               struct mrvlietypes_beaconsmissed *bcnmiss;
7136 -               case __constant_cpu_to_le16(TLV_TYPE_BCNMISS):
7137 -                       bcnmiss = (void *)(response_buf + cmd_len);
7138 -                       pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
7139 -                                       bcnmiss->beaconmissed,
7140 -                                       (event->events & cpu_to_le16(0x0008))?1:0);
7141 -               default:
7142 -                       cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
7143 -                       break;
7144 -               }
7145 -       }
7146 -
7147 -       kfree(response_buf);
7148  
7149 -       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7150 -       free_page(addr);
7151 -       return res;
7152 -}
7153 -
7154 -static ssize_t libertas_bcnmiss_write(struct file *file,
7155 -                                   const char __user *userbuf,
7156 -                                   size_t count, loff_t *ppos)
7157 +static ssize_t lbs_lowrssi_read(
7158 +       struct file *file, char __user *userbuf,
7159 +       size_t count, loff_t *ppos)
7160  {
7161 -       wlan_private *priv = file->private_data;
7162 -       wlan_adapter *adapter = priv->adapter;
7163 -       ssize_t res, buf_size;
7164 -       int value, freq, subscribed, cmd_len;
7165 -       struct cmd_ctrl_node *pcmdnode;
7166 -       struct cmd_ds_command *pcmdptr;
7167 -       struct cmd_ds_802_11_subscribe_event *event;
7168 -       struct mrvlietypes_beaconsmissed *bcnmiss;
7169 -       void *response_buf;
7170 -       u16 event_bitmap;
7171 -       u8 *ptr;
7172 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7173 -       char *buf = (char *)addr;
7174 -
7175 -       buf_size = min(count, len - 1);
7176 -       if (copy_from_user(buf, userbuf, buf_size)) {
7177 -               res = -EFAULT;
7178 -               goto out_unlock;
7179 -       }
7180 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
7181 -       if (res != 3) {
7182 -               res = -EFAULT;
7183 -               goto out_unlock;
7184 -       }
7185 -
7186 -       event_bitmap = libertas_get_events_bitmap(priv);
7187 -
7188 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7189 -       if (res < 0)
7190 -               goto out_unlock;
7191 -
7192 -       event = &pcmdptr->params.subscribe_event;
7193 -       event->action = cpu_to_le16(cmd_act_set);
7194 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
7195 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
7196 -               sizeof(struct mrvlietypes_beaconsmissed));
7197 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7198 -       ptr = (u8*) pcmdptr+cmd_len;
7199 -       bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
7200 -       bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
7201 -       bcnmiss->header.len = cpu_to_le16(2);
7202 -       bcnmiss->beaconmissed = value;
7203 -       event_bitmap |= subscribed ? 0x0008 : 0x0;
7204 -       event->events = cpu_to_le16(event_bitmap);
7205 -
7206 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7207 -       wake_up_interruptible(&priv->mainthread.waitq);
7208 -
7209 -       /* Sleep until response is generated by FW */
7210 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7211 -                                pcmdnode->cmdwaitqwoken);
7212 -
7213 -       pcmdptr = response_buf;
7214 -
7215 -       if (pcmdptr->result) {
7216 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7217 -                          le16_to_cpu(pcmdptr->result));
7218 -               kfree(response_buf);
7219 -               free_page(addr);
7220 -               return 0;
7221 -       }
7222 +       return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
7223 +               file, userbuf, count, ppos);
7224 +}
7225  
7226 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7227 -               lbs_pr_err("command response incorrect!\n");
7228 -               free_page(addr);
7229 -               kfree(response_buf);
7230 -               return 0;
7231 -       }
7232  
7233 -       res = count;
7234 -out_unlock:
7235 -       free_page(addr);
7236 -       return res;
7237 +static ssize_t lbs_lowrssi_write(
7238 +       struct file *file, const char __user *userbuf,
7239 +       size_t count, loff_t *ppos)
7240 +{
7241 +       return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
7242 +               file, userbuf, count, ppos);
7243  }
7244  
7245 -static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
7246 -                                 size_t count, loff_t *ppos)
7247 +
7248 +static ssize_t lbs_lowsnr_read(
7249 +       struct file *file, char __user *userbuf,
7250 +       size_t count, loff_t *ppos)
7251  {
7252 -       wlan_private *priv = file->private_data;
7253 -       wlan_adapter *adapter = priv->adapter;
7254 -       struct cmd_ctrl_node *pcmdnode;
7255 -       struct cmd_ds_command *pcmdptr;
7256 -       struct cmd_ds_802_11_subscribe_event *event;
7257 -       void *response_buf;
7258 -       int res, cmd_len;
7259 -       ssize_t pos = 0;
7260 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7261 -       char *buf = (char *)addr;
7262 +       return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
7263 +               file, userbuf, count, ppos);
7264 +}
7265  
7266 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7267 -       if (res < 0) {
7268 -               free_page(addr);
7269 -               return res;
7270 -       }
7271  
7272 -       event = &pcmdptr->params.subscribe_event;
7273 -       event->action = cpu_to_le16(cmd_act_get);
7274 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
7275 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7276 -       wake_up_interruptible(&priv->mainthread.waitq);
7277 -
7278 -       /* Sleep until response is generated by FW */
7279 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7280 -                                pcmdnode->cmdwaitqwoken);
7281 -
7282 -       pcmdptr = response_buf;
7283 -
7284 -       if (pcmdptr->result) {
7285 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7286 -                          le16_to_cpu(pcmdptr->result));
7287 -               kfree(response_buf);
7288 -               free_page(addr);
7289 -               return 0;
7290 -       }
7291 +static ssize_t lbs_lowsnr_write(
7292 +       struct file *file, const char __user *userbuf,
7293 +       size_t count, loff_t *ppos)
7294 +{
7295 +       return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
7296 +               file, userbuf, count, ppos);
7297 +}
7298  
7299 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7300 -               lbs_pr_err("command response incorrect!\n");
7301 -               kfree(response_buf);
7302 -               free_page(addr);
7303 -               return 0;
7304 -       }
7305  
7306 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7307 -       event = (void *)(response_buf + S_DS_GEN);
7308 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
7309 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
7310 -               switch (header->type) {
7311 -               struct mrvlietypes_rssithreshold  *Highrssi;
7312 -               case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH):
7313 -                       Highrssi = (void *)(response_buf + cmd_len);
7314 -                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
7315 -                                       Highrssi->rssivalue,
7316 -                                       Highrssi->rssifreq,
7317 -                                       (event->events & cpu_to_le16(0x0010))?1:0);
7318 -               default:
7319 -                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
7320 -                       break;
7321 -               }
7322 -       }
7323 +static ssize_t lbs_failcount_read(
7324 +       struct file *file, char __user *userbuf,
7325 +       size_t count, loff_t *ppos)
7326 +{
7327 +       return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
7328 +               file, userbuf, count, ppos);
7329 +}
7330  
7331 -       kfree(response_buf);
7332  
7333 -       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7334 -       free_page(addr);
7335 -       return res;
7336 +static ssize_t lbs_failcount_write(
7337 +       struct file *file, const char __user *userbuf,
7338 +       size_t count, loff_t *ppos)
7339 +{
7340 +       return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
7341 +               file, userbuf, count, ppos);
7342  }
7343  
7344 -static ssize_t libertas_highrssi_write(struct file *file,
7345 -                                   const char __user *userbuf,
7346 -                                   size_t count, loff_t *ppos)
7347 +
7348 +static ssize_t lbs_highrssi_read(
7349 +       struct file *file, char __user *userbuf,
7350 +       size_t count, loff_t *ppos)
7351  {
7352 -       wlan_private *priv = file->private_data;
7353 -       wlan_adapter *adapter = priv->adapter;
7354 -       ssize_t res, buf_size;
7355 -       int value, freq, subscribed, cmd_len;
7356 -       struct cmd_ctrl_node *pcmdnode;
7357 -       struct cmd_ds_command *pcmdptr;
7358 -       struct cmd_ds_802_11_subscribe_event *event;
7359 -       struct mrvlietypes_rssithreshold *rssi_threshold;
7360 -       void *response_buf;
7361 -       u16 event_bitmap;
7362 -       u8 *ptr;
7363 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7364 -       char *buf = (char *)addr;
7365 +       return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
7366 +               file, userbuf, count, ppos);
7367 +}
7368  
7369 -       buf_size = min(count, len - 1);
7370 -       if (copy_from_user(buf, userbuf, buf_size)) {
7371 -               res = -EFAULT;
7372 -               goto out_unlock;
7373 -       }
7374 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
7375 -       if (res != 3) {
7376 -               res = -EFAULT;
7377 -               goto out_unlock;
7378 -       }
7379  
7380 -       event_bitmap = libertas_get_events_bitmap(priv);
7381 +static ssize_t lbs_highrssi_write(
7382 +       struct file *file, const char __user *userbuf,
7383 +       size_t count, loff_t *ppos)
7384 +{
7385 +       return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
7386 +               file, userbuf, count, ppos);
7387 +}
7388  
7389 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7390 -       if (res < 0)
7391 -               goto out_unlock;
7392  
7393 -       event = &pcmdptr->params.subscribe_event;
7394 -       event->action = cpu_to_le16(cmd_act_set);
7395 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
7396 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
7397 -               sizeof(struct mrvlietypes_rssithreshold));
7398 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7399 -       ptr = (u8*) pcmdptr+cmd_len;
7400 -       rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
7401 -       rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
7402 -       rssi_threshold->header.len = cpu_to_le16(2);
7403 -       rssi_threshold->rssivalue = value;
7404 -       rssi_threshold->rssifreq = freq;
7405 -       event_bitmap |= subscribed ? 0x0010 : 0x0;
7406 -       event->events = cpu_to_le16(event_bitmap);
7407 -
7408 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7409 -       wake_up_interruptible(&priv->mainthread.waitq);
7410 -
7411 -       /* Sleep until response is generated by FW */
7412 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7413 -                                pcmdnode->cmdwaitqwoken);
7414 -
7415 -       pcmdptr = response_buf;
7416 -
7417 -       if (pcmdptr->result) {
7418 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7419 -                          le16_to_cpu(pcmdptr->result));
7420 -               kfree(response_buf);
7421 -               return 0;
7422 -       }
7423 +static ssize_t lbs_highsnr_read(
7424 +       struct file *file, char __user *userbuf,
7425 +       size_t count, loff_t *ppos)
7426 +{
7427 +       return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
7428 +               file, userbuf, count, ppos);
7429 +}
7430  
7431 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7432 -               lbs_pr_err("command response incorrect!\n");
7433 -               kfree(response_buf);
7434 -               return 0;
7435 -       }
7436  
7437 -       res = count;
7438 -out_unlock:
7439 -       free_page(addr);
7440 -       return res;
7441 +static ssize_t lbs_highsnr_write(
7442 +       struct file *file, const char __user *userbuf,
7443 +       size_t count, loff_t *ppos)
7444 +{
7445 +       return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
7446 +               file, userbuf, count, ppos);
7447  }
7448  
7449 -static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
7450 -                                 size_t count, loff_t *ppos)
7451 +static ssize_t lbs_bcnmiss_read(
7452 +       struct file *file, char __user *userbuf,
7453 +       size_t count, loff_t *ppos)
7454  {
7455 -       wlan_private *priv = file->private_data;
7456 -       wlan_adapter *adapter = priv->adapter;
7457 -       struct cmd_ctrl_node *pcmdnode;
7458 -       struct cmd_ds_command *pcmdptr;
7459 -       struct cmd_ds_802_11_subscribe_event *event;
7460 -       void *response_buf;
7461 -       int res, cmd_len;
7462 -       ssize_t pos = 0;
7463 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7464 -       char *buf = (char *)addr;
7465 -
7466 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7467 -       if (res < 0) {
7468 -               free_page(addr);
7469 -               return res;
7470 -       }
7471 -
7472 -       event = &pcmdptr->params.subscribe_event;
7473 -       event->action = cpu_to_le16(cmd_act_get);
7474 -       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
7475 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7476 -       wake_up_interruptible(&priv->mainthread.waitq);
7477 -
7478 -       /* Sleep until response is generated by FW */
7479 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7480 -                                pcmdnode->cmdwaitqwoken);
7481 -
7482 -       pcmdptr = response_buf;
7483 -
7484 -       if (pcmdptr->result) {
7485 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7486 -                          le16_to_cpu(pcmdptr->result));
7487 -               kfree(response_buf);
7488 -               free_page(addr);
7489 -               return 0;
7490 -       }
7491 -
7492 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7493 -               lbs_pr_err("command response incorrect!\n");
7494 -               kfree(response_buf);
7495 -               free_page(addr);
7496 -               return 0;
7497 -       }
7498 -
7499 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7500 -       event = (void *)(response_buf + S_DS_GEN);
7501 -       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
7502 -               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
7503 -               switch (header->type) {
7504 -               struct mrvlietypes_snrthreshold *HighSnr;
7505 -               case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH):
7506 -                       HighSnr = (void *)(response_buf + cmd_len);
7507 -                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
7508 -                                       HighSnr->snrvalue,
7509 -                                       HighSnr->snrfreq,
7510 -                                       (event->events & cpu_to_le16(0x0020))?1:0);
7511 -               default:
7512 -                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
7513 -                       break;
7514 -               }
7515 -       }
7516 +       return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
7517 +               file, userbuf, count, ppos);
7518 +}
7519  
7520 -       kfree(response_buf);
7521  
7522 -       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7523 -       free_page(addr);
7524 -       return res;
7525 +static ssize_t lbs_bcnmiss_write(
7526 +       struct file *file, const char __user *userbuf,
7527 +       size_t count, loff_t *ppos)
7528 +{
7529 +       return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
7530 +               file, userbuf, count, ppos);
7531  }
7532  
7533 -static ssize_t libertas_highsnr_write(struct file *file,
7534 -                                   const char __user *userbuf,
7535 -                                   size_t count, loff_t *ppos)
7536 -{
7537 -       wlan_private *priv = file->private_data;
7538 -       wlan_adapter *adapter = priv->adapter;
7539 -       ssize_t res, buf_size;
7540 -       int value, freq, subscribed, cmd_len;
7541 -       struct cmd_ctrl_node *pcmdnode;
7542 -       struct cmd_ds_command *pcmdptr;
7543 -       struct cmd_ds_802_11_subscribe_event *event;
7544 -       struct mrvlietypes_snrthreshold *snr_threshold;
7545 -       void *response_buf;
7546 -       u16 event_bitmap;
7547 -       u8 *ptr;
7548 -       unsigned long addr = get_zeroed_page(GFP_KERNEL);
7549 -       char *buf = (char *)addr;
7550  
7551 -       buf_size = min(count, len - 1);
7552 -       if (copy_from_user(buf, userbuf, buf_size)) {
7553 -               res = -EFAULT;
7554 -               goto out_unlock;
7555 -       }
7556 -       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
7557 -       if (res != 3) {
7558 -               res = -EFAULT;
7559 -               goto out_unlock;
7560 -       }
7561  
7562 -       event_bitmap = libertas_get_events_bitmap(priv);
7563  
7564 -       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
7565 -       if (res < 0)
7566 -               goto out_unlock;
7567  
7568 -       event = &pcmdptr->params.subscribe_event;
7569 -       event->action = cpu_to_le16(cmd_act_set);
7570 -       pcmdptr->size = cpu_to_le16(S_DS_GEN +
7571 -               sizeof(struct cmd_ds_802_11_subscribe_event) +
7572 -               sizeof(struct mrvlietypes_snrthreshold));
7573 -       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
7574 -       ptr = (u8*) pcmdptr+cmd_len;
7575 -       snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
7576 -       snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
7577 -       snr_threshold->header.len = cpu_to_le16(2);
7578 -       snr_threshold->snrvalue = value;
7579 -       snr_threshold->snrfreq = freq;
7580 -       event_bitmap |= subscribed ? 0x0020 : 0x0;
7581 -       event->events = cpu_to_le16(event_bitmap);
7582 -
7583 -       libertas_queue_cmd(adapter, pcmdnode, 1);
7584 -       wake_up_interruptible(&priv->mainthread.waitq);
7585 -
7586 -       /* Sleep until response is generated by FW */
7587 -       wait_event_interruptible(pcmdnode->cmdwait_q,
7588 -                                pcmdnode->cmdwaitqwoken);
7589 -
7590 -       pcmdptr = response_buf;
7591 -
7592 -       if (pcmdptr->result) {
7593 -               lbs_pr_err("%s: fail, result=%d\n", __func__,
7594 -                          le16_to_cpu(pcmdptr->result));
7595 -               kfree(response_buf);
7596 -               free_page(addr);
7597 -               return 0;
7598 -       }
7599  
7600 -       if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
7601 -               lbs_pr_err("command response incorrect!\n");
7602 -               kfree(response_buf);
7603 -               free_page(addr);
7604 -               return 0;
7605 -       }
7606  
7607 -       res = count;
7608 -out_unlock:
7609 -       free_page(addr);
7610 -       return res;
7611 -}
7612  
7613 -static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
7614 +static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
7615                                   size_t count, loff_t *ppos)
7616  {
7617 -       wlan_private *priv = file->private_data;
7618 -       wlan_adapter *adapter = priv->adapter;
7619 -       struct wlan_offset_value offval;
7620 +       struct lbs_private *priv = file->private_data;
7621 +       struct lbs_offset_value offval;
7622         ssize_t pos = 0;
7623         int ret;
7624         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7625 @@ -1374,23 +628,23 @@ static ssize_t libertas_rdmac_read(struc
7626         offval.offset = priv->mac_offset;
7627         offval.value = 0;
7628  
7629 -       ret = libertas_prepare_and_send_command(priv,
7630 -                               cmd_mac_reg_access, 0,
7631 -                               cmd_option_waitforrsp, 0, &offval);
7632 +       ret = lbs_prepare_and_send_command(priv,
7633 +                               CMD_MAC_REG_ACCESS, 0,
7634 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7635         mdelay(10);
7636         pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
7637 -                               priv->mac_offset, adapter->offsetvalue.value);
7638 +                               priv->mac_offset, priv->offsetvalue.value);
7639  
7640         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7641         free_page(addr);
7642         return ret;
7643  }
7644  
7645 -static ssize_t libertas_rdmac_write(struct file *file,
7646 +static ssize_t lbs_rdmac_write(struct file *file,
7647                                     const char __user *userbuf,
7648                                     size_t count, loff_t *ppos)
7649  {
7650 -       wlan_private *priv = file->private_data;
7651 +       struct lbs_private *priv = file->private_data;
7652         ssize_t res, buf_size;
7653         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7654         char *buf = (char *)addr;
7655 @@ -1407,15 +661,15 @@ out_unlock:
7656         return res;
7657  }
7658  
7659 -static ssize_t libertas_wrmac_write(struct file *file,
7660 +static ssize_t lbs_wrmac_write(struct file *file,
7661                                     const char __user *userbuf,
7662                                     size_t count, loff_t *ppos)
7663  {
7664  
7665 -       wlan_private *priv = file->private_data;
7666 +       struct lbs_private *priv = file->private_data;
7667         ssize_t res, buf_size;
7668         u32 offset, value;
7669 -       struct wlan_offset_value offval;
7670 +       struct lbs_offset_value offval;
7671         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7672         char *buf = (char *)addr;
7673  
7674 @@ -1432,9 +686,9 @@ static ssize_t libertas_wrmac_write(stru
7675  
7676         offval.offset = offset;
7677         offval.value = value;
7678 -       res = libertas_prepare_and_send_command(priv,
7679 -                               cmd_mac_reg_access, 1,
7680 -                               cmd_option_waitforrsp, 0, &offval);
7681 +       res = lbs_prepare_and_send_command(priv,
7682 +                               CMD_MAC_REG_ACCESS, 1,
7683 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7684         mdelay(10);
7685  
7686         res = count;
7687 @@ -1443,12 +697,11 @@ out_unlock:
7688         return res;
7689  }
7690  
7691 -static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
7692 +static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
7693                                   size_t count, loff_t *ppos)
7694  {
7695 -       wlan_private *priv = file->private_data;
7696 -       wlan_adapter *adapter = priv->adapter;
7697 -       struct wlan_offset_value offval;
7698 +       struct lbs_private *priv = file->private_data;
7699 +       struct lbs_offset_value offval;
7700         ssize_t pos = 0;
7701         int ret;
7702         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7703 @@ -1457,12 +710,12 @@ static ssize_t libertas_rdbbp_read(struc
7704         offval.offset = priv->bbp_offset;
7705         offval.value = 0;
7706  
7707 -       ret = libertas_prepare_and_send_command(priv,
7708 -                               cmd_bbp_reg_access, 0,
7709 -                               cmd_option_waitforrsp, 0, &offval);
7710 +       ret = lbs_prepare_and_send_command(priv,
7711 +                               CMD_BBP_REG_ACCESS, 0,
7712 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7713         mdelay(10);
7714         pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
7715 -                               priv->bbp_offset, adapter->offsetvalue.value);
7716 +                               priv->bbp_offset, priv->offsetvalue.value);
7717  
7718         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7719         free_page(addr);
7720 @@ -1470,11 +723,11 @@ static ssize_t libertas_rdbbp_read(struc
7721         return ret;
7722  }
7723  
7724 -static ssize_t libertas_rdbbp_write(struct file *file,
7725 +static ssize_t lbs_rdbbp_write(struct file *file,
7726                                     const char __user *userbuf,
7727                                     size_t count, loff_t *ppos)
7728  {
7729 -       wlan_private *priv = file->private_data;
7730 +       struct lbs_private *priv = file->private_data;
7731         ssize_t res, buf_size;
7732         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7733         char *buf = (char *)addr;
7734 @@ -1491,15 +744,15 @@ out_unlock:
7735         return res;
7736  }
7737  
7738 -static ssize_t libertas_wrbbp_write(struct file *file,
7739 +static ssize_t lbs_wrbbp_write(struct file *file,
7740                                     const char __user *userbuf,
7741                                     size_t count, loff_t *ppos)
7742  {
7743  
7744 -       wlan_private *priv = file->private_data;
7745 +       struct lbs_private *priv = file->private_data;
7746         ssize_t res, buf_size;
7747         u32 offset, value;
7748 -       struct wlan_offset_value offval;
7749 +       struct lbs_offset_value offval;
7750         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7751         char *buf = (char *)addr;
7752  
7753 @@ -1516,9 +769,9 @@ static ssize_t libertas_wrbbp_write(stru
7754  
7755         offval.offset = offset;
7756         offval.value = value;
7757 -       res = libertas_prepare_and_send_command(priv,
7758 -                               cmd_bbp_reg_access, 1,
7759 -                               cmd_option_waitforrsp, 0, &offval);
7760 +       res = lbs_prepare_and_send_command(priv,
7761 +                               CMD_BBP_REG_ACCESS, 1,
7762 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7763         mdelay(10);
7764  
7765         res = count;
7766 @@ -1527,12 +780,11 @@ out_unlock:
7767         return res;
7768  }
7769  
7770 -static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
7771 +static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
7772                                   size_t count, loff_t *ppos)
7773  {
7774 -       wlan_private *priv = file->private_data;
7775 -       wlan_adapter *adapter = priv->adapter;
7776 -       struct wlan_offset_value offval;
7777 +       struct lbs_private *priv = file->private_data;
7778 +       struct lbs_offset_value offval;
7779         ssize_t pos = 0;
7780         int ret;
7781         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7782 @@ -1541,12 +793,12 @@ static ssize_t libertas_rdrf_read(struct
7783         offval.offset = priv->rf_offset;
7784         offval.value = 0;
7785  
7786 -       ret = libertas_prepare_and_send_command(priv,
7787 -                               cmd_rf_reg_access, 0,
7788 -                               cmd_option_waitforrsp, 0, &offval);
7789 +       ret = lbs_prepare_and_send_command(priv,
7790 +                               CMD_RF_REG_ACCESS, 0,
7791 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7792         mdelay(10);
7793         pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
7794 -                               priv->rf_offset, adapter->offsetvalue.value);
7795 +                               priv->rf_offset, priv->offsetvalue.value);
7796  
7797         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
7798         free_page(addr);
7799 @@ -1554,11 +806,11 @@ static ssize_t libertas_rdrf_read(struct
7800         return ret;
7801  }
7802  
7803 -static ssize_t libertas_rdrf_write(struct file *file,
7804 +static ssize_t lbs_rdrf_write(struct file *file,
7805                                     const char __user *userbuf,
7806                                     size_t count, loff_t *ppos)
7807  {
7808 -       wlan_private *priv = file->private_data;
7809 +       struct lbs_private *priv = file->private_data;
7810         ssize_t res, buf_size;
7811         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7812         char *buf = (char *)addr;
7813 @@ -1575,15 +827,15 @@ out_unlock:
7814         return res;
7815  }
7816  
7817 -static ssize_t libertas_wrrf_write(struct file *file,
7818 +static ssize_t lbs_wrrf_write(struct file *file,
7819                                     const char __user *userbuf,
7820                                     size_t count, loff_t *ppos)
7821  {
7822  
7823 -       wlan_private *priv = file->private_data;
7824 +       struct lbs_private *priv = file->private_data;
7825         ssize_t res, buf_size;
7826         u32 offset, value;
7827 -       struct wlan_offset_value offval;
7828 +       struct lbs_offset_value offval;
7829         unsigned long addr = get_zeroed_page(GFP_KERNEL);
7830         char *buf = (char *)addr;
7831  
7832 @@ -1600,9 +852,9 @@ static ssize_t libertas_wrrf_write(struc
7833  
7834         offval.offset = offset;
7835         offval.value = value;
7836 -       res = libertas_prepare_and_send_command(priv,
7837 -                               cmd_rf_reg_access, 1,
7838 -                               cmd_option_waitforrsp, 0, &offval);
7839 +       res = lbs_prepare_and_send_command(priv,
7840 +                               CMD_RF_REG_ACCESS, 1,
7841 +                               CMD_OPTION_WAITFORRSP, 0, &offval);
7842         mdelay(10);
7843  
7844         res = count;
7845 @@ -1618,69 +870,69 @@ out_unlock:
7846         .write = (fwrite), \
7847  }
7848  
7849 -struct libertas_debugfs_files {
7850 +struct lbs_debugfs_files {
7851         char *name;
7852         int perm;
7853         struct file_operations fops;
7854  };
7855  
7856 -static struct libertas_debugfs_files debugfs_files[] = {
7857 -       { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
7858 -       { "getscantable", 0444, FOPS(libertas_getscantable,
7859 +static struct lbs_debugfs_files debugfs_files[] = {
7860 +       { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
7861 +       { "getscantable", 0444, FOPS(lbs_getscantable,
7862                                         write_file_dummy), },
7863 -       { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
7864 -                               libertas_sleepparams_write), },
7865 -       { "extscan", 0600, FOPS(NULL, libertas_extscan), },
7866 -       { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
7867 +       { "sleepparams", 0644, FOPS(lbs_sleepparams_read,
7868 +                               lbs_sleepparams_write), },
7869 +       { "extscan", 0600, FOPS(NULL, lbs_extscan), },
7870 +       { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), },
7871  };
7872  
7873 -static struct libertas_debugfs_files debugfs_events_files[] = {
7874 -       {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
7875 -                               libertas_lowrssi_write), },
7876 -       {"low_snr", 0644, FOPS(libertas_lowsnr_read,
7877 -                               libertas_lowsnr_write), },
7878 -       {"failure_count", 0644, FOPS(libertas_failcount_read,
7879 -                               libertas_failcount_write), },
7880 -       {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
7881 -                               libertas_bcnmiss_write), },
7882 -       {"high_rssi", 0644, FOPS(libertas_highrssi_read,
7883 -                               libertas_highrssi_write), },
7884 -       {"high_snr", 0644, FOPS(libertas_highsnr_read,
7885 -                               libertas_highsnr_write), },
7886 +static struct lbs_debugfs_files debugfs_events_files[] = {
7887 +       {"low_rssi", 0644, FOPS(lbs_lowrssi_read,
7888 +                               lbs_lowrssi_write), },
7889 +       {"low_snr", 0644, FOPS(lbs_lowsnr_read,
7890 +                               lbs_lowsnr_write), },
7891 +       {"failure_count", 0644, FOPS(lbs_failcount_read,
7892 +                               lbs_failcount_write), },
7893 +       {"beacon_missed", 0644, FOPS(lbs_bcnmiss_read,
7894 +                               lbs_bcnmiss_write), },
7895 +       {"high_rssi", 0644, FOPS(lbs_highrssi_read,
7896 +                               lbs_highrssi_write), },
7897 +       {"high_snr", 0644, FOPS(lbs_highsnr_read,
7898 +                               lbs_highsnr_write), },
7899  };
7900  
7901 -static struct libertas_debugfs_files debugfs_regs_files[] = {
7902 -       {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
7903 -       {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
7904 -       {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
7905 -       {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
7906 -       {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
7907 -       {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
7908 +static struct lbs_debugfs_files debugfs_regs_files[] = {
7909 +       {"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
7910 +       {"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
7911 +       {"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
7912 +       {"wrbbp", 0600, FOPS(NULL, lbs_wrbbp_write), },
7913 +       {"rdrf", 0644, FOPS(lbs_rdrf_read, lbs_rdrf_write), },
7914 +       {"wrrf", 0600, FOPS(NULL, lbs_wrrf_write), },
7915  };
7916  
7917 -void libertas_debugfs_init(void)
7918 +void lbs_debugfs_init(void)
7919  {
7920 -       if (!libertas_dir)
7921 -               libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
7922 +       if (!lbs_dir)
7923 +               lbs_dir = debugfs_create_dir("lbs_wireless", NULL);
7924  
7925         return;
7926  }
7927  
7928 -void libertas_debugfs_remove(void)
7929 +void lbs_debugfs_remove(void)
7930  {
7931 -       if (libertas_dir)
7932 -                debugfs_remove(libertas_dir);
7933 +       if (lbs_dir)
7934 +                debugfs_remove(lbs_dir);
7935         return;
7936  }
7937  
7938 -void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
7939 +void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
7940  {
7941         int i;
7942 -       struct libertas_debugfs_files *files;
7943 -       if (!libertas_dir)
7944 +       struct lbs_debugfs_files *files;
7945 +       if (!lbs_dir)
7946                 goto exit;
7947  
7948 -       priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
7949 +       priv->debugfs_dir = debugfs_create_dir(dev->name, lbs_dir);
7950         if (!priv->debugfs_dir)
7951                 goto exit;
7952  
7953 @@ -1720,13 +972,13 @@ void libertas_debugfs_init_one(wlan_priv
7954         }
7955  
7956  #ifdef PROC_DEBUG
7957 -       libertas_debug_init(priv, dev);
7958 +       lbs_debug_init(priv, dev);
7959  #endif
7960  exit:
7961         return;
7962  }
7963  
7964 -void libertas_debugfs_remove_one(wlan_private *priv)
7965 +void lbs_debugfs_remove_one(struct lbs_private *priv)
7966  {
7967         int i;
7968  
7969 @@ -1753,8 +1005,8 @@ void libertas_debugfs_remove_one(wlan_pr
7970  
7971  #ifdef PROC_DEBUG
7972  
7973 -#define item_size(n)   (FIELD_SIZEOF(wlan_adapter, n))
7974 -#define item_addr(n)   (offsetof(wlan_adapter, n))
7975 +#define item_size(n)   (FIELD_SIZEOF(struct lbs_private, n))
7976 +#define item_addr(n)   (offsetof(struct lbs_private, n))
7977  
7978  
7979  struct debug_data {
7980 @@ -1763,7 +1015,7 @@ struct debug_data {
7981         size_t addr;
7982  };
7983  
7984 -/* To debug any member of wlan_adapter, simply add one line here.
7985 +/* To debug any member of struct lbs_private, simply add one line here.
7986   */
7987  static struct debug_data items[] = {
7988         {"intcounter", item_size(intcounter), item_addr(intcounter)},
7989 @@ -1784,7 +1036,7 @@ static int num_of_items = ARRAY_SIZE(ite
7990   *  @param data    data to output
7991   *  @return       number of output data
7992   */
7993 -static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
7994 +static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
7995                         size_t count, loff_t *ppos)
7996  {
7997         int val = 0;
7998 @@ -1828,7 +1080,7 @@ static ssize_t wlan_debugfs_read(struct 
7999   *  @param data    data to write
8000   *  @return       number of data
8001   */
8002 -static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
8003 +static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
8004                             size_t cnt, loff_t *ppos)
8005  {
8006         int r, i;
8007 @@ -1839,7 +1091,7 @@ static ssize_t wlan_debugfs_write(struct
8008         char *p2;
8009         struct debug_data *d = (struct debug_data *)f->private_data;
8010  
8011 -       pdata = (char *)kmalloc(cnt, GFP_KERNEL);
8012 +       pdata = kmalloc(cnt, GFP_KERNEL);
8013         if (pdata == NULL)
8014                 return 0;
8015  
8016 @@ -1880,21 +1132,21 @@ static ssize_t wlan_debugfs_write(struct
8017         return (ssize_t)cnt;
8018  }
8019  
8020 -static struct file_operations libertas_debug_fops = {
8021 +static struct file_operations lbs_debug_fops = {
8022         .owner = THIS_MODULE,
8023         .open = open_file_generic,
8024 -       .write = wlan_debugfs_write,
8025 -       .read = wlan_debugfs_read,
8026 +       .write = lbs_debugfs_write,
8027 +       .read = lbs_debugfs_read,
8028  };
8029  
8030  /**
8031   *  @brief create debug proc file
8032   *
8033 - *  @param priv           pointer wlan_private
8034 + *  @param priv           pointer struct lbs_private
8035   *  @param dev     pointer net_device
8036   *  @return       N/A
8037   */
8038 -static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
8039 +static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev)
8040  {
8041         int i;
8042  
8043 @@ -1902,11 +1154,10 @@ static void libertas_debug_init(wlan_pri
8044                 return;
8045  
8046         for (i = 0; i < num_of_items; i++)
8047 -               items[i].addr += (size_t) priv->adapter;
8048 +               items[i].addr += (size_t) priv;
8049  
8050         priv->debugfs_debug = debugfs_create_file("debug", 0644,
8051                                                   priv->debugfs_dir, &items[0],
8052 -                                                 &libertas_debug_fops);
8053 +                                                 &lbs_debug_fops);
8054  }
8055  #endif
8056 -
8057 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/debugfs.h linux-2.6.22-300/drivers/net/wireless/libertas/debugfs.h
8058 --- linux-2.6.22-250/drivers/net/wireless/libertas/debugfs.h    2007-07-08 19:32:17.000000000 -0400
8059 +++ linux-2.6.22-300/drivers/net/wireless/libertas/debugfs.h    2008-05-27 16:42:14.000000000 -0400
8060 @@ -1,6 +1,10 @@
8061 -void libertas_debugfs_init(void);
8062 -void libertas_debugfs_remove(void);
8063 +#ifndef _LBS_DEBUGFS_H_
8064 +#define _LBS_DEBUGFS_H_
8065  
8066 -void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev);
8067 -void libertas_debugfs_remove_one(wlan_private *priv);
8068 +void lbs_debugfs_init(void);
8069 +void lbs_debugfs_remove(void);
8070  
8071 +void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev);
8072 +void lbs_debugfs_remove_one(struct lbs_private *priv);
8073 +
8074 +#endif
8075 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/decl.h linux-2.6.22-300/drivers/net/wireless/libertas/decl.h
8076 --- linux-2.6.22-250/drivers/net/wireless/libertas/decl.h       2007-07-08 19:32:17.000000000 -0400
8077 +++ linux-2.6.22-300/drivers/net/wireless/libertas/decl.h       2008-06-05 18:10:06.000000000 -0400
8078 @@ -3,89 +3,78 @@
8079    *  functions defined in other source files
8080    */
8081  
8082 -#ifndef _WLAN_DECL_H_
8083 -#define _WLAN_DECL_H_
8084 +#ifndef _LBS_DECL_H_
8085 +#define _LBS_DECL_H_
8086  
8087  #include <linux/device.h>
8088  
8089  #include "defs.h"
8090  
8091  /** Function Prototype Declaration */
8092 -struct wlan_private;
8093 +struct lbs_private;
8094  struct sk_buff;
8095  struct net_device;
8096 -
8097 -extern char *libertas_fw_name;
8098 -
8099 -void libertas_free_adapter(wlan_private * priv);
8100 -int libertas_set_mac_packet_filter(wlan_private * priv);
8101 -
8102 -int libertas_send_null_packet(wlan_private * priv, u8 pwr_mgmt);
8103 -void libertas_send_tx_feedback(wlan_private * priv);
8104 -u8 libertas_check_last_packet_indication(wlan_private * priv);
8105 -
8106 -int libertas_free_cmd_buffer(wlan_private * priv);
8107  struct cmd_ctrl_node;
8108 -struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv);
8109 +struct cmd_ds_command;
8110  
8111 -void libertas_set_cmd_ctrl_node(wlan_private * priv,
8112 -                   struct cmd_ctrl_node *ptempnode,
8113 -                   u32 cmd_oid, u16 wait_option, void *pdata_buf);
8114 -
8115 -int libertas_prepare_and_send_command(wlan_private * priv,
8116 -                         u16 cmd_no,
8117 -                         u16 cmd_action,
8118 -                         u16 wait_option, u32 cmd_oid, void *pdata_buf);
8119 -
8120 -void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail);
8121 -
8122 -int libertas_allocate_cmd_buffer(wlan_private * priv);
8123 -int libertas_execute_next_command(wlan_private * priv);
8124 -int libertas_process_event(wlan_private * priv);
8125 -void libertas_interrupt(struct net_device *);
8126 -int libertas_set_radio_control(wlan_private * priv);
8127 -u32 libertas_index_to_data_rate(u8 index);
8128 -u8 libertas_data_rate_to_index(u32 rate);
8129 -void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
8130 -
8131 -void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
8132 -
8133 -/** The proc fs interface */
8134 -int libertas_process_rx_command(wlan_private * priv);
8135 -int libertas_process_tx(wlan_private * priv, struct sk_buff *skb);
8136 -void libertas_cleanup_and_insert_cmd(wlan_private * priv,
8137 -                                       struct cmd_ctrl_node *ptempcmd);
8138 -void __libertas_cleanup_and_insert_cmd(wlan_private * priv,
8139 -                                       struct cmd_ctrl_node *ptempcmd);
8140 +void lbs_set_mac_control(struct lbs_private *priv);
8141  
8142 -int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band);
8143 +void lbs_send_tx_feedback(struct lbs_private *priv);
8144  
8145 -int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *);
8146 +int lbs_free_cmd_buffer(struct lbs_private *priv);
8147  
8148 -void libertas_ps_sleep(wlan_private * priv, int wait_option);
8149 -void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode);
8150 -void libertas_ps_wakeup(wlan_private * priv, int wait_option);
8151 +int lbs_prepare_and_send_command(struct lbs_private *priv,
8152 +       u16 cmd_no,
8153 +       u16 cmd_action,
8154 +       u16 wait_option, u32 cmd_oid, void *pdata_buf);
8155 +
8156 +int lbs_allocate_cmd_buffer(struct lbs_private *priv);
8157 +int lbs_execute_next_command(struct lbs_private *priv);
8158 +int lbs_process_event(struct lbs_private *priv);
8159 +void lbs_interrupt(struct lbs_private *priv);
8160 +int lbs_set_radio_control(struct lbs_private *priv);
8161 +u32 lbs_fw_index_to_data_rate(u8 index);
8162 +u8 lbs_data_rate_to_fw_index(u32 rate);
8163 +void lbs_get_fwversion(struct lbs_private *priv,
8164 +       char *fwversion,
8165 +       int maxlen);
8166  
8167 -void libertas_tx_runqueue(wlan_private *priv);
8168 -
8169 -struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
8170 -                               wlan_adapter * adapter, u8 band, u16 channel);
8171 -
8172 -void libertas_mac_event_disconnected(wlan_private * priv);
8173 -
8174 -void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
8175 -
8176 -/* fw.c */
8177 -int libertas_init_fw(wlan_private * priv, char *fw_name);
8178 +/** The proc fs interface */
8179 +int lbs_process_rx_command(struct lbs_private *priv);
8180 +void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
8181 +                         int result);
8182 +int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
8183 +int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
8184 +
8185 +int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
8186 +
8187 +void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
8188 +void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode);
8189 +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
8190 +
8191 +struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
8192 +       struct lbs_private *priv,
8193 +       u8 band,
8194 +       u16 channel);
8195 +
8196 +void lbs_mac_event_disconnected(struct lbs_private *priv);
8197 +
8198 +void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str);
8199 +
8200 +/* persistcfg.c */
8201 +void lbs_persist_config_init(struct net_device *net);
8202 +void lbs_persist_config_remove(struct net_device *net);
8203  
8204  /* main.c */
8205 -struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
8206 -                                                            int *cfp_no);
8207 -wlan_private *libertas_add_card(void *card, struct device *dmdev);
8208 -int libertas_activate_card(wlan_private *priv, char *fw_name);
8209 -int libertas_remove_card(wlan_private *priv);
8210 -int libertas_add_mesh(wlan_private *priv, struct device *dev);
8211 -void libertas_remove_mesh(wlan_private *priv);
8212 -
8213 +struct chan_freq_power *lbs_get_region_cfp_table(u8 region,
8214 +       u8 band,
8215 +       int *cfp_no);
8216 +struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
8217 +int lbs_remove_card(struct lbs_private *priv);
8218 +int lbs_start_card(struct lbs_private *priv);
8219 +int lbs_stop_card(struct lbs_private *priv);
8220 +int lbs_reset_device(struct lbs_private *priv);
8221 +void lbs_host_to_card_done(struct lbs_private *priv);
8222  
8223 -#endif                         /* _WLAN_DECL_H_ */
8224 +int lbs_update_channel(struct lbs_private *priv);
8225 +#endif
8226 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/defs.h linux-2.6.22-300/drivers/net/wireless/libertas/defs.h
8227 --- linux-2.6.22-250/drivers/net/wireless/libertas/defs.h       2007-07-08 19:32:17.000000000 -0400
8228 +++ linux-2.6.22-300/drivers/net/wireless/libertas/defs.h       2008-06-05 18:10:06.000000000 -0400
8229 @@ -2,8 +2,8 @@
8230    * This header file contains global constant/enum definitions,
8231    * global variable declaration.
8232    */
8233 -#ifndef _WLAN_DEFS_H_
8234 -#define _WLAN_DEFS_H_
8235 +#ifndef _LBS_DEFS_H_
8236 +#define _LBS_DEFS_H_
8237  
8238  #include <linux/spinlock.h>
8239  
8240 @@ -39,47 +39,51 @@
8241  #define LBS_DEB_FW     0x00080000
8242  #define LBS_DEB_THREAD 0x00100000
8243  #define LBS_DEB_HEX    0x00200000
8244 +#define LBS_DEB_SDIO   0x00400000
8245 +#define LBS_DEB_SYSFS  0x00800000
8246  
8247 -extern unsigned int libertas_debug;
8248 +extern unsigned int lbs_debug;
8249  
8250  #ifdef DEBUG
8251 -#define LBS_DEB_LL(grp, fmt, args...) \
8252 -do { if ((libertas_debug & (grp)) == (grp)) \
8253 -  printk(KERN_DEBUG DRV_NAME "%s: " fmt, \
8254 +#define LBS_DEB_LL(grp, grpnam, fmt, args...) \
8255 +do { if ((lbs_debug & (grp)) == (grp)) \
8256 +  printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \
8257           in_interrupt() ? " (INT)" : "", ## args); } while (0)
8258  #else
8259 -#define LBS_DEB_LL(grp, fmt, args...) do {} while (0)
8260 +#define LBS_DEB_LL(grp, grpnam, fmt, args...) do {} while (0)
8261  #endif
8262  
8263  #define lbs_deb_enter(grp) \
8264 -  LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s():%d enter\n", __FUNCTION__, __LINE__);
8265 +  LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s():%d\n", __FUNCTION__, __LINE__);
8266  #define lbs_deb_enter_args(grp, fmt, args...) \
8267 -  LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__);
8268 +  LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__);
8269  #define lbs_deb_leave(grp) \
8270 -  LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave\n", __FUNCTION__, __LINE__);
8271 +  LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d\n", __FUNCTION__, __LINE__);
8272  #define lbs_deb_leave_args(grp, fmt, args...) \
8273 -  LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave, " fmt "\n", \
8274 +  LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d, " fmt "\n", \
8275    __FUNCTION__, __LINE__, ##args);
8276 -#define lbs_deb_main(fmt, args...)      LBS_DEB_LL(LBS_DEB_MAIN, fmt, ##args)
8277 -#define lbs_deb_net(fmt, args...)       LBS_DEB_LL(LBS_DEB_NET, fmt, ##args)
8278 -#define lbs_deb_mesh(fmt, args...)      LBS_DEB_LL(LBS_DEB_MESH, fmt, ##args)
8279 -#define lbs_deb_wext(fmt, args...)      LBS_DEB_LL(LBS_DEB_WEXT, fmt, ##args)
8280 -#define lbs_deb_ioctl(fmt, args...)     LBS_DEB_LL(LBS_DEB_IOCTL, fmt, ##args)
8281 -#define lbs_deb_scan(fmt, args...)      LBS_DEB_LL(LBS_DEB_SCAN, fmt, ##args)
8282 -#define lbs_deb_assoc(fmt, args...)     LBS_DEB_LL(LBS_DEB_ASSOC, fmt, ##args)
8283 -#define lbs_deb_join(fmt, args...)      LBS_DEB_LL(LBS_DEB_JOIN, fmt, ##args)
8284 -#define lbs_deb_11d(fmt, args...)       LBS_DEB_LL(LBS_DEB_11D, fmt, ##args)
8285 -#define lbs_deb_debugfs(fmt, args...)   LBS_DEB_LL(LBS_DEB_DEBUGFS, fmt, ##args)
8286 -#define lbs_deb_ethtool(fmt, args...)   LBS_DEB_LL(LBS_DEB_ETHTOOL, fmt, ##args)
8287 -#define lbs_deb_host(fmt, args...)      LBS_DEB_LL(LBS_DEB_HOST, fmt, ##args)
8288 -#define lbs_deb_cmd(fmt, args...)       LBS_DEB_LL(LBS_DEB_CMD, fmt, ##args)
8289 -#define lbs_deb_rx(fmt, args...)        LBS_DEB_LL(LBS_DEB_RX, fmt, ##args)
8290 -#define lbs_deb_tx(fmt, args...)        LBS_DEB_LL(LBS_DEB_TX, fmt, ##args)
8291 -#define lbs_deb_fw(fmt, args...)        LBS_DEB_LL(LBS_DEB_FW, fmt, ##args)
8292 -#define lbs_deb_usb(fmt, args...)       LBS_DEB_LL(LBS_DEB_USB, fmt, ##args)
8293 -#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, "%s:" fmt, (dev)->bus_id, ##args)
8294 -#define lbs_deb_cs(fmt, args...)        LBS_DEB_LL(LBS_DEB_CS, fmt, ##args)
8295 -#define lbs_deb_thread(fmt, args...)    LBS_DEB_LL(LBS_DEB_THREAD, fmt, ##args)
8296 +#define lbs_deb_main(fmt, args...)      LBS_DEB_LL(LBS_DEB_MAIN, " main", fmt, ##args)
8297 +#define lbs_deb_net(fmt, args...)       LBS_DEB_LL(LBS_DEB_NET, " net", fmt, ##args)
8298 +#define lbs_deb_mesh(fmt, args...)      LBS_DEB_LL(LBS_DEB_MESH, " mesh", fmt, ##args)
8299 +#define lbs_deb_wext(fmt, args...)      LBS_DEB_LL(LBS_DEB_WEXT, " wext", fmt, ##args)
8300 +#define lbs_deb_ioctl(fmt, args...)     LBS_DEB_LL(LBS_DEB_IOCTL, " ioctl", fmt, ##args)
8301 +#define lbs_deb_scan(fmt, args...)      LBS_DEB_LL(LBS_DEB_SCAN, " scan", fmt, ##args)
8302 +#define lbs_deb_assoc(fmt, args...)     LBS_DEB_LL(LBS_DEB_ASSOC, " assoc", fmt, ##args)
8303 +#define lbs_deb_join(fmt, args...)      LBS_DEB_LL(LBS_DEB_JOIN, " join", fmt, ##args)
8304 +#define lbs_deb_11d(fmt, args...)       LBS_DEB_LL(LBS_DEB_11D, " 11d", fmt, ##args)
8305 +#define lbs_deb_debugfs(fmt, args...)   LBS_DEB_LL(LBS_DEB_DEBUGFS, " debugfs", fmt, ##args)
8306 +#define lbs_deb_ethtool(fmt, args...)   LBS_DEB_LL(LBS_DEB_ETHTOOL, " ethtool", fmt, ##args)
8307 +#define lbs_deb_host(fmt, args...)      LBS_DEB_LL(LBS_DEB_HOST, " host", fmt, ##args)
8308 +#define lbs_deb_cmd(fmt, args...)       LBS_DEB_LL(LBS_DEB_CMD, " cmd", fmt, ##args)
8309 +#define lbs_deb_rx(fmt, args...)        LBS_DEB_LL(LBS_DEB_RX, " rx", fmt, ##args)
8310 +#define lbs_deb_tx(fmt, args...)        LBS_DEB_LL(LBS_DEB_TX, " tx", fmt, ##args)
8311 +#define lbs_deb_fw(fmt, args...)        LBS_DEB_LL(LBS_DEB_FW, " fw", fmt, ##args)
8312 +#define lbs_deb_usb(fmt, args...)       LBS_DEB_LL(LBS_DEB_USB, " usb", fmt, ##args)
8313 +#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args)
8314 +#define lbs_deb_cs(fmt, args...)        LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args)
8315 +#define lbs_deb_thread(fmt, args...)    LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
8316 +#define lbs_deb_sdio(fmt, args...)      LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
8317 +#define lbs_deb_sysfs(fmt, args...)     LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
8318  
8319  #define lbs_pr_info(format, args...) \
8320         printk(KERN_INFO DRV_NAME": " format, ## args)
8321 @@ -89,22 +93,28 @@ do { if ((libertas_debug & (grp)) == (gr
8322         printk(KERN_ALERT DRV_NAME": " format, ## args)
8323  
8324  #ifdef DEBUG
8325 -static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
8326 +static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
8327  {
8328         int i = 0;
8329  
8330 -       if (!(libertas_debug & LBS_DEB_HEX))
8331 -               return;
8332 -
8333 -       printk(KERN_DEBUG "%s: ", prompt);
8334 -       for (i = 1; i <= len; i++) {
8335 -               printk("%02x ", (u8) * buf);
8336 -               buf++;
8337 +       if (len &&
8338 +           (lbs_debug & LBS_DEB_HEX) &&
8339 +           (lbs_debug & grp))
8340 +       {
8341 +               for (i = 1; i <= len; i++) {
8342 +                       if ((i & 0xf) == 1) {
8343 +                               if (i != 1)
8344 +                                       printk("\n");
8345 +                               printk(DRV_NAME " %s: ", prompt);
8346 +                       }
8347 +                       printk("%02x ", (u8) * buf);
8348 +                       buf++;
8349 +               }
8350 +               printk("\n");
8351         }
8352 -       printk("\n");
8353  }
8354  #else
8355 -#define lbs_dbg_hex(x,y,z)                             do {} while (0)
8356 +#define lbs_deb_hex(grp,prompt,buf,len)        do {} while (0)
8357  #endif
8358  
8359  
8360 @@ -124,15 +134,22 @@ static inline void lbs_dbg_hex(char *pro
8361  */
8362  
8363  #define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
8364 -#define MRVDRV_NUM_OF_CMD_BUFFER        10
8365 -#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
8366 +#define LBS_NUM_CMD_BUFFERS             10
8367 +#define LBS_CMD_BUFFER_SIZE             (2 * 1024)
8368  #define MRVDRV_MAX_CHANNEL_SIZE                14
8369  #define MRVDRV_ASSOCIATION_TIME_OUT    255
8370  #define MRVDRV_SNAP_HEADER_LEN          8
8371  
8372 -#define        WLAN_UPLD_SIZE                  2312
8373 +#define        LBS_UPLD_SIZE                   2312
8374  #define DEV_NAME_LEN                   32
8375  
8376 +/* Wake criteria for HOST_SLEEP_CFG command */
8377 +#define EHS_WAKE_ON_BROADCAST_DATA     0x0001
8378 +#define EHS_WAKE_ON_UNICAST_DATA       0x0002
8379 +#define EHS_WAKE_ON_MAC_EVENT          0x0004
8380 +#define EHS_WAKE_ON_MULTICAST_DATA     0x0008
8381 +#define EHS_REMOVE_WAKEUP              0xFFFFFFFF
8382 +
8383  /** Misc constants */
8384  /* This section defines 802.11 specific contants */
8385  
8386 @@ -149,17 +166,28 @@ static inline void lbs_dbg_hex(char *pro
8387  #define        MRVDRV_CHANNELS_PER_SCAN                4
8388  #define        MRVDRV_MAX_CHANNELS_PER_SCAN            14
8389  
8390 -#define MRVDRV_DEBUG_RX_PATH           0x00000001
8391 -#define MRVDRV_DEBUG_TX_PATH           0x00000002
8392 -
8393  #define MRVDRV_MIN_BEACON_INTERVAL             20
8394  #define MRVDRV_MAX_BEACON_INTERVAL             1000
8395  #define MRVDRV_BEACON_INTERVAL                 100
8396  
8397 +#define MARVELL_MESH_IE_LENGTH         9
8398 +
8399 +/* Values used to populate the struct mrvl_mesh_ie.  The only time you need this
8400 + * is when enabling the mesh using CMD_MESH_CONFIG.
8401 + */
8402 +#define MARVELL_MESH_IE_TYPE           4
8403 +#define MARVELL_MESH_IE_SUBTYPE                0
8404 +#define MARVELL_MESH_IE_VERSION                0
8405 +#define MARVELL_MESH_PROTO_ID_HWMP     0
8406 +#define MARVELL_MESH_METRIC_ID         0
8407 +#define MARVELL_MESH_CAPABILITY                0
8408 +
8409  /** INT status Bit Definition*/
8410 -#define his_cmddnldrdy                 0x01
8411 -#define his_cardevent                  0x02
8412 -#define his_cmdupldrdy                 0x04
8413 +#define MRVDRV_TX_DNLD_RDY             0x0001
8414 +#define MRVDRV_RX_UPLD_RDY             0x0002
8415 +#define MRVDRV_CMD_DNLD_RDY            0x0004
8416 +#define MRVDRV_CMD_UPLD_RDY            0x0008
8417 +#define MRVDRV_CARDEVENT               0x0010
8418  
8419  #define SBI_EVENT_CAUSE_SHIFT          3
8420  
8421 @@ -218,9 +246,6 @@ static inline void lbs_dbg_hex(char *pro
8422  #define        CMD_F_HOSTCMD           (1 << 0)
8423  #define FW_CAPINFO_WPA         (1 << 0)
8424  
8425 -/** WPA key LENGTH*/
8426 -#define MRVL_MAX_KEY_WPA_KEY_LENGTH     32
8427 -
8428  #define KEY_LEN_WPA_AES                        16
8429  #define KEY_LEN_WPA_TKIP               32
8430  #define KEY_LEN_WEP_104                        13
8431 @@ -247,28 +272,15 @@ static inline void lbs_dbg_hex(char *pro
8432                          ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \
8433                          AVG_SCALE))  / N))
8434  
8435 -#define B_SUPPORTED_RATES              8
8436 -#define G_SUPPORTED_RATES              14
8437 -
8438 -#define        WLAN_SUPPORTED_RATES            14
8439 +#define MAX_RATES                      14
8440  
8441  #define        MAX_LEDS                        8
8442  
8443 -#define IS_MESH_FRAME(x) (x->cb[6])
8444 -#define SET_MESH_FRAME(x) (x->cb[6]=1)
8445 -#define UNSET_MESH_FRAME(x) (x->cb[6]=0)
8446 -
8447  /** Global Variable Declaration */
8448 -typedef struct _wlan_private wlan_private;
8449 -typedef struct _wlan_adapter wlan_adapter;
8450 -extern const char libertas_driver_version[];
8451 -extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE];
8452 +extern const char lbs_driver_version[];
8453 +extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
8454  
8455 -extern u8 libertas_supported_rates[G_SUPPORTED_RATES];
8456 -
8457 -extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES];
8458 -
8459 -extern u8 libertas_adhoc_rates_b[4];
8460 +extern u8 lbs_bg_rates[MAX_RATES];
8461  
8462  /** ENUM definition*/
8463  /** SNRNF_TYPE */
8464 @@ -285,13 +297,13 @@ enum SNRNF_DATA {
8465         MAX_TYPE_AVG
8466  };
8467  
8468 -/** WLAN_802_11_POWER_MODE */
8469 -enum WLAN_802_11_POWER_MODE {
8470 -       wlan802_11powermodecam,
8471 -       wlan802_11powermodemax_psp,
8472 -       wlan802_11Powermodefast_psp,
8473 +/** LBS_802_11_POWER_MODE */
8474 +enum LBS_802_11_POWER_MODE {
8475 +       LBS802_11POWERMODECAM,
8476 +       LBS802_11POWERMODEMAX_PSP,
8477 +       LBS802_11POWERMODEFAST_PSP,
8478         /*not a real mode, defined as an upper bound */
8479 -       wlan802_11powemodemax
8480 +       LBS802_11POWEMODEMAX
8481  };
8482  
8483  /** PS_STATE */
8484 @@ -309,16 +321,16 @@ enum DNLD_STATE {
8485         DNLD_CMD_SENT
8486  };
8487  
8488 -/** WLAN_MEDIA_STATE */
8489 -enum WLAN_MEDIA_STATE {
8490 -       libertas_connected,
8491 -       libertas_disconnected
8492 +/** LBS_MEDIA_STATE */
8493 +enum LBS_MEDIA_STATE {
8494 +       LBS_CONNECTED,
8495 +       LBS_DISCONNECTED
8496  };
8497  
8498 -/** WLAN_802_11_PRIVACY_FILTER */
8499 -enum WLAN_802_11_PRIVACY_FILTER {
8500 -       wlan802_11privfilteracceptall,
8501 -       wlan802_11privfilter8021xWEP
8502 +/** LBS_802_11_PRIVACY_FILTER */
8503 +enum LBS_802_11_PRIVACY_FILTER {
8504 +       LBS802_11PRIVFILTERACCEPTALL,
8505 +       LBS802_11PRIVFILTER8021XWEP
8506  };
8507  
8508  /** mv_ms_type */
8509 @@ -331,23 +343,23 @@ enum mv_ms_type {
8510  
8511  /** SNMP_MIB_INDEX_e */
8512  enum SNMP_MIB_INDEX_e {
8513 -       desired_bsstype_i = 0,
8514 -       op_rateset_i,
8515 -       bcnperiod_i,
8516 -       dtimperiod_i,
8517 -       assocrsp_timeout_i,
8518 -       rtsthresh_i,
8519 -       short_retrylim_i,
8520 -       long_retrylim_i,
8521 -       fragthresh_i,
8522 -       dot11d_i,
8523 -       dot11h_i,
8524 -       manufid_i,
8525 -       prodID_i,
8526 -       manuf_oui_i,
8527 -       manuf_name_i,
8528 -       manuf_prodname_i,
8529 -       manuf_prodver_i,
8530 +       DESIRED_BSSTYPE_I = 0,
8531 +       OP_RATESET_I,
8532 +       BCNPERIOD_I,
8533 +       DTIMPERIOD_I,
8534 +       ASSOCRSP_TIMEOUT_I,
8535 +       RTSTHRESH_I,
8536 +       SHORT_RETRYLIM_I,
8537 +       LONG_RETRYLIM_I,
8538 +       FRAGTHRESH_I,
8539 +       DOT11D_I,
8540 +       DOT11H_I,
8541 +       MANUFID_I,
8542 +       PRODID_I,
8543 +       MANUF_OUI_I,
8544 +       MANUF_NAME_I,
8545 +       MANUF_PRODNAME_I,
8546 +       MANUF_PRODVER_I,
8547  };
8548  
8549  /** KEY_TYPE_ID */
8550 @@ -383,4 +395,4 @@ enum SNMP_MIB_VALUE_e {
8551  #define FWT_DEFAULT_SLEEPMODE 0
8552  #define FWT_DEFAULT_SNR 0
8553  
8554 -#endif                         /* _WLAN_DEFS_H_ */
8555 +#endif
8556 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/dev.h linux-2.6.22-300/drivers/net/wireless/libertas/dev.h
8557 --- linux-2.6.22-250/drivers/net/wireless/libertas/dev.h        2007-07-08 19:32:17.000000000 -0400
8558 +++ linux-2.6.22-300/drivers/net/wireless/libertas/dev.h        2008-06-05 18:10:06.000000000 -0400
8559 @@ -1,22 +1,20 @@
8560  /**
8561    * This file contains definitions and data structures specific
8562    * to Marvell 802.11 NIC. It contains the Device Information
8563 -  * structure wlan_adapter.
8564 +  * structure struct lbs_private..
8565    */
8566 -#ifndef _WLAN_DEV_H_
8567 -#define _WLAN_DEV_H_
8568 +#ifndef _LBS_DEV_H_
8569 +#define _LBS_DEV_H_
8570  
8571  #include <linux/netdevice.h>
8572  #include <linux/wireless.h>
8573  #include <linux/ethtool.h>
8574  #include <linux/debugfs.h>
8575 -#include <net/ieee80211.h>
8576  
8577  #include "defs.h"
8578  #include "scan.h"
8579 -#include "thread.h"
8580  
8581 -extern struct ethtool_ops libertas_ethtool_ops;
8582 +extern struct ethtool_ops lbs_ethtool_ops;
8583  
8584  #define        MAX_BSSID_PER_CHANNEL           16
8585  
8586 @@ -54,7 +52,7 @@ struct region_channel {
8587         struct chan_freq_power *CFP;
8588  };
8589  
8590 -struct wlan_802_11_security {
8591 +struct lbs_802_11_security {
8592         u8 WPAenabled;
8593         u8 WPA2enabled;
8594         u8 wep_enabled;
8595 @@ -73,10 +71,8 @@ struct current_bss_params {
8596         u8 band;
8597         /** channel */
8598         u8 channel;
8599 -       /** number of rates supported */
8600 -       int numofrates;
8601 -       /** supported rates*/
8602 -       u8 datarates[WLAN_SUPPORTED_RATES];
8603 +       /** zero-terminated array of supported data rates */
8604 +       u8 rates[MAX_RATES + 1];
8605  };
8606  
8607  /** sleep_params */
8608 @@ -90,7 +86,7 @@ struct sleep_params {
8609  };
8610  
8611  /* Mesh statistics */
8612 -struct wlan_mesh_stats {
8613 +struct lbs_mesh_stats {
8614         u32     fwd_bcast_cnt;          /* Fwd: Broadcast counter */
8615         u32     fwd_unicast_cnt;        /* Fwd: Unicast counter */
8616         u32     fwd_drop_ttl;           /* Fwd: TTL zero */
8617 @@ -102,22 +98,23 @@ struct wlan_mesh_stats {
8618  };
8619  
8620  /** Private structure for the MV device */
8621 -struct _wlan_private {
8622 -       int open;
8623 +struct lbs_private {
8624         int mesh_open;
8625         int infra_open;
8626 +       int mesh_autostart_enabled;
8627 +       __le16 boot2_version;
8628  
8629         char name[DEV_NAME_LEN];
8630  
8631         void *card;
8632 -       wlan_adapter *adapter;
8633         struct net_device *dev;
8634  
8635         struct net_device_stats stats;
8636 -       struct net_device *mesh_dev ; /* Virtual device */
8637 +       struct net_device *mesh_dev; /* Virtual device */
8638 +       struct net_device *rtap_net_dev;
8639  
8640         struct iw_statistics wstats;
8641 -       struct wlan_mesh_stats mstats;
8642 +       struct lbs_mesh_stats mstats;
8643         struct dentry *debugfs_dir;
8644         struct dentry *debugfs_debug;
8645         struct dentry *debugfs_files[6];
8646 @@ -135,78 +132,37 @@ struct _wlan_private {
8647         /** Upload length */
8648         u32 upld_len;
8649         /* Upload buffer */
8650 -       u8 upld_buf[WLAN_UPLD_SIZE];
8651 +       u8 upld_buf[LBS_UPLD_SIZE];
8652         /* Download sent:
8653            bit0 1/0=data_sent/data_tx_done,
8654            bit1 1/0=cmd_sent/cmd_tx_done,
8655            all other bits reserved 0 */
8656         u8 dnld_sent;
8657  
8658 -       const struct firmware *firmware;
8659 -       struct device *hotplug_device;
8660 -
8661         /** thread to service interrupts */
8662 -       struct wlan_thread mainthread;
8663 +       struct task_struct *main_thread;
8664 +       wait_queue_head_t waitq;
8665 +       struct workqueue_struct *work_thread;
8666 +
8667 +       struct work_struct mcast_work;
8668  
8669 +       struct delayed_work scan_work;
8670         struct delayed_work assoc_work;
8671 -       struct workqueue_struct *assoc_thread;
8672         struct work_struct sync_channel;
8673  
8674         /** Hardware access */
8675 -       int (*hw_register_dev) (wlan_private * priv);
8676 -       int (*hw_unregister_dev) (wlan_private *);
8677 -       int (*hw_prog_firmware) (wlan_private *);
8678 -       int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
8679 -       int (*hw_get_int_status) (wlan_private * priv, u8 *);
8680 -       int (*hw_read_event_cause) (wlan_private *);
8681 -};
8682 -
8683 -/** Association request
8684 - *
8685 - * Encapsulates all the options that describe a specific assocation request
8686 - * or configuration of the wireless card's radio, mode, and security settings.
8687 - */
8688 -struct assoc_request {
8689 -#define ASSOC_FLAG_SSID                        1
8690 -#define ASSOC_FLAG_CHANNEL             2
8691 -#define ASSOC_FLAG_BAND                        3
8692 -#define ASSOC_FLAG_MODE                        4
8693 -#define ASSOC_FLAG_BSSID               5
8694 -#define ASSOC_FLAG_WEP_KEYS            6
8695 -#define ASSOC_FLAG_WEP_TX_KEYIDX       7
8696 -#define ASSOC_FLAG_WPA_MCAST_KEY       8
8697 -#define ASSOC_FLAG_WPA_UCAST_KEY       9
8698 -#define ASSOC_FLAG_SECINFO             10
8699 -#define ASSOC_FLAG_WPA_IE              11
8700 -       unsigned long flags;
8701 -
8702 -       u8 ssid[IW_ESSID_MAX_SIZE + 1];
8703 -       u8 ssid_len;
8704 -       u8 channel;
8705 -       u8 band;
8706 -       u8 mode;
8707 -       u8 bssid[ETH_ALEN];
8708 +       int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
8709 +       int (*hw_get_int_status) (struct lbs_private *priv, u8 *);
8710 +       int (*hw_read_event_cause) (struct lbs_private *);
8711 +
8712 +       /* Wake On LAN */
8713 +       uint32_t wol_criteria;
8714 +       uint8_t wol_gpio;
8715 +       uint8_t wol_gap;
8716  
8717 -       /** WEP keys */
8718 -       struct WLAN_802_11_KEY wep_keys[4];
8719 -       u16 wep_tx_keyidx;
8720 -
8721 -       /** WPA keys */
8722 -       struct WLAN_802_11_KEY wpa_mcast_key;
8723 -       struct WLAN_802_11_KEY wpa_unicast_key;
8724 -
8725 -       struct wlan_802_11_security secinfo;
8726 +       /* was struct lbs_adapter from here... */
8727  
8728 -       /** WPA Information Elements*/
8729 -       u8 wpa_ie[MAX_WPA_IE_LEN];
8730 -       u8 wpa_ie_len;
8731 -
8732 -       /* BSS to associate with for infrastructure of Ad-Hoc join */
8733 -       struct bss_descriptor bss;
8734 -};
8735 -
8736 -/** Wlan adapter data structure*/
8737 -struct _wlan_adapter {
8738 +       /** Wlan adapter data structure*/
8739         /** STATUS variables */
8740         u8 fwreleasenumber[4];
8741         u32 fwcapinfo;
8742 @@ -214,7 +170,10 @@ struct _wlan_adapter {
8743  
8744         struct mutex lock;
8745  
8746 -       u8 tmptxbuf[WLAN_UPLD_SIZE];
8747 +       /* TX packet ready to be sent... */
8748 +       int tx_pending_len;             /* -1 while building packet */
8749 +
8750 +       u8 tx_pending_buf[LBS_UPLD_SIZE];
8751         /* protected by hard_start_xmit serialization */
8752  
8753         /** command-related variables */
8754 @@ -232,8 +191,7 @@ struct _wlan_adapter {
8755         struct list_head cmdpendingq;
8756  
8757         wait_queue_head_t cmd_pending;
8758 -       u8 nr_cmd_pending;
8759 -       /* command related variables protected by adapter->driver_lock */
8760 +       /* command related variables protected by priv->driver_lock */
8761  
8762         /** Async and Sync Event variables */
8763         u32 intcounter;
8764 @@ -245,37 +203,32 @@ struct _wlan_adapter {
8765  
8766         /** Timers */
8767         struct timer_list command_timer;
8768 -
8769 -       /* TX queue used in PS mode */
8770 -       spinlock_t txqueue_lock;
8771 -       struct sk_buff *tx_queue_ps[NR_TX_QUEUE];
8772 -       unsigned int tx_queue_idx;
8773 +       int nr_retries;
8774 +       int cmd_timed_out;
8775  
8776         u8 hisregcpy;
8777  
8778         /** current ssid/bssid related parameters*/
8779         struct current_bss_params curbssparams;
8780  
8781 +       uint16_t mesh_tlv;
8782 +       u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
8783 +       u8 mesh_ssid_len;
8784 +
8785         /* IW_MODE_* */
8786         u8 mode;
8787  
8788 -       u8 prev_ssid[IW_ESSID_MAX_SIZE + 1];
8789 -       u8 prev_ssid_len;
8790 -       u8 prev_bssid[ETH_ALEN];
8791 -
8792         /* Scan results list */
8793         struct list_head network_list;
8794         struct list_head network_free_list;
8795         struct bss_descriptor *networks;
8796  
8797 -       u8 scantype;
8798 -       u32 scanmode;
8799 -
8800 -       u16 beaconperiod;
8801 +       u16 beacon_period;
8802 +       u8 beacon_enable;
8803         u8 adhoccreate;
8804  
8805         /** capability Info used in Association, start, join */
8806 -       struct ieeetypes_capinfo capinfo;
8807 +       u16 capability;
8808  
8809         /** MAC address information */
8810         u8 current_addr[ETH_ALEN];
8811 @@ -287,71 +240,53 @@ struct _wlan_adapter {
8812  
8813         u16 enablehwauto;
8814         u16 ratebitmap;
8815 -       /** control G rates */
8816 -       u8 adhoc_grate_enabled;
8817 -
8818 -       u32 txantenna;
8819 -       u32 rxantenna;
8820  
8821         u32 fragthsd;
8822         u32 rtsthsd;
8823  
8824 -       u32 datarate;
8825 -       u8 is_datarate_auto;
8826 -
8827 -       u16 listeninterval;
8828 -       u16 prescan;
8829         u8 txretrycount;
8830  
8831         /** Tx-related variables (for single packet tx) */
8832         struct sk_buff *currenttxskb;
8833 -       u16 TxLockFlag;
8834  
8835         /** NIC Operation characteristics */
8836 -       u16 currentpacketfilter;
8837 +       u16 mac_control;
8838         u32 connect_status;
8839 +       u32 mesh_connect_status;
8840         u16 regioncode;
8841 -       u16 regiontableindex;
8842         u16 txpowerlevel;
8843  
8844         /** POWER MANAGEMENT AND PnP SUPPORT */
8845         u8 surpriseremoved;
8846 -       u16 atimwindow;
8847  
8848         u16 psmode;             /* Wlan802_11PowermodeCAM=disable
8849                                    Wlan802_11PowermodeMAX_PSP=enable */
8850 -       u16 multipledtim;
8851         u32 psstate;
8852 +       char ps_supported;
8853         u8 needtowakeup;
8854  
8855 -       struct PS_CMD_ConfirmSleep libertas_ps_confirm_sleep;
8856 -       u16 locallisteninterval;
8857 -       u16 nullpktinterval;
8858 +       struct PS_CMD_ConfirmSleep lbs_ps_confirm_sleep;
8859 +       struct cmd_header lbs_ps_confirm_wake;
8860  
8861         struct assoc_request * pending_assoc_req;
8862         struct assoc_request * in_progress_assoc_req;
8863  
8864         /** Encryption parameter */
8865 -       struct wlan_802_11_security secinfo;
8866 +       struct lbs_802_11_security secinfo;
8867  
8868         /** WEP keys */
8869 -       struct WLAN_802_11_KEY wep_keys[4];
8870 +       struct enc_key wep_keys[4];
8871         u16 wep_tx_keyidx;
8872  
8873         /** WPA keys */
8874 -       struct WLAN_802_11_KEY wpa_mcast_key;
8875 -       struct WLAN_802_11_KEY wpa_unicast_key;
8876 +       struct enc_key wpa_mcast_key;
8877 +       struct enc_key wpa_unicast_key;
8878  
8879         /** WPA Information Elements*/
8880         u8 wpa_ie[MAX_WPA_IE_LEN];
8881         u8 wpa_ie_len;
8882  
8883 -       u16 rxantennamode;
8884 -       u16 txantennamode;
8885 -
8886         /** Requested Signal Strength*/
8887 -       u16 bcn_avg_factor;
8888 -       u16 data_avg_factor;
8889         u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
8890         u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
8891         u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
8892 @@ -359,15 +294,13 @@ struct _wlan_adapter {
8893         u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
8894         u16 nextSNRNF;
8895         u16 numSNRNF;
8896 -       u16 rxpd_rate;
8897  
8898         u8 radioon;
8899         u32 preamble;
8900  
8901 -       /** Multi bands Parameter*/
8902 -       u8 libertas_supported_rates[G_SUPPORTED_RATES];
8903 -
8904 -       /** Blue Tooth Co-existence Arbitration */
8905 +       /** data rate stuff */
8906 +       u8 cur_rate;
8907 +       u8 auto_rate;
8908  
8909         /** sleep_params */
8910         struct sleep_params sp;
8911 @@ -381,7 +314,7 @@ struct _wlan_adapter {
8912         struct region_channel universal_channel[MAX_REGION_CHANNEL_NUM];
8913  
8914         /** 11D and Domain Regulatory Data */
8915 -       struct wlan_802_11d_domain_reg domainreg;
8916 +       struct lbs_802_11d_domain_reg domainreg;
8917         struct parsed_region_chan_11d parsed_region_chan;
8918  
8919         /** FSM variable for 11d support */
8920 @@ -389,20 +322,57 @@ struct _wlan_adapter {
8921  
8922         /**     MISCELLANEOUS */
8923         u8 *prdeeprom;
8924 -       struct wlan_offset_value offsetvalue;
8925 +       struct lbs_offset_value offsetvalue;
8926  
8927         struct cmd_ds_802_11_get_log logmsg;
8928 -       u16 scanprobes;
8929 -
8930 -       u32 pkttxctrl;
8931  
8932 -       u16 txrate;
8933 -       u32 linkmode;
8934 -       u32 radiomode;
8935 -       u32 debugmode;
8936 +       u32 monitormode;
8937 +       int last_scanned_channel;
8938         u8 fw_ready;
8939 +};
8940  
8941 -       u8 last_scanned_channel;
8942 +/** Association request
8943 + *
8944 + * Encapsulates all the options that describe a specific assocation request
8945 + * or configuration of the wireless card's radio, mode, and security settings.
8946 + */
8947 +struct assoc_request {
8948 +#define ASSOC_FLAG_SSID                        1
8949 +#define ASSOC_FLAG_CHANNEL             2
8950 +#define ASSOC_FLAG_BAND                        3
8951 +#define ASSOC_FLAG_MODE                        4
8952 +#define ASSOC_FLAG_BSSID               5
8953 +#define ASSOC_FLAG_WEP_KEYS            6
8954 +#define ASSOC_FLAG_WEP_TX_KEYIDX       7
8955 +#define ASSOC_FLAG_WPA_MCAST_KEY       8
8956 +#define ASSOC_FLAG_WPA_UCAST_KEY       9
8957 +#define ASSOC_FLAG_SECINFO             10
8958 +#define ASSOC_FLAG_WPA_IE              11
8959 +       unsigned long flags;
8960 +
8961 +       u8 ssid[IW_ESSID_MAX_SIZE + 1];
8962 +       u8 ssid_len;
8963 +       u8 channel;
8964 +       u8 band;
8965 +       u8 mode;
8966 +       u8 bssid[ETH_ALEN];
8967 +
8968 +       /** WEP keys */
8969 +       struct enc_key wep_keys[4];
8970 +       u16 wep_tx_keyidx;
8971 +
8972 +       /** WPA keys */
8973 +       struct enc_key wpa_mcast_key;
8974 +       struct enc_key wpa_unicast_key;
8975 +
8976 +       struct lbs_802_11_security secinfo;
8977 +
8978 +       /** WPA Information Elements*/
8979 +       u8 wpa_ie[MAX_WPA_IE_LEN];
8980 +       u8 wpa_ie_len;
8981 +
8982 +       /* BSS to associate with for infrastructure of Ad-Hoc join */
8983 +       struct bss_descriptor bss;
8984  };
8985  
8986 -#endif                         /* _WLAN_DEV_H_ */
8987 +#endif
8988 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/ethtool.c linux-2.6.22-300/drivers/net/wireless/libertas/ethtool.c
8989 --- linux-2.6.22-250/drivers/net/wireless/libertas/ethtool.c    2007-07-08 19:32:17.000000000 -0400
8990 +++ linux-2.6.22-300/drivers/net/wireless/libertas/ethtool.c    2008-06-05 18:10:06.000000000 -0400
8991 @@ -8,6 +8,8 @@
8992  #include "dev.h"
8993  #include "join.h"
8994  #include "wext.h"
8995 +#include "cmd.h"
8996 +
8997  static const char * mesh_stat_strings[]= {
8998                         "drop_duplicate_bcast",
8999                         "drop_ttl_zero",
9000 @@ -19,35 +21,34 @@ static const char * mesh_stat_strings[]=
9001                         "tx_failed_cnt"
9002  };
9003  
9004 -static void libertas_ethtool_get_drvinfo(struct net_device *dev,
9005 +static void lbs_ethtool_get_drvinfo(struct net_device *dev,
9006                                          struct ethtool_drvinfo *info)
9007  {
9008 -       wlan_private *priv = (wlan_private *) dev->priv;
9009 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
9010         char fwver[32];
9011  
9012 -       libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1);
9013 +       lbs_get_fwversion(priv, fwver, sizeof(fwver) - 1);
9014  
9015         strcpy(info->driver, "libertas");
9016 -       strcpy(info->version, libertas_driver_version);
9017 +       strcpy(info->version, lbs_driver_version);
9018         strcpy(info->fw_version, fwver);
9019  }
9020  
9021  /* All 8388 parts have 16KiB EEPROM size at the time of writing.
9022   * In case that changes this needs fixing.
9023   */
9024 -#define LIBERTAS_EEPROM_LEN 16384
9025 +#define LBS_EEPROM_LEN 16384
9026  
9027 -static int libertas_ethtool_get_eeprom_len(struct net_device *dev)
9028 +static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
9029  {
9030 -       return LIBERTAS_EEPROM_LEN;
9031 +       return LBS_EEPROM_LEN;
9032  }
9033  
9034 -static int libertas_ethtool_get_eeprom(struct net_device *dev,
9035 +static int lbs_ethtool_get_eeprom(struct net_device *dev,
9036                                    struct ethtool_eeprom *eeprom, u8 * bytes)
9037  {
9038 -       wlan_private *priv = (wlan_private *) dev->priv;
9039 -       wlan_adapter *adapter = priv->adapter;
9040 -       struct wlan_ioctl_regrdwr regctrl;
9041 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
9042 +       struct lbs_ioctl_regrdwr regctrl;
9043         char *ptr;
9044         int ret;
9045  
9046 @@ -55,48 +56,47 @@ static int libertas_ethtool_get_eeprom(s
9047         regctrl.offset = eeprom->offset;
9048         regctrl.NOB = eeprom->len;
9049  
9050 -       if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN)
9051 +       if (eeprom->offset + eeprom->len > LBS_EEPROM_LEN)
9052                 return -EINVAL;
9053  
9054  //      mutex_lock(&priv->mutex);
9055  
9056 -       adapter->prdeeprom =
9057 -                   (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
9058 -       if (!adapter->prdeeprom)
9059 +       priv->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
9060 +       if (!priv->prdeeprom)
9061                 return -ENOMEM;
9062 -       memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
9063 +       memcpy(priv->prdeeprom, &regctrl, sizeof(regctrl));
9064  
9065         /* +14 is for action, offset, and NOB in
9066          * response */
9067         lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n",
9068                regctrl.action, regctrl.offset, regctrl.NOB);
9069  
9070 -       ret = libertas_prepare_and_send_command(priv,
9071 -                                   cmd_802_11_eeprom_access,
9072 +       ret = lbs_prepare_and_send_command(priv,
9073 +                                   CMD_802_11_EEPROM_ACCESS,
9074                                     regctrl.action,
9075 -                                   cmd_option_waitforrsp, 0,
9076 +                                   CMD_OPTION_WAITFORRSP, 0,
9077                                     &regctrl);
9078  
9079         if (ret) {
9080 -               if (adapter->prdeeprom)
9081 -                       kfree(adapter->prdeeprom);
9082 +               if (priv->prdeeprom)
9083 +                       kfree(priv->prdeeprom);
9084                 goto done;
9085         }
9086  
9087         mdelay(10);
9088  
9089 -       ptr = (char *)adapter->prdeeprom;
9090 +       ptr = (char *)priv->prdeeprom;
9091  
9092         /* skip the command header, but include the "value" u32 variable */
9093 -       ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4;
9094 +       ptr = ptr + sizeof(struct lbs_ioctl_regrdwr) - 4;
9095  
9096         /*
9097          * Return the result back to the user
9098          */
9099         memcpy(bytes, ptr, eeprom->len);
9100  
9101 -       if (adapter->prdeeprom)
9102 -               kfree(adapter->prdeeprom);
9103 +       if (priv->prdeeprom)
9104 +               kfree(priv->prdeeprom);
9105  //     mutex_unlock(&priv->mutex);
9106  
9107         ret = 0;
9108 @@ -106,65 +106,56 @@ done:
9109          return ret;
9110  }
9111  
9112 -static void libertas_ethtool_get_stats(struct net_device * dev,
9113 -                               struct ethtool_stats * stats, u64 * data)
9114 +static void lbs_ethtool_get_stats(struct net_device *dev,
9115 +                                 struct ethtool_stats *stats, uint64_t *data)
9116  {
9117 -       wlan_private *priv = dev->priv;
9118 -
9119 -       lbs_deb_enter(LBS_DEB_ETHTOOL);
9120 -
9121 -       stats->cmd = ETHTOOL_GSTATS;
9122 -       BUG_ON(stats->n_stats != MESH_STATS_NUM);
9123 -
9124 -        data[0] = priv->mstats.fwd_drop_rbt;
9125 -        data[1] = priv->mstats.fwd_drop_ttl;
9126 -        data[2] = priv->mstats.fwd_drop_noroute;
9127 -        data[3] = priv->mstats.fwd_drop_nobuf;
9128 -        data[4] = priv->mstats.fwd_unicast_cnt;
9129 -        data[5] = priv->mstats.fwd_bcast_cnt;
9130 -        data[6] = priv->mstats.drop_blind;
9131 -        data[7] = priv->mstats.tx_failed_cnt;
9132 -
9133 -       lbs_deb_enter(LBS_DEB_ETHTOOL);
9134 -}
9135 -
9136 -static int libertas_ethtool_get_stats_count(struct net_device * dev)
9137 -{
9138 -       int ret;
9139 -       wlan_private *priv = dev->priv;
9140 +       struct lbs_private *priv = dev->priv;
9141         struct cmd_ds_mesh_access mesh_access;
9142 +       int ret;
9143  
9144         lbs_deb_enter(LBS_DEB_ETHTOOL);
9145  
9146         /* Get Mesh Statistics */
9147 -       ret = libertas_prepare_and_send_command(priv,
9148 -                       cmd_mesh_access, cmd_act_mesh_get_stats,
9149 -                       cmd_option_waitforrsp, 0, &mesh_access);
9150 +       ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
9151  
9152         if (ret) {
9153 -               ret = 0;
9154 -               goto done;
9155 +               memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
9156 +               return;
9157         }
9158  
9159 -        priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
9160 -        priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
9161 -        priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
9162 -        priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
9163 -        priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
9164 -        priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
9165 -        priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
9166 -        priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
9167 +       priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
9168 +       priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
9169 +       priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
9170 +       priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
9171 +       priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
9172 +       priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
9173 +       priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
9174 +       priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
9175 +
9176 +       data[0] = priv->mstats.fwd_drop_rbt;
9177 +       data[1] = priv->mstats.fwd_drop_ttl;
9178 +       data[2] = priv->mstats.fwd_drop_noroute;
9179 +       data[3] = priv->mstats.fwd_drop_nobuf;
9180 +       data[4] = priv->mstats.fwd_unicast_cnt;
9181 +       data[5] = priv->mstats.fwd_bcast_cnt;
9182 +       data[6] = priv->mstats.drop_blind;
9183 +       data[7] = priv->mstats.tx_failed_cnt;
9184  
9185 -       ret = MESH_STATS_NUM;
9186 +       lbs_deb_enter(LBS_DEB_ETHTOOL);
9187 +}
9188  
9189 -done:
9190 -       lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret);
9191 -       return ret;
9192 +static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
9193 +{
9194 +       struct lbs_private *priv = dev->priv;
9195 +
9196 +       if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
9197 +               return MESH_STATS_NUM;
9198 +
9199 +       return -EOPNOTSUPP;
9200  }
9201  
9202 -static void libertas_ethtool_get_strings (struct net_device * dev,
9203 -                                         u32 stringset,
9204 -                                         u8 * s)
9205 +static void lbs_ethtool_get_strings(struct net_device *dev,
9206 +                                   uint32_t stringset, uint8_t *s)
9207  {
9208         int i;
9209  
9210 @@ -182,12 +173,57 @@ static void libertas_ethtool_get_strings
9211         lbs_deb_enter(LBS_DEB_ETHTOOL);
9212  }
9213  
9214 -struct ethtool_ops libertas_ethtool_ops = {
9215 -       .get_drvinfo = libertas_ethtool_get_drvinfo,
9216 -       .get_eeprom =  libertas_ethtool_get_eeprom,
9217 -       .get_eeprom_len = libertas_ethtool_get_eeprom_len,
9218 -       .get_stats_count = libertas_ethtool_get_stats_count,
9219 -       .get_ethtool_stats = libertas_ethtool_get_stats,
9220 -       .get_strings = libertas_ethtool_get_strings,
9221 +static void lbs_ethtool_get_wol(struct net_device *dev,
9222 +                               struct ethtool_wolinfo *wol)
9223 +{
9224 +       struct lbs_private *priv = dev->priv;
9225 +
9226 +       if (priv->wol_criteria == 0xffffffff) {
9227 +               /* Interface driver didn't configure wake */
9228 +               wol->supported = wol->wolopts = 0;
9229 +               return;
9230 +       }
9231 +
9232 +       wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
9233 +
9234 +       if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
9235 +               wol->wolopts |= WAKE_UCAST;
9236 +       if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
9237 +               wol->wolopts |= WAKE_MCAST;
9238 +       if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA)
9239 +               wol->wolopts |= WAKE_BCAST;
9240 +       if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT)
9241 +               wol->wolopts |= WAKE_PHY;
9242 +}
9243 +
9244 +static int lbs_ethtool_set_wol(struct net_device *dev,
9245 +                              struct ethtool_wolinfo *wol)
9246 +{
9247 +       struct lbs_private *priv = dev->priv;
9248 +       uint32_t criteria = 0;
9249 +
9250 +       if (priv->wol_criteria == 0xffffffff && wol->wolopts)
9251 +               return -EOPNOTSUPP;
9252 +
9253 +       if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
9254 +               return -EOPNOTSUPP;
9255 +
9256 +       if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
9257 +       if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
9258 +       if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
9259 +       if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;
9260 +
9261 +       return lbs_host_sleep_cfg(priv, criteria);
9262 +}
9263 +
9264 +struct ethtool_ops lbs_ethtool_ops = {
9265 +       .get_drvinfo = lbs_ethtool_get_drvinfo,
9266 +       .get_eeprom =  lbs_ethtool_get_eeprom,
9267 +       .get_eeprom_len = lbs_ethtool_get_eeprom_len,
9268 +       .get_sset_count = lbs_ethtool_get_sset_count,
9269 +       .get_ethtool_stats = lbs_ethtool_get_stats,
9270 +       .get_strings = lbs_ethtool_get_strings,
9271 +       .get_wol = lbs_ethtool_get_wol,
9272 +       .set_wol = lbs_ethtool_set_wol,
9273  };
9274  
9275 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/fw.c linux-2.6.22-300/drivers/net/wireless/libertas/fw.c
9276 --- linux-2.6.22-250/drivers/net/wireless/libertas/fw.c 2007-07-08 19:32:17.000000000 -0400
9277 +++ linux-2.6.22-300/drivers/net/wireless/libertas/fw.c 1969-12-31 19:00:00.000000000 -0500
9278 @@ -1,349 +0,0 @@
9279 -/**
9280 -  * This file contains the initialization for FW and HW
9281 -  */
9282 -#include <linux/firmware.h>
9283 -
9284 -#include "host.h"
9285 -#include "defs.h"
9286 -#include "decl.h"
9287 -#include "dev.h"
9288 -#include "wext.h"
9289 -#include "if_usb.h"
9290 -
9291 -/**
9292 - *  @brief This function checks the validity of Boot2/FW image.
9293 - *
9294 - *  @param data              pointer to image
9295 - *         len               image length
9296 - *  @return     0 or -1
9297 - */
9298 -static int check_fwfile_format(u8 *data, u32 totlen)
9299 -{
9300 -       u32 bincmd, exit;
9301 -       u32 blksize, offset, len;
9302 -       int ret;
9303 -
9304 -       ret = 1;
9305 -       exit = len = 0;
9306 -
9307 -       do {
9308 -               struct fwheader *fwh = (void *)data;
9309 -
9310 -               bincmd = le32_to_cpu(fwh->dnldcmd);
9311 -               blksize = le32_to_cpu(fwh->datalength);
9312 -               switch (bincmd) {
9313 -               case FW_HAS_DATA_TO_RECV:
9314 -                       offset = sizeof(struct fwheader) + blksize;
9315 -                       data += offset;
9316 -                       len += offset;
9317 -                       if (len >= totlen)
9318 -                               exit = 1;
9319 -                       break;
9320 -               case FW_HAS_LAST_BLOCK:
9321 -                       exit = 1;
9322 -                       ret = 0;
9323 -                       break;
9324 -               default:
9325 -                       exit = 1;
9326 -                       break;
9327 -               }
9328 -       } while (!exit);
9329 -
9330 -       if (ret)
9331 -               lbs_pr_err("firmware file format check FAIL\n");
9332 -       else
9333 -               lbs_deb_fw("firmware file format check PASS\n");
9334 -
9335 -       return ret;
9336 -}
9337 -
9338 -/**
9339 - *  @brief This function downloads firmware image, gets
9340 - *  HW spec from firmware and set basic parameters to
9341 - *  firmware.
9342 - *
9343 - *  @param priv    A pointer to wlan_private structure
9344 - *  @return       0 or -1
9345 - */
9346 -static int wlan_setup_station_hw(wlan_private * priv, char *fw_name)
9347 -{
9348 -       int ret = -1;
9349 -       wlan_adapter *adapter = priv->adapter;
9350 -
9351 -       lbs_deb_enter(LBS_DEB_FW);
9352 -
9353 -       if ((ret = request_firmware(&priv->firmware, fw_name,
9354 -                                   priv->hotplug_device)) < 0) {
9355 -               lbs_pr_err("request_firmware() failed with %#x\n", ret);
9356 -               lbs_pr_err("firmware %s not found\n", fw_name);
9357 -               goto done;
9358 -       }
9359 -
9360 -       if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
9361 -               release_firmware(priv->firmware);
9362 -               goto done;
9363 -       }
9364 -
9365 -       ret = priv->hw_prog_firmware(priv);
9366 -
9367 -       release_firmware(priv->firmware);
9368 -
9369 -       if (ret) {
9370 -               lbs_deb_fw("bootloader in invalid state\n");
9371 -               ret = -1;
9372 -               goto done;
9373 -       }
9374 -
9375 -       /*
9376 -        * Read MAC address from HW
9377 -        */
9378 -       memset(adapter->current_addr, 0xff, ETH_ALEN);
9379 -
9380 -       ret = libertas_prepare_and_send_command(priv, cmd_get_hw_spec,
9381 -                                   0, cmd_option_waitforrsp, 0, NULL);
9382 -
9383 -       if (ret) {
9384 -               ret = -1;
9385 -               goto done;
9386 -       }
9387 -
9388 -       libertas_set_mac_packet_filter(priv);
9389 -
9390 -       /* Get the supported Data rates */
9391 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
9392 -                                   cmd_act_get_tx_rate,
9393 -                                   cmd_option_waitforrsp, 0, NULL);
9394 -
9395 -       if (ret) {
9396 -               ret = -1;
9397 -               goto done;
9398 -       }
9399 -
9400 -       ret = 0;
9401 -done:
9402 -       lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
9403 -       return ret;
9404 -}
9405 -
9406 -static int wlan_allocate_adapter(wlan_private * priv)
9407 -{
9408 -       size_t bufsize;
9409 -       wlan_adapter *adapter = priv->adapter;
9410 -
9411 -       /* Allocate buffer to store the BSSID list */
9412 -       bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
9413 -       adapter->networks = kzalloc(bufsize, GFP_KERNEL);
9414 -       if (!adapter->networks) {
9415 -               lbs_pr_err("Out of memory allocating beacons\n");
9416 -               libertas_free_adapter(priv);
9417 -               return -ENOMEM;
9418 -       }
9419 -
9420 -       /* Allocate the command buffers */
9421 -       libertas_allocate_cmd_buffer(priv);
9422 -
9423 -       memset(&adapter->libertas_ps_confirm_sleep, 0, sizeof(struct PS_CMD_ConfirmSleep));
9424 -       adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);
9425 -       adapter->libertas_ps_confirm_sleep.command =
9426 -           cpu_to_le16(cmd_802_11_ps_mode);
9427 -       adapter->libertas_ps_confirm_sleep.size =
9428 -           cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
9429 -       adapter->libertas_ps_confirm_sleep.result = 0;
9430 -       adapter->libertas_ps_confirm_sleep.action =
9431 -           cpu_to_le16(cmd_subcmd_sleep_confirmed);
9432 -
9433 -       return 0;
9434 -}
9435 -
9436 -static void wlan_init_adapter(wlan_private * priv)
9437 -{
9438 -       wlan_adapter *adapter = priv->adapter;
9439 -       int i;
9440 -
9441 -       adapter->scanprobes = 0;
9442 -
9443 -       adapter->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
9444 -       adapter->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
9445 -
9446 -       /* ATIM params */
9447 -       adapter->atimwindow = 0;
9448 -
9449 -       adapter->connect_status = libertas_disconnected;
9450 -       memset(adapter->current_addr, 0xff, ETH_ALEN);
9451 -
9452 -       /* scan type */
9453 -       adapter->scantype = cmd_scan_type_active;
9454 -
9455 -       /* scan mode */
9456 -       adapter->scanmode = cmd_bss_type_any;
9457 -
9458 -       /* 802.11 specific */
9459 -       adapter->secinfo.wep_enabled = 0;
9460 -       for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
9461 -            i++)
9462 -               memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
9463 -       adapter->wep_tx_keyidx = 0;
9464 -       adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
9465 -       adapter->mode = IW_MODE_INFRA;
9466 -
9467 -       adapter->pending_assoc_req = NULL;
9468 -       adapter->in_progress_assoc_req = NULL;
9469 -
9470 -       /* Initialize scan result lists */
9471 -       INIT_LIST_HEAD(&adapter->network_free_list);
9472 -       INIT_LIST_HEAD(&adapter->network_list);
9473 -       for (i = 0; i < MAX_NETWORK_COUNT; i++) {
9474 -               list_add_tail(&adapter->networks[i].list,
9475 -                             &adapter->network_free_list);
9476 -       }
9477 -
9478 -       mutex_init(&adapter->lock);
9479 -
9480 -       adapter->prescan = 1;
9481 -
9482 -       memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
9483 -       adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
9484 -
9485 -       /* PnP and power profile */
9486 -       adapter->surpriseremoved = 0;
9487 -
9488 -       adapter->currentpacketfilter =
9489 -           cmd_act_mac_rx_on | cmd_act_mac_tx_on;
9490 -
9491 -       adapter->radioon = RADIO_ON;
9492 -       adapter->txantenna = RF_ANTENNA_2;
9493 -       adapter->rxantenna = RF_ANTENNA_AUTO;
9494 -
9495 -       adapter->is_datarate_auto = 1;
9496 -       adapter->beaconperiod = MRVDRV_BEACON_INTERVAL;
9497 -
9498 -       // set default value of capinfo.
9499 -#define SHORT_PREAMBLE_ALLOWED         1
9500 -       memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
9501 -       adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
9502 -
9503 -       adapter->psmode = wlan802_11powermodecam;
9504 -       adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
9505 -
9506 -       adapter->listeninterval = MRVDRV_DEFAULT_LISTEN_INTERVAL;
9507 -
9508 -       adapter->psstate = PS_STATE_FULL_POWER;
9509 -       adapter->needtowakeup = 0;
9510 -       adapter->locallisteninterval = 0;       /* default value in firmware will be used */
9511 -
9512 -       adapter->datarate = 0;  // Initially indicate the rate as auto
9513 -
9514 -       adapter->adhoc_grate_enabled = 0;
9515 -
9516 -       adapter->intcounter = 0;
9517 -
9518 -       adapter->currenttxskb = NULL;
9519 -       adapter->pkttxctrl = 0;
9520 -
9521 -       memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
9522 -       adapter->tx_queue_idx = 0;
9523 -       spin_lock_init(&adapter->txqueue_lock);
9524 -
9525 -       return;
9526 -}
9527 -
9528 -static void command_timer_fn(unsigned long data);
9529 -
9530 -int libertas_init_fw(wlan_private * priv, char *fw_name)
9531 -{
9532 -       int ret = -1;
9533 -       wlan_adapter *adapter = priv->adapter;
9534 -
9535 -       lbs_deb_enter(LBS_DEB_FW);
9536 -
9537 -       /* Allocate adapter structure */
9538 -       if ((ret = wlan_allocate_adapter(priv)) != 0)
9539 -               goto done;
9540 -
9541 -       /* init adapter structure */
9542 -       wlan_init_adapter(priv);
9543 -
9544 -       /* init timer etc. */
9545 -       setup_timer(&adapter->command_timer, command_timer_fn,
9546 -                       (unsigned long)priv);
9547 -
9548 -       /* download fimrware etc. */
9549 -       if ((ret = wlan_setup_station_hw(priv, fw_name)) != 0) {
9550 -               del_timer_sync(&adapter->command_timer);
9551 -               goto done;
9552 -       }
9553 -
9554 -       /* init 802.11d */
9555 -       libertas_init_11d(priv);
9556 -
9557 -       ret = 0;
9558 -done:
9559 -       lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
9560 -       return ret;
9561 -}
9562 -
9563 -void libertas_free_adapter(wlan_private * priv)
9564 -{
9565 -       wlan_adapter *adapter = priv->adapter;
9566 -
9567 -       if (!adapter) {
9568 -               lbs_deb_fw("why double free adapter?\n");
9569 -               return;
9570 -       }
9571 -
9572 -       lbs_deb_fw("free command buffer\n");
9573 -       libertas_free_cmd_buffer(priv);
9574 -
9575 -       lbs_deb_fw("free command_timer\n");
9576 -       del_timer(&adapter->command_timer);
9577 -
9578 -       lbs_deb_fw("free scan results table\n");
9579 -       kfree(adapter->networks);
9580 -       adapter->networks = NULL;
9581 -
9582 -       /* Free the adapter object itself */
9583 -       lbs_deb_fw("free adapter\n");
9584 -       kfree(adapter);
9585 -       priv->adapter = NULL;
9586 -}
9587 -
9588 -/**
9589 - *  This function handles the timeout of command sending.
9590 - *  It will re-send the same command again.
9591 - */
9592 -static void command_timer_fn(unsigned long data)
9593 -{
9594 -       wlan_private *priv = (wlan_private *)data;
9595 -       wlan_adapter *adapter = priv->adapter;
9596 -       struct cmd_ctrl_node *ptempnode;
9597 -       struct cmd_ds_command *cmd;
9598 -       unsigned long flags;
9599 -
9600 -       ptempnode = adapter->cur_cmd;
9601 -       if (ptempnode == NULL) {
9602 -               lbs_deb_fw("ptempnode empty\n");
9603 -               return;
9604 -       }
9605 -
9606 -       cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
9607 -       if (!cmd) {
9608 -               lbs_deb_fw("cmd is NULL\n");
9609 -               return;
9610 -       }
9611 -
9612 -       lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);
9613 -
9614 -       if (!adapter->fw_ready)
9615 -               return;
9616 -
9617 -       spin_lock_irqsave(&adapter->driver_lock, flags);
9618 -       adapter->cur_cmd = NULL;
9619 -       spin_unlock_irqrestore(&adapter->driver_lock, flags);
9620 -
9621 -       lbs_deb_fw("re-sending same command because of timeout\n");
9622 -       libertas_queue_cmd(adapter, ptempnode, 0);
9623 -
9624 -       wake_up_interruptible(&priv->mainthread.waitq);
9625 -
9626 -       return;
9627 -}
9628 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/hostcmd.h linux-2.6.22-300/drivers/net/wireless/libertas/hostcmd.h
9629 --- linux-2.6.22-250/drivers/net/wireless/libertas/hostcmd.h    2007-07-08 19:32:17.000000000 -0400
9630 +++ linux-2.6.22-300/drivers/net/wireless/libertas/hostcmd.h    2008-06-05 18:10:06.000000000 -0400
9631 @@ -2,8 +2,8 @@
9632   * This file contains the function prototypes, data structure
9633   * and defines for all the host/station commands
9634   */
9635 -#ifndef __HOSTCMD__H
9636 -#define __HOSTCMD__H
9637 +#ifndef _LBS_HOSTCMD_H
9638 +#define _LBS_HOSTCMD_H
9639  
9640  #include <linux/wireless.h>
9641  #include "11d.h"
9642 @@ -65,61 +65,40 @@ struct rxpd {
9643         u8 reserved[3];
9644  };
9645  
9646 +struct cmd_header {
9647 +       __le16 command;
9648 +       __le16 size;
9649 +       __le16 seqnum;
9650 +       __le16 result;
9651 +} __attribute__ ((packed));
9652 +
9653  struct cmd_ctrl_node {
9654 -       /* CMD link list */
9655         struct list_head list;
9656 -       u32 status;
9657 -       /* CMD ID */
9658 -       u32 cmd_oid;
9659 -       /*CMD wait option: wait for finish or no wait */
9660 -       u16 wait_option;
9661 -       /* command parameter */
9662 -       void *pdata_buf;
9663 -       /*command data */
9664 -       u8 *bufvirtualaddr;
9665 -       u16 cmdflags;
9666 +       int result;
9667 +       /* command response */
9668 +       int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
9669 +       unsigned long callback_arg;
9670 +       /* command data */
9671 +       struct cmd_header *cmdbuf;
9672         /* wait queue */
9673         u16 cmdwaitqwoken;
9674         wait_queue_head_t cmdwait_q;
9675  };
9676  
9677 -/* WLAN_802_11_KEY
9678 - *
9679 - * Generic structure to hold all key types.  key type (WEP40, WEP104, TKIP, AES)
9680 - * is determined from the keylength field.
9681 - */
9682 -struct WLAN_802_11_KEY {
9683 -       __le32 len;
9684 -       __le32 flags;  /* KEY_INFO_* from wlan_defs.h */
9685 -       u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH];
9686 -       __le16 type; /* KEY_TYPE_* from wlan_defs.h */
9687 -};
9688 -
9689 -struct IE_WPA {
9690 -       u8 elementid;
9691 -       u8 len;
9692 -       u8 oui[4];
9693 -       __le16 version;
9694 +/* Generic structure to hold all key types. */
9695 +struct enc_key {
9696 +       u16 len;
9697 +       u16 flags;  /* KEY_INFO_* from defs.h */
9698 +       u16 type; /* KEY_TYPE_* from defs.h */
9699 +       u8 key[32];
9700  };
9701  
9702 -/* wlan_offset_value */
9703 -struct wlan_offset_value {
9704 +/* lbs_offset_value */
9705 +struct lbs_offset_value {
9706         u32 offset;
9707         u32 value;
9708  };
9709  
9710 -struct WLAN_802_11_FIXED_IEs {
9711 -       __le64 timestamp;
9712 -       __le16 beaconinterval;
9713 -       u16 capabilities; /* Actually struct ieeetypes_capinfo */
9714 -};
9715 -
9716 -struct WLAN_802_11_VARIABLE_IEs {
9717 -       u8 elementid;
9718 -       u8 length;
9719 -       u8 data[1];
9720 -};
9721 -
9722  /* Define general data structure */
9723  /* cmd_DS_GEN */
9724  struct cmd_ds_gen {
9725 @@ -127,14 +106,19 @@ struct cmd_ds_gen {
9726         __le16 size;
9727         __le16 seqnum;
9728         __le16 result;
9729 +       void *cmdresp[0];
9730  };
9731  
9732  #define S_DS_GEN sizeof(struct cmd_ds_gen)
9733 +
9734 +
9735  /*
9736 - * Define data structure for cmd_get_hw_spec
9737 + * Define data structure for CMD_GET_HW_SPEC
9738   * This structure defines the response for the GET_HW_SPEC command
9739   */
9740  struct cmd_ds_get_hw_spec {
9741 +       struct cmd_header hdr;
9742 +
9743         /* HW Interface version number */
9744         __le16 hwifversion;
9745         /* HW version number */
9746 @@ -174,15 +158,22 @@ struct cmd_ds_802_11_reset {
9747  struct cmd_ds_802_11_subscribe_event {
9748         __le16 action;
9749         __le16 events;
9750 +
9751 +       /* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a
9752 +        * number of TLVs. From the v5.1 manual, those TLVs would add up to
9753 +        * 40 bytes. However, future firmware might add additional TLVs, so I
9754 +        * bump this up a bit.
9755 +        */
9756 +       u8 tlv[128];
9757  };
9758  
9759  /*
9760   * This scan handle Country Information IE(802.11d compliant)
9761 - * Define data structure for cmd_802_11_scan
9762 + * Define data structure for CMD_802_11_SCAN
9763   */
9764  struct cmd_ds_802_11_scan {
9765         u8 bsstype;
9766 -       u8 BSSID[ETH_ALEN];
9767 +       u8 bssid[ETH_ALEN];
9768         u8 tlvbuffer[1];
9769  #if 0
9770         mrvlietypes_ssidparamset_t ssidParamSet;
9771 @@ -214,11 +205,13 @@ struct cmd_ds_802_11_get_log {
9772  };
9773  
9774  struct cmd_ds_mac_control {
9775 +       struct cmd_header hdr;
9776         __le16 action;
9777 -       __le16 reserved;
9778 +       u16 reserved;
9779  };
9780  
9781  struct cmd_ds_mac_multicast_adr {
9782 +       struct cmd_header hdr;
9783         __le16 action;
9784         __le16 nr_of_adrs;
9785         u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
9786 @@ -237,7 +230,7 @@ struct cmd_ds_802_11_deauthenticate {
9787  
9788  struct cmd_ds_802_11_associate {
9789         u8 peerstaaddr[6];
9790 -       struct ieeetypes_capinfo capinfo;
9791 +       __le16 capability;
9792         __le16 listeninterval;
9793         __le16 bcnperiod;
9794         u8 dtimperiod;
9795 @@ -260,8 +253,8 @@ struct cmd_ds_802_11_associate_rsp {
9796  };
9797  
9798  struct cmd_ds_802_11_ad_hoc_result {
9799 -       u8 PAD[3];
9800 -       u8 BSSID[ETH_ALEN];
9801 +       u8 pad[3];
9802 +       u8 bssid[ETH_ALEN];
9803  };
9804  
9805  struct cmd_ds_802_11_set_wep {
9806 @@ -355,6 +348,12 @@ struct cmd_ds_802_11_radio_control {
9807         __le16 control;
9808  };
9809  
9810 +struct cmd_ds_802_11_beacon_control {
9811 +       __le16 action;
9812 +       __le16 beacon_enable;
9813 +       __le16 beacon_period;
9814 +};
9815 +
9816  struct cmd_ds_802_11_sleep_params {
9817         /* ACT_GET/ACT_SET */
9818         __le16 action;
9819 @@ -387,11 +386,13 @@ struct cmd_ds_802_11_inactivity_timeout 
9820  };
9821  
9822  struct cmd_ds_802_11_rf_channel {
9823 +       struct cmd_header hdr;
9824 +
9825         __le16 action;
9826 -       __le16 currentchannel;
9827 -       __le16 rftype;
9828 -       __le16 reserved;
9829 -       u8 channellist[32];
9830 +       __le16 channel;
9831 +       __le16 rftype;      /* unused */
9832 +       __le16 reserved;    /* unused */
9833 +       u8 channellist[32]; /* unused */
9834  };
9835  
9836  struct cmd_ds_802_11_rssi {
9837 @@ -428,6 +429,32 @@ struct cmd_ds_802_11_rf_antenna {
9838  
9839  };
9840  
9841 +struct cmd_ds_802_11_monitor_mode {
9842 +       __le16 action;
9843 +       __le16 mode;
9844 +};
9845 +
9846 +struct cmd_ds_set_boot2_ver {
9847 +       struct cmd_header hdr;
9848 +
9849 +       __le16 action;
9850 +       __le16 version;
9851 +};
9852 +
9853 +struct cmd_ds_802_11_fw_wake_method {
9854 +       struct cmd_header hdr;
9855 +
9856 +       __le16 action;
9857 +       __le16 method;
9858 +};
9859 +
9860 +struct cmd_ds_802_11_sleep_period {
9861 +       struct cmd_header hdr;
9862 +
9863 +       __le16 action;
9864 +       __le16 period;
9865 +};
9866 +
9867  struct cmd_ds_802_11_ps_mode {
9868         __le16 action;
9869         __le16 nullpktinterval;
9870 @@ -450,9 +477,11 @@ struct PS_CMD_ConfirmSleep {
9871  };
9872  
9873  struct cmd_ds_802_11_data_rate {
9874 +       struct cmd_header hdr;
9875 +
9876         __le16 action;
9877 -       __le16 reserverd;
9878 -       u8 datarate[G_SUPPORTED_RATES];
9879 +       __le16 reserved;
9880 +       u8 rates[MAX_RATES];
9881  };
9882  
9883  struct cmd_ds_802_11_rate_adapt_rateset {
9884 @@ -462,30 +491,30 @@ struct cmd_ds_802_11_rate_adapt_rateset 
9885  };
9886  
9887  struct cmd_ds_802_11_ad_hoc_start {
9888 -       u8 SSID[IW_ESSID_MAX_SIZE];
9889 +       u8 ssid[IW_ESSID_MAX_SIZE];
9890         u8 bsstype;
9891         __le16 beaconperiod;
9892         u8 dtimperiod;
9893         union IEEEtypes_ssparamset ssparamset;
9894         union ieeetypes_phyparamset phyparamset;
9895         __le16 probedelay;
9896 -       struct ieeetypes_capinfo cap;
9897 -       u8 datarate[G_SUPPORTED_RATES];
9898 +       __le16 capability;
9899 +       u8 rates[MAX_RATES];
9900         u8 tlv_memory_size_pad[100];
9901  } __attribute__ ((packed));
9902  
9903  struct adhoc_bssdesc {
9904 -       u8 BSSID[6];
9905 -       u8 SSID[32];
9906 -       u8 bsstype;
9907 +       u8 bssid[6];
9908 +       u8 ssid[32];
9909 +       u8 type;
9910         __le16 beaconperiod;
9911         u8 dtimperiod;
9912         __le64 timestamp;
9913         __le64 localtime;
9914         union ieeetypes_phyparamset phyparamset;
9915         union IEEEtypes_ssparamset ssparamset;
9916 -       struct ieeetypes_capinfo cap;
9917 -       u8 datarates[G_SUPPORTED_RATES];
9918 +       __le16 capability;
9919 +       u8 rates[MAX_RATES];
9920  
9921         /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
9922          * Adhoc join command and will cause a binary layout mismatch with
9923 @@ -494,7 +523,7 @@ struct adhoc_bssdesc {
9924  } __attribute__ ((packed));
9925  
9926  struct cmd_ds_802_11_ad_hoc_join {
9927 -       struct adhoc_bssdesc bssdescriptor;
9928 +       struct adhoc_bssdesc bss;
9929         __le16 failtimeout;
9930         __le16 probedelay;
9931  
9932 @@ -525,6 +554,13 @@ struct MrvlIEtype_keyParamSet {
9933         u8 key[32];
9934  };
9935  
9936 +struct cmd_ds_host_sleep {
9937 +       struct cmd_header hdr;
9938 +       __le32 criteria;
9939 +       uint8_t gpio;
9940 +       uint8_t gap;
9941 +} __attribute__ ((packed));
9942 +
9943  struct cmd_ds_802_11_key_material {
9944         __le16 action;
9945         struct MrvlIEtype_keyParamSet keyParamSet[2];
9946 @@ -611,7 +647,21 @@ struct cmd_ds_fwt_access {
9947         u8 prec[ETH_ALEN];
9948  } __attribute__ ((packed));
9949  
9950 +
9951 +struct cmd_ds_mesh_config {
9952 +       struct cmd_header hdr;
9953 +
9954 +        __le16 action;
9955 +        __le16 channel;
9956 +        __le16 type;
9957 +        __le16 length;
9958 +        u8 data[128];   /* last position reserved */
9959 +} __attribute__ ((packed));
9960 +
9961 +
9962  struct cmd_ds_mesh_access {
9963 +       struct cmd_header hdr;
9964 +
9965         __le16 action;
9966         __le32 data[32];        /* last position reserved */
9967  } __attribute__ ((packed));
9968 @@ -628,11 +678,9 @@ struct cmd_ds_command {
9969  
9970         /* command Body */
9971         union {
9972 -               struct cmd_ds_get_hw_spec hwspec;
9973                 struct cmd_ds_802_11_ps_mode psmode;
9974                 struct cmd_ds_802_11_scan scan;
9975                 struct cmd_ds_802_11_scan_rsp scanresp;
9976 -               struct cmd_ds_mac_control macctrl;
9977                 struct cmd_ds_802_11_associate associate;
9978                 struct cmd_ds_802_11_deauthenticate deauth;
9979                 struct cmd_ds_802_11_set_wep wep;
9980 @@ -646,9 +694,8 @@ struct cmd_ds_command {
9981                 struct cmd_ds_802_11_snmp_mib smib;
9982                 struct cmd_ds_802_11_rf_tx_power txp;
9983                 struct cmd_ds_802_11_rf_antenna rant;
9984 -               struct cmd_ds_802_11_data_rate drate;
9985 +               struct cmd_ds_802_11_monitor_mode monitor;
9986                 struct cmd_ds_802_11_rate_adapt_rateset rateset;
9987 -               struct cmd_ds_mac_multicast_adr madr;
9988                 struct cmd_ds_802_11_ad_hoc_join adj;
9989                 struct cmd_ds_802_11_radio_control radio;
9990                 struct cmd_ds_802_11_rf_channel rfchannel;
9991 @@ -676,9 +723,9 @@ struct cmd_ds_command {
9992                 struct cmd_tx_rate_query txrate;
9993                 struct cmd_ds_bt_access bt;
9994                 struct cmd_ds_fwt_access fwt;
9995 -               struct cmd_ds_mesh_access mesh;
9996                 struct cmd_ds_get_tsf gettsf;
9997                 struct cmd_ds_802_11_subscribe_event subscribe_event;
9998 +               struct cmd_ds_802_11_beacon_control bcn_ctrl;
9999         } params;
10000  } __attribute__ ((packed));
10001  
10002 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/host.h linux-2.6.22-300/drivers/net/wireless/libertas/host.h
10003 --- linux-2.6.22-250/drivers/net/wireless/libertas/host.h       2007-07-08 19:32:17.000000000 -0400
10004 +++ linux-2.6.22-300/drivers/net/wireless/libertas/host.h       2008-06-05 18:10:06.000000000 -0400
10005 @@ -2,340 +2,313 @@
10006    * This file contains definitions of WLAN commands.
10007    */
10008  
10009 -#ifndef _HOST_H_
10010 -#define _HOST_H_
10011 +#ifndef _LBS_HOST_H_
10012 +#define _LBS_HOST_H_
10013  
10014  /** PUBLIC DEFINITIONS */
10015 -#define DEFAULT_AD_HOC_CHANNEL       6
10016 -#define DEFAULT_AD_HOC_CHANNEL_A    36
10017 +#define DEFAULT_AD_HOC_CHANNEL                 6
10018 +#define        DEFAULT_AD_HOC_CHANNEL_A                36
10019  
10020  /** IEEE 802.11 oids */
10021 -#define OID_802_11_SSID                       0x00008002
10022 -#define OID_802_11_INFRASTRUCTURE_MODE        0x00008008
10023 -#define OID_802_11_FRAGMENTATION_THRESHOLD    0x00008009
10024 -#define OID_802_11_RTS_THRESHOLD              0x0000800A
10025 -#define OID_802_11_TX_ANTENNA_SELECTED        0x0000800D
10026 -#define OID_802_11_SUPPORTED_RATES            0x0000800E
10027 -#define OID_802_11_STATISTICS                 0x00008012
10028 -#define OID_802_11_TX_RETRYCOUNT              0x0000801D
10029 -#define OID_802_11D_ENABLE                    0x00008020
10030 -
10031 -#define cmd_option_waitforrsp             0x0002
10032 -
10033 -/** Host command ID */
10034 -#define cmd_code_dnld                 0x0002
10035 -#define cmd_get_hw_spec               0x0003
10036 -#define cmd_eeprom_update             0x0004
10037 -#define cmd_802_11_reset              0x0005
10038 -#define cmd_802_11_scan               0x0006
10039 -#define cmd_802_11_get_log            0x000b
10040 -#define cmd_mac_multicast_adr         0x0010
10041 -#define cmd_802_11_authenticate       0x0011
10042 -#define cmd_802_11_eeprom_access      0x0059
10043 -#define cmd_802_11_associate          0x0050
10044 -#define cmd_802_11_set_wep            0x0013
10045 -#define cmd_802_11_get_stat           0x0014
10046 -#define cmd_802_3_get_stat            0x0015
10047 -#define cmd_802_11_snmp_mib           0x0016
10048 -#define cmd_mac_reg_map               0x0017
10049 -#define cmd_bbp_reg_map               0x0018
10050 -#define cmd_mac_reg_access            0x0019
10051 -#define cmd_bbp_reg_access            0x001a
10052 -#define cmd_rf_reg_access             0x001b
10053 -#define cmd_802_11_radio_control      0x001c
10054 -#define cmd_802_11_rf_channel         0x001d
10055 -#define cmd_802_11_rf_tx_power        0x001e
10056 -#define cmd_802_11_rssi               0x001f
10057 -#define cmd_802_11_rf_antenna         0x0020
10058 -
10059 -#define cmd_802_11_ps_mode           0x0021
10060 -
10061 -#define cmd_802_11_data_rate          0x0022
10062 -#define cmd_rf_reg_map                0x0023
10063 -#define cmd_802_11_deauthenticate     0x0024
10064 -#define cmd_802_11_reassociate        0x0025
10065 -#define cmd_802_11_disassociate       0x0026
10066 -#define cmd_mac_control               0x0028
10067 -#define cmd_802_11_ad_hoc_start       0x002b
10068 -#define cmd_802_11_ad_hoc_join        0x002c
10069 -
10070 -#define cmd_802_11_query_tkip_reply_cntrs  0x002e
10071 -#define cmd_802_11_enable_rsn              0x002f
10072 -#define cmd_802_11_pairwise_tsc       0x0036
10073 -#define cmd_802_11_group_tsc          0x0037
10074 -#define cmd_802_11_key_material       0x005e
10075 -
10076 -#define cmd_802_11_set_afc            0x003c
10077 -#define cmd_802_11_get_afc            0x003d
10078 -
10079 -#define cmd_802_11_ad_hoc_stop        0x0040
10080 -
10081 -#define cmd_802_11_beacon_stop        0x0049
10082 -
10083 -#define cmd_802_11_mac_address        0x004D
10084 -#define cmd_802_11_eeprom_access      0x0059
10085 -
10086 -#define cmd_802_11_band_config        0x0058
10087 -
10088 -#define cmd_802_11d_domain_info       0x005b
10089 -
10090 -#define cmd_802_11_sleep_params          0x0066
10091 -
10092 -#define cmd_802_11_inactivity_timeout    0x0067
10093 -
10094 -#define cmd_802_11_tpc_cfg               0x0072
10095 -#define cmd_802_11_pwr_cfg               0x0073
10096 -
10097 -#define cmd_802_11_led_gpio_ctrl         0x004e
10098 -
10099 -#define cmd_802_11_subscribe_event       0x0075
10100 -
10101 -#define cmd_802_11_rate_adapt_rateset    0x0076
10102 -
10103 -#define cmd_802_11_tx_rate_query       0x007f
10104 -
10105 -#define cmd_get_tsf                      0x0080
10106 -
10107 -#define cmd_bt_access                 0x0087
10108 -#define cmd_ret_bt_access                 0x8087
10109 -
10110 -#define cmd_fwt_access                0x0095
10111 -#define cmd_ret_fwt_access                0x8095
10112 -
10113 -#define cmd_mesh_access               0x009b
10114 -#define cmd_ret_mesh_access               0x809b
10115 +#define OID_802_11_SSID                                0x00008002
10116 +#define OID_802_11_INFRASTRUCTURE_MODE         0x00008008
10117 +#define OID_802_11_FRAGMENTATION_THRESHOLD     0x00008009
10118 +#define OID_802_11_RTS_THRESHOLD               0x0000800A
10119 +#define OID_802_11_TX_ANTENNA_SELECTED         0x0000800D
10120 +#define OID_802_11_SUPPORTED_RATES             0x0000800E
10121 +#define OID_802_11_STATISTICS                  0x00008012
10122 +#define OID_802_11_TX_RETRYCOUNT               0x0000801D
10123 +#define OID_802_11D_ENABLE                     0x00008020
10124 +
10125 +#define CMD_OPTION_WAITFORRSP                  0x0002
10126 +
10127 +/** Host command IDs */
10128 +
10129 +/* Return command are almost always the same as the host command, but with
10130 + * bit 15 set high.  There are a few exceptions, though...
10131 + */
10132 +#define CMD_RET(cmd)                   (0x8000 | cmd)
10133 +
10134 +/* Return command convention exceptions: */
10135 +#define CMD_RET_802_11_ASSOCIATE               0x8012
10136 +
10137 +/* Command codes */
10138 +#define CMD_CODE_DNLD                          0x0002
10139 +#define CMD_GET_HW_SPEC                                0x0003
10140 +#define        CMD_EEPROM_UPDATE                       0x0004
10141 +#define CMD_802_11_RESET                       0x0005
10142 +#define        CMD_802_11_SCAN                         0x0006
10143 +#define CMD_802_11_GET_LOG                     0x000b
10144 +#define CMD_MAC_MULTICAST_ADR                  0x0010
10145 +#define CMD_802_11_AUTHENTICATE                        0x0011
10146 +#define CMD_802_11_EEPROM_ACCESS               0x0059
10147 +#define CMD_802_11_ASSOCIATE                   0x0050
10148 +#define CMD_802_11_SET_WEP                     0x0013
10149 +#define CMD_802_11_GET_STAT                    0x0014
10150 +#define CMD_802_3_GET_STAT                     0x0015
10151 +#define CMD_802_11_SNMP_MIB                    0x0016
10152 +#define CMD_MAC_REG_MAP                                0x0017
10153 +#define CMD_BBP_REG_MAP                                0x0018
10154 +#define CMD_MAC_REG_ACCESS                     0x0019
10155 +#define CMD_BBP_REG_ACCESS                     0x001a
10156 +#define CMD_RF_REG_ACCESS                      0x001b
10157 +#define CMD_802_11_RADIO_CONTROL               0x001c
10158 +#define CMD_802_11_RF_CHANNEL                  0x001d
10159 +#define CMD_802_11_RF_TX_POWER                 0x001e
10160 +#define CMD_802_11_RSSI                                0x001f
10161 +#define CMD_802_11_RF_ANTENNA                  0x0020
10162 +#define CMD_802_11_PS_MODE                     0x0021
10163 +#define CMD_802_11_DATA_RATE                   0x0022
10164 +#define CMD_RF_REG_MAP                         0x0023
10165 +#define CMD_802_11_DEAUTHENTICATE              0x0024
10166 +#define CMD_802_11_REASSOCIATE                 0x0025
10167 +#define CMD_802_11_DISASSOCIATE                        0x0026
10168 +#define CMD_MAC_CONTROL                                0x0028
10169 +#define CMD_802_11_AD_HOC_START                        0x002b
10170 +#define CMD_802_11_AD_HOC_JOIN                 0x002c
10171 +#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS      0x002e
10172 +#define CMD_802_11_ENABLE_RSN                  0x002f
10173 +#define CMD_802_11_PAIRWISE_TSC                        0x0036
10174 +#define CMD_802_11_GROUP_TSC                   0x0037
10175 +#define CMD_802_11_SET_AFC                     0x003c
10176 +#define CMD_802_11_GET_AFC                     0x003d
10177 +#define CMD_802_11_AD_HOC_STOP                 0x0040
10178 +#define CMD_802_11_HOST_SLEEP_CFG              0x0043
10179 +#define CMD_802_11_WAKEUP_CONFIRM              0x0044
10180 +#define CMD_802_11_HOST_SLEEP_ACTIVATE         0x0045
10181 +#define CMD_802_11_BEACON_STOP                 0x0049
10182 +#define CMD_802_11_MAC_ADDRESS                 0x004d
10183 +#define CMD_802_11_LED_GPIO_CTRL               0x004e
10184 +#define CMD_802_11_EEPROM_ACCESS               0x0059
10185 +#define CMD_802_11_BAND_CONFIG                 0x0058
10186 +#define CMD_802_11D_DOMAIN_INFO                        0x005b
10187 +#define CMD_802_11_KEY_MATERIAL                        0x005e
10188 +#define CMD_802_11_SLEEP_PARAMS                        0x0066
10189 +#define CMD_802_11_INACTIVITY_TIMEOUT          0x0067
10190 +#define CMD_802_11_SLEEP_PERIOD                        0x0068
10191 +#define CMD_802_11_TPC_CFG                     0x0072
10192 +#define CMD_802_11_PWR_CFG                     0x0073
10193 +#define CMD_802_11_FW_WAKE_METHOD              0x0074
10194 +#define CMD_802_11_SUBSCRIBE_EVENT             0x0075
10195 +#define CMD_802_11_RATE_ADAPT_RATESET          0x0076
10196 +#define CMD_802_11_TX_RATE_QUERY               0x007f
10197 +#define        CMD_GET_TSF                             0x0080
10198 +#define CMD_BT_ACCESS                          0x0087
10199 +#define CMD_FWT_ACCESS                         0x0095
10200 +#define CMD_802_11_MONITOR_MODE                        0x0098
10201 +#define CMD_MESH_ACCESS                                0x009b
10202 +#define CMD_MESH_CONFIG                                0x00a3
10203 +#define        CMD_SET_BOOT2_VER                       0x00a5
10204 +#define CMD_802_11_BEACON_CTRL                 0x00b0
10205  
10206  /* For the IEEE Power Save */
10207 -#define cmd_subcmd_enter_ps               0x0030
10208 -#define cmd_subcmd_exit_ps                0x0031
10209 -#define cmd_subcmd_sleep_confirmed        0x0034
10210 -#define cmd_subcmd_full_powerdown         0x0035
10211 -#define cmd_subcmd_full_powerup           0x0036
10212 -
10213 -/* command RET code, MSB is set to 1 */
10214 -#define cmd_ret_hw_spec_info              0x8003
10215 -#define cmd_ret_eeprom_update             0x8004
10216 -#define cmd_ret_802_11_reset              0x8005
10217 -#define cmd_ret_802_11_scan               0x8006
10218 -#define cmd_ret_802_11_get_log            0x800b
10219 -#define cmd_ret_mac_control               0x8028
10220 -#define cmd_ret_mac_multicast_adr         0x8010
10221 -#define cmd_ret_802_11_authenticate       0x8011
10222 -#define cmd_ret_802_11_deauthenticate     0x8024
10223 -#define cmd_ret_802_11_associate          0x8012
10224 -#define cmd_ret_802_11_reassociate        0x8025
10225 -#define cmd_ret_802_11_disassociate       0x8026
10226 -#define cmd_ret_802_11_set_wep            0x8013
10227 -#define cmd_ret_802_11_stat               0x8014
10228 -#define cmd_ret_802_3_stat                0x8015
10229 -#define cmd_ret_802_11_snmp_mib           0x8016
10230 -#define cmd_ret_mac_reg_map               0x8017
10231 -#define cmd_ret_bbp_reg_map               0x8018
10232 -#define cmd_ret_rf_reg_map                0x8023
10233 -#define cmd_ret_mac_reg_access            0x8019
10234 -#define cmd_ret_bbp_reg_access            0x801a
10235 -#define cmd_ret_rf_reg_access             0x801b
10236 -#define cmd_ret_802_11_radio_control      0x801c
10237 -#define cmd_ret_802_11_rf_channel         0x801d
10238 -#define cmd_ret_802_11_rssi               0x801f
10239 -#define cmd_ret_802_11_rf_tx_power        0x801e
10240 -#define cmd_ret_802_11_rf_antenna         0x8020
10241 -#define cmd_ret_802_11_ps_mode            0x8021
10242 -#define cmd_ret_802_11_data_rate          0x8022
10243 -
10244 -#define cmd_ret_802_11_ad_hoc_start       0x802B
10245 -#define cmd_ret_802_11_ad_hoc_join        0x802C
10246 -
10247 -#define cmd_ret_802_11_query_tkip_reply_cntrs  0x802e
10248 -#define cmd_ret_802_11_enable_rsn              0x802f
10249 -#define cmd_ret_802_11_pairwise_tsc       0x8036
10250 -#define cmd_ret_802_11_group_tsc          0x8037
10251 -#define cmd_ret_802_11_key_material       0x805e
10252 -
10253 -#define cmd_enable_rsn                    0x0001
10254 -#define cmd_disable_rsn                   0x0000
10255 -
10256 -#define cmd_act_set                       0x0001
10257 -#define cmd_act_get                       0x0000
10258 -
10259 -#define cmd_act_get_AES                   (cmd_act_get + 2)
10260 -#define cmd_act_set_AES                   (cmd_act_set + 2)
10261 -#define cmd_act_remove_aes                (cmd_act_set + 3)
10262 -
10263 -#define cmd_ret_802_11_set_afc            0x803c
10264 -#define cmd_ret_802_11_get_afc            0x803d
10265 -
10266 -#define cmd_ret_802_11_ad_hoc_stop        0x8040
10267 -
10268 -#define cmd_ret_802_11_beacon_stop        0x8049
10269 -
10270 -#define cmd_ret_802_11_mac_address        0x804D
10271 -#define cmd_ret_802_11_eeprom_access      0x8059
10272 -
10273 -#define cmd_ret_802_11_band_config        0x8058
10274 -
10275 -#define cmd_ret_802_11_sleep_params          0x8066
10276 -
10277 -#define cmd_ret_802_11_inactivity_timeout    0x8067
10278 -
10279 -#define cmd_ret_802_11d_domain_info      (0x8000 |                  \
10280 -                                              cmd_802_11d_domain_info)
10281 -
10282 -#define cmd_ret_802_11_tpc_cfg        (cmd_802_11_tpc_cfg | 0x8000)
10283 -#define cmd_ret_802_11_pwr_cfg        (cmd_802_11_pwr_cfg | 0x8000)
10284 -
10285 -#define cmd_ret_802_11_led_gpio_ctrl     0x804e
10286 -
10287 -#define cmd_ret_802_11_subscribe_event (cmd_802_11_subscribe_event | 0x8000)
10288 -
10289 -#define cmd_ret_802_11_rate_adapt_rateset      (cmd_802_11_rate_adapt_rateset | 0x8000)
10290 -
10291 -#define cmd_rte_802_11_tx_rate_query   (cmd_802_11_tx_rate_query | 0x8000)
10292 -
10293 -#define cmd_ret_get_tsf             0x8080
10294 -
10295 -/* Define action or option for cmd_802_11_set_wep */
10296 -#define cmd_act_add                         0x0002
10297 -#define cmd_act_remove                      0x0004
10298 -#define cmd_act_use_default                 0x0008
10299 -
10300 -#define cmd_type_wep_40_bit                 0x0001
10301 -#define cmd_type_wep_104_bit                0x0002
10302 -
10303 -#define cmd_NUM_OF_WEP_KEYS                 4
10304 -
10305 -#define cmd_WEP_KEY_INDEX_MASK              0x3fff
10306 -
10307 -/* Define action or option for cmd_802_11_reset */
10308 -#define cmd_act_halt                        0x0003
10309 -
10310 -/* Define action or option for cmd_802_11_scan */
10311 -#define cmd_bss_type_bss                    0x0001
10312 -#define cmd_bss_type_ibss                   0x0002
10313 -#define cmd_bss_type_any                    0x0003
10314 -
10315 -/* Define action or option for cmd_802_11_scan */
10316 -#define cmd_scan_type_active                0x0000
10317 -#define cmd_scan_type_passive               0x0001
10318 -
10319 -#define cmd_scan_radio_type_bg         0
10320 -
10321 -#define cmd_scan_probe_delay_time           0
10322 -
10323 -/* Define action or option for cmd_mac_control */
10324 -#define cmd_act_mac_rx_on                   0x0001
10325 -#define cmd_act_mac_tx_on                   0x0002
10326 -#define cmd_act_mac_loopback_on             0x0004
10327 -#define cmd_act_mac_wep_enable              0x0008
10328 -#define cmd_act_mac_int_enable              0x0010
10329 -#define cmd_act_mac_multicast_enable        0x0020
10330 -#define cmd_act_mac_broadcast_enable        0x0040
10331 -#define cmd_act_mac_promiscuous_enable      0x0080
10332 -#define cmd_act_mac_all_multicast_enable    0x0100
10333 -#define cmd_act_mac_strict_protection_enable  0x0400
10334 -
10335 -/* Define action or option for cmd_802_11_radio_control */
10336 -#define cmd_type_auto_preamble              0x0001
10337 -#define cmd_type_short_preamble             0x0002
10338 -#define cmd_type_long_preamble              0x0003
10339 -
10340 -#define TURN_ON_RF                              0x01
10341 -#define RADIO_ON                                0x01
10342 -#define RADIO_OFF                               0x00
10343 -
10344 -#define SET_AUTO_PREAMBLE                       0x05
10345 -#define SET_SHORT_PREAMBLE                      0x03
10346 -#define SET_LONG_PREAMBLE                       0x01
10347 +#define CMD_SUBCMD_ENTER_PS            0x0030
10348 +#define CMD_SUBCMD_EXIT_PS             0x0031
10349 +#define CMD_SUBCMD_SLEEP_CONFIRMED     0x0034
10350 +#define CMD_SUBCMD_FULL_POWERDOWN      0x0035
10351 +#define CMD_SUBCMD_FULL_POWERUP                0x0036
10352 +
10353 +#define CMD_ENABLE_RSN                 0x0001
10354 +#define CMD_DISABLE_RSN                        0x0000
10355 +
10356 +#define CMD_ACT_GET                    0x0000
10357 +#define CMD_ACT_SET                    0x0001
10358 +#define CMD_ACT_GET_AES                        0x0002
10359 +#define CMD_ACT_SET_AES                        0x0003
10360 +#define CMD_ACT_REMOVE_AES             0x0004
10361 +
10362 +/* Define action or option for CMD_802_11_SET_WEP */
10363 +#define CMD_ACT_ADD                    0x0002
10364 +#define CMD_ACT_REMOVE                 0x0004
10365 +#define CMD_ACT_USE_DEFAULT            0x0008
10366 +
10367 +#define CMD_TYPE_WEP_40_BIT            0x01
10368 +#define CMD_TYPE_WEP_104_BIT           0x02
10369 +
10370 +#define CMD_NUM_OF_WEP_KEYS            4
10371 +
10372 +#define CMD_WEP_KEY_INDEX_MASK         0x3fff
10373 +
10374 +/* Define action or option for CMD_802_11_RESET */
10375 +#define CMD_ACT_HALT                   0x0003
10376 +
10377 +/* Define action or option for CMD_802_11_SCAN */
10378 +#define CMD_BSS_TYPE_BSS               0x0001
10379 +#define CMD_BSS_TYPE_IBSS              0x0002
10380 +#define CMD_BSS_TYPE_ANY               0x0003
10381 +
10382 +/* Define action or option for CMD_802_11_SCAN */
10383 +#define CMD_SCAN_TYPE_ACTIVE           0x0000
10384 +#define CMD_SCAN_TYPE_PASSIVE          0x0001
10385 +
10386 +#define CMD_SCAN_RADIO_TYPE_BG         0
10387 +
10388 +#define        CMD_SCAN_PROBE_DELAY_TIME       0
10389 +
10390 +/* Define action or option for CMD_MAC_CONTROL */
10391 +#define CMD_ACT_MAC_RX_ON                      0x0001
10392 +#define CMD_ACT_MAC_TX_ON                      0x0002
10393 +#define CMD_ACT_MAC_LOOPBACK_ON                        0x0004
10394 +#define CMD_ACT_MAC_WEP_ENABLE                 0x0008
10395 +#define CMD_ACT_MAC_INT_ENABLE                 0x0010
10396 +#define CMD_ACT_MAC_MULTICAST_ENABLE           0x0020
10397 +#define CMD_ACT_MAC_BROADCAST_ENABLE           0x0040
10398 +#define CMD_ACT_MAC_PROMISCUOUS_ENABLE         0x0080
10399 +#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE       0x0100
10400 +#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE   0x0400
10401 +
10402 +/* Define action or option for CMD_802_11_RADIO_CONTROL */
10403 +#define CMD_TYPE_AUTO_PREAMBLE         0x0001
10404 +#define CMD_TYPE_SHORT_PREAMBLE                0x0002
10405 +#define CMD_TYPE_LONG_PREAMBLE         0x0003
10406 +
10407 +/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
10408 +#define CMD_SUBSCRIBE_RSSI_LOW         0x0001
10409 +#define CMD_SUBSCRIBE_SNR_LOW          0x0002
10410 +#define CMD_SUBSCRIBE_FAILCOUNT                0x0004
10411 +#define CMD_SUBSCRIBE_BCNMISS          0x0008
10412 +#define CMD_SUBSCRIBE_RSSI_HIGH                0x0010
10413 +#define CMD_SUBSCRIBE_SNR_HIGH         0x0020
10414 +
10415 +#define TURN_ON_RF                     0x01
10416 +#define RADIO_ON                       0x01
10417 +#define RADIO_OFF                      0x00
10418 +
10419 +#define SET_AUTO_PREAMBLE              0x05
10420 +#define SET_SHORT_PREAMBLE             0x03
10421 +#define SET_LONG_PREAMBLE              0x01
10422  
10423  /* Define action or option for CMD_802_11_RF_CHANNEL */
10424 -#define cmd_opt_802_11_rf_channel_get       0x00
10425 -#define cmd_opt_802_11_rf_channel_set       0x01
10426 +#define CMD_OPT_802_11_RF_CHANNEL_GET  0x00
10427 +#define CMD_OPT_802_11_RF_CHANNEL_SET  0x01
10428  
10429 -/* Define action or option for cmd_802_11_rf_tx_power */
10430 -#define cmd_act_tx_power_opt_get            0x0000
10431 -#define cmd_act_tx_power_opt_set_high       0x8007
10432 -#define cmd_act_tx_power_opt_set_mid        0x8004
10433 -#define cmd_act_tx_power_opt_set_low        0x8000
10434 -
10435 -#define cmd_act_tx_power_index_high         0x0007
10436 -#define cmd_act_tx_power_index_mid          0x0004
10437 -#define cmd_act_tx_power_index_low          0x0000
10438 -
10439 -/* Define action or option for cmd_802_11_data_rate */
10440 -#define cmd_act_set_tx_auto                 0x0000
10441 -#define cmd_act_set_tx_fix_rate             0x0001
10442 -#define cmd_act_get_tx_rate                 0x0002
10443 -
10444 -#define cmd_act_set_rx                      0x0001
10445 -#define cmd_act_set_tx                      0x0002
10446 -#define cmd_act_set_both                    0x0003
10447 -#define cmd_act_get_rx                      0x0004
10448 -#define cmd_act_get_tx                      0x0008
10449 -#define cmd_act_get_both                    0x000c
10450 -
10451 -/* Define action or option for cmd_802_11_ps_mode */
10452 -#define cmd_type_cam                        0x0000
10453 -#define cmd_type_max_psp                    0x0001
10454 -#define cmd_type_fast_psp                   0x0002
10455 +/* Define action or option for CMD_802_11_RF_TX_POWER */
10456 +#define CMD_ACT_TX_POWER_OPT_GET       0x0000
10457 +#define CMD_ACT_TX_POWER_OPT_SET_HIGH  0x8007
10458 +#define CMD_ACT_TX_POWER_OPT_SET_MID   0x8004
10459 +#define CMD_ACT_TX_POWER_OPT_SET_LOW   0x8000
10460 +
10461 +#define CMD_ACT_TX_POWER_INDEX_HIGH    0x0007
10462 +#define CMD_ACT_TX_POWER_INDEX_MID     0x0004
10463 +#define CMD_ACT_TX_POWER_INDEX_LOW     0x0000
10464 +
10465 +/* Define action or option for CMD_802_11_DATA_RATE */
10466 +#define CMD_ACT_SET_TX_AUTO            0x0000
10467 +#define CMD_ACT_SET_TX_FIX_RATE                0x0001
10468 +#define CMD_ACT_GET_TX_RATE            0x0002
10469 +
10470 +#define CMD_ACT_SET_RX                 0x0001
10471 +#define        CMD_ACT_SET_TX                  0x0002
10472 +#define CMD_ACT_SET_BOTH               0x0003
10473 +#define        CMD_ACT_GET_RX                  0x0004
10474 +#define CMD_ACT_GET_TX                 0x0008
10475 +#define        CMD_ACT_GET_BOTH                0x000c
10476 +
10477 +/* Define action or option for CMD_802_11_PS_MODE */
10478 +#define CMD_TYPE_CAM                   0x0000
10479 +#define        CMD_TYPE_MAX_PSP                0x0001
10480 +#define CMD_TYPE_FAST_PSP              0x0002
10481 +
10482 +/* Options for CMD_802_11_FW_WAKE_METHOD */
10483 +#define CMD_WAKE_METHOD_UNCHANGED      0x0000
10484 +#define CMD_WAKE_METHOD_COMMAND_INT    0x0001
10485 +#define CMD_WAKE_METHOD_GPIO           0x0002
10486  
10487 -/* Define action or option for cmd_bt_access */
10488 +/* Define action or option for CMD_BT_ACCESS */
10489  enum cmd_bt_access_opts {
10490         /* The bt commands start at 5 instead of 1 because the old dft commands
10491          * are mapped to 1-4.  These old commands are no longer maintained and
10492          * should not be called.
10493          */
10494 -       cmd_act_bt_access_add = 5,
10495 -       cmd_act_bt_access_del,
10496 -       cmd_act_bt_access_list,
10497 -       cmd_act_bt_access_reset,
10498 -       cmd_act_bt_access_set_invert,
10499 -       cmd_act_bt_access_get_invert
10500 +       CMD_ACT_BT_ACCESS_ADD = 5,
10501 +       CMD_ACT_BT_ACCESS_DEL,
10502 +       CMD_ACT_BT_ACCESS_LIST,
10503 +       CMD_ACT_BT_ACCESS_RESET,
10504 +       CMD_ACT_BT_ACCESS_SET_INVERT,
10505 +       CMD_ACT_BT_ACCESS_GET_INVERT
10506  };
10507  
10508 -/* Define action or option for cmd_fwt_access */
10509 +/* Define action or option for CMD_FWT_ACCESS */
10510  enum cmd_fwt_access_opts {
10511 -       cmd_act_fwt_access_add = 1,
10512 -       cmd_act_fwt_access_del,
10513 -       cmd_act_fwt_access_lookup,
10514 -       cmd_act_fwt_access_list,
10515 -       cmd_act_fwt_access_list_route,
10516 -       cmd_act_fwt_access_list_neighbor,
10517 -       cmd_act_fwt_access_reset,
10518 -       cmd_act_fwt_access_cleanup,
10519 -       cmd_act_fwt_access_time,
10520 +       CMD_ACT_FWT_ACCESS_ADD = 1,
10521 +       CMD_ACT_FWT_ACCESS_DEL,
10522 +       CMD_ACT_FWT_ACCESS_LOOKUP,
10523 +       CMD_ACT_FWT_ACCESS_LIST,
10524 +       CMD_ACT_FWT_ACCESS_LIST_ROUTE,
10525 +       CMD_ACT_FWT_ACCESS_LIST_NEIGHBOR,
10526 +       CMD_ACT_FWT_ACCESS_RESET,
10527 +       CMD_ACT_FWT_ACCESS_CLEANUP,
10528 +       CMD_ACT_FWT_ACCESS_TIME,
10529  };
10530  
10531 -/* Define action or option for cmd_mesh_access */
10532 +/* Define action or option for CMD_MESH_ACCESS */
10533  enum cmd_mesh_access_opts {
10534 -       cmd_act_mesh_get_ttl = 1,
10535 -       cmd_act_mesh_set_ttl,
10536 -       cmd_act_mesh_get_stats,
10537 -       cmd_act_mesh_get_anycast,
10538 -       cmd_act_mesh_set_anycast,
10539 +       CMD_ACT_MESH_GET_TTL = 1,
10540 +       CMD_ACT_MESH_SET_TTL,
10541 +       CMD_ACT_MESH_GET_STATS,
10542 +       CMD_ACT_MESH_GET_ANYCAST,
10543 +       CMD_ACT_MESH_SET_ANYCAST,
10544 +       CMD_ACT_MESH_SET_LINK_COSTS,
10545 +       CMD_ACT_MESH_GET_LINK_COSTS,
10546 +       CMD_ACT_MESH_SET_BCAST_RATE,
10547 +       CMD_ACT_MESH_GET_BCAST_RATE,
10548 +       CMD_ACT_MESH_SET_RREQ_DELAY,
10549 +       CMD_ACT_MESH_GET_RREQ_DELAY,
10550 +       CMD_ACT_MESH_SET_ROUTE_EXP,
10551 +       CMD_ACT_MESH_GET_ROUTE_EXP,
10552 +       CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
10553 +       CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
10554 +       CMD_ACT_MESH_SET_PRB_RSP_RETRY_LIMIT = 17,
10555 +};
10556 +
10557 +/* Define actions and types for CMD_MESH_CONFIG */
10558 +enum cmd_mesh_config_actions {
10559 +       CMD_ACT_MESH_CONFIG_STOP = 0,
10560 +       CMD_ACT_MESH_CONFIG_START,
10561 +       CMD_ACT_MESH_CONFIG_SET,
10562 +       CMD_ACT_MESH_CONFIG_GET,
10563 +};
10564 +
10565 +enum cmd_mesh_config_types {
10566 +       CMD_TYPE_MESH_SET_BOOTFLAG = 1,
10567 +       CMD_TYPE_MESH_SET_BOOTTIME,
10568 +       CMD_TYPE_MESH_SET_DEF_CHANNEL,
10569 +       CMD_TYPE_MESH_SET_MESH_IE,
10570 +       CMD_TYPE_MESH_GET_DEFAULTS,
10571 +       CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
10572  };
10573  
10574  /** Card Event definition */
10575 -#define MACREG_INT_CODE_TX_PPA_FREE             0x00000000
10576 -#define MACREG_INT_CODE_TX_DMA_DONE             0x00000001
10577 -#define MACREG_INT_CODE_LINK_LOSE_W_SCAN        0x00000002
10578 -#define MACREG_INT_CODE_LINK_LOSE_NO_SCAN       0x00000003
10579 -#define MACREG_INT_CODE_LINK_SENSED             0x00000004
10580 -#define MACREG_INT_CODE_CMD_FINISHED            0x00000005
10581 -#define MACREG_INT_CODE_MIB_CHANGED             0x00000006
10582 -#define MACREG_INT_CODE_INIT_DONE               0x00000007
10583 -#define MACREG_INT_CODE_DEAUTHENTICATED         0x00000008
10584 -#define MACREG_INT_CODE_DISASSOCIATED           0x00000009
10585 -#define MACREG_INT_CODE_PS_AWAKE                0x0000000a
10586 -#define MACREG_INT_CODE_PS_SLEEP                0x0000000b
10587 -#define MACREG_INT_CODE_MIC_ERR_MULTICAST       0x0000000d
10588 -#define MACREG_INT_CODE_MIC_ERR_UNICAST         0x0000000e
10589 -#define MACREG_INT_CODE_WM_AWAKE                0x0000000f
10590 -#define MACREG_INT_CODE_ADHOC_BCN_LOST          0x00000011
10591 -#define MACREG_INT_CODE_RSSI_LOW               0x00000019
10592 -#define MACREG_INT_CODE_SNR_LOW                        0x0000001a
10593 -#define MACREG_INT_CODE_MAX_FAIL               0x0000001b
10594 -#define MACREG_INT_CODE_RSSI_HIGH              0x0000001c
10595 -#define MACREG_INT_CODE_SNR_HIGH               0x0000001d
10596 -#define MACREG_INT_CODE_MESH_AUTO_STARTED      0x00000023
10597 +#define MACREG_INT_CODE_TX_PPA_FREE            0
10598 +#define MACREG_INT_CODE_TX_DMA_DONE            1
10599 +#define MACREG_INT_CODE_LINK_LOST_W_SCAN       2
10600 +#define MACREG_INT_CODE_LINK_LOST_NO_SCAN      3
10601 +#define MACREG_INT_CODE_LINK_SENSED            4
10602 +#define MACREG_INT_CODE_CMD_FINISHED           5
10603 +#define MACREG_INT_CODE_MIB_CHANGED            6
10604 +#define MACREG_INT_CODE_INIT_DONE              7
10605 +#define MACREG_INT_CODE_DEAUTHENTICATED                8
10606 +#define MACREG_INT_CODE_DISASSOCIATED          9
10607 +#define MACREG_INT_CODE_PS_AWAKE               10
10608 +#define MACREG_INT_CODE_PS_SLEEP               11
10609 +#define MACREG_INT_CODE_MIC_ERR_MULTICAST      13
10610 +#define MACREG_INT_CODE_MIC_ERR_UNICAST                14
10611 +#define MACREG_INT_CODE_WM_AWAKE               15
10612 +#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE       16
10613 +#define MACREG_INT_CODE_ADHOC_BCN_LOST         17
10614 +#define MACREG_INT_CODE_HOST_AWAKE             18
10615 +#define MACREG_INT_CODE_STOP_TX                        19
10616 +#define MACREG_INT_CODE_START_TX               20
10617 +#define MACREG_INT_CODE_CHANNEL_SWITCH         21
10618 +#define MACREG_INT_CODE_MEASUREMENT_RDY                22
10619 +#define MACREG_INT_CODE_WMM_CHANGE             23
10620 +#define MACREG_INT_CODE_BG_SCAN_REPORT         24
10621 +#define MACREG_INT_CODE_RSSI_LOW               25
10622 +#define MACREG_INT_CODE_SNR_LOW                        26
10623 +#define MACREG_INT_CODE_MAX_FAIL               27
10624 +#define MACREG_INT_CODE_RSSI_HIGH              28
10625 +#define MACREG_INT_CODE_SNR_HIGH               29
10626 +#define MACREG_INT_CODE_MESH_AUTO_STARTED      35
10627 +#define MACREG_INT_CODE_FIRMWARE_READY         48
10628  
10629 -#endif                         /* _HOST_H_ */
10630 +#endif
10631 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_bootcmd.c linux-2.6.22-300/drivers/net/wireless/libertas/if_bootcmd.c
10632 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_bootcmd.c 2007-07-08 19:32:17.000000000 -0400
10633 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_bootcmd.c 1969-12-31 19:00:00.000000000 -0500
10634 @@ -1,40 +0,0 @@
10635 -/**
10636 -  * This file contains functions used in USB Boot command
10637 -  * and Boot2/FW update
10638 -  */
10639 -
10640 -#include <linux/delay.h>
10641 -#include <linux/firmware.h>
10642 -#include <linux/netdevice.h>
10643 -#include <linux/usb.h>
10644 -
10645 -#define DRV_NAME "usb8xxx"
10646 -
10647 -#include "defs.h"
10648 -#include "dev.h"
10649 -#include "if_usb.h"
10650 -
10651 -/**
10652 - *  @brief This function issues Boot command to the Boot2 code
10653 - *  @param ivalue   1:Boot from FW by USB-Download
10654 - *                  2:Boot from FW in EEPROM
10655 - *  @return            0
10656 - */
10657 -int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
10658 -{
10659 -       struct usb_card_rec     *cardp = priv->card;
10660 -       struct bootcmdstr       sbootcmd;
10661 -       int i;
10662 -
10663 -       /* Prepare command */
10664 -       sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
10665 -       sbootcmd.u8cmd_tag = ivalue;
10666 -       for (i=0; i<11; i++)
10667 -               sbootcmd.au8dumy[i]=0x00;
10668 -       memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
10669 -
10670 -       /* Issue command */
10671 -       usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
10672 -
10673 -       return 0;
10674 -}
10675 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_cs.c linux-2.6.22-300/drivers/net/wireless/libertas/if_cs.c
10676 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_cs.c      1969-12-31 19:00:00.000000000 -0500
10677 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_cs.c      2008-06-05 18:10:06.000000000 -0400
10678 @@ -0,0 +1,965 @@
10679 +/*
10680 +
10681 +  Driver for the Marvell 8385 based compact flash WLAN cards.
10682 +
10683 +  (C) 2007 by Holger Schurig <hs4233@mail.mn-solutions.de>
10684 +
10685 +  This program is free software; you can redistribute it and/or modify
10686 +  it under the terms of the GNU General Public License as published by
10687 +  the Free Software Foundation; either version 2 of the License, or
10688 +  (at your option) any later version.
10689 +
10690 +  This program is distributed in the hope that it will be useful,
10691 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
10692 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10693 +  GNU General Public License for more details.
10694 +
10695 +  You should have received a copy of the GNU General Public License
10696 +  along with this program; see the file COPYING.  If not, write to
10697 +  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
10698 +  Boston, MA 02110-1301, USA.
10699 +
10700 +*/
10701 +
10702 +#include <linux/module.h>
10703 +#include <linux/delay.h>
10704 +#include <linux/moduleparam.h>
10705 +#include <linux/firmware.h>
10706 +#include <linux/netdevice.h>
10707 +
10708 +#include <pcmcia/cs_types.h>
10709 +#include <pcmcia/cs.h>
10710 +#include <pcmcia/cistpl.h>
10711 +#include <pcmcia/ds.h>
10712 +
10713 +#include <linux/io.h>
10714 +
10715 +#define DRV_NAME "libertas_cs"
10716 +
10717 +#include "decl.h"
10718 +#include "defs.h"
10719 +#include "dev.h"
10720 +
10721 +
10722 +/********************************************************************/
10723 +/* Module stuff                                                     */
10724 +/********************************************************************/
10725 +
10726 +MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
10727 +MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
10728 +MODULE_LICENSE("GPL");
10729 +
10730 +
10731 +
10732 +/********************************************************************/
10733 +/* Data structures                                                  */
10734 +/********************************************************************/
10735 +
10736 +struct if_cs_card {
10737 +       struct pcmcia_device *p_dev;
10738 +       struct lbs_private *priv;
10739 +       void __iomem *iobase;
10740 +};
10741 +
10742 +
10743 +
10744 +/********************************************************************/
10745 +/* Hardware access                                                  */
10746 +/********************************************************************/
10747 +
10748 +/* This define enables wrapper functions which allow you
10749 +   to dump all register accesses. You normally won't this,
10750 +   except for development */
10751 +/* #define DEBUG_IO */
10752 +
10753 +#ifdef DEBUG_IO
10754 +static int debug_output = 0;
10755 +#else
10756 +/* This way the compiler optimizes the printk's away */
10757 +#define debug_output 0
10758 +#endif
10759 +
10760 +static inline unsigned int if_cs_read8(struct if_cs_card *card, uint reg)
10761 +{
10762 +       unsigned int val = ioread8(card->iobase + reg);
10763 +       if (debug_output)
10764 +               printk(KERN_INFO "##inb %08x<%02x\n", reg, val);
10765 +       return val;
10766 +}
10767 +static inline unsigned int if_cs_read16(struct if_cs_card *card, uint reg)
10768 +{
10769 +       unsigned int val = ioread16(card->iobase + reg);
10770 +       if (debug_output)
10771 +               printk(KERN_INFO "##inw %08x<%04x\n", reg, val);
10772 +       return val;
10773 +}
10774 +static inline void if_cs_read16_rep(
10775 +       struct if_cs_card *card,
10776 +       uint reg,
10777 +       void *buf,
10778 +       unsigned long count)
10779 +{
10780 +       if (debug_output)
10781 +               printk(KERN_INFO "##insw %08x<(0x%lx words)\n",
10782 +                       reg, count);
10783 +       ioread16_rep(card->iobase + reg, buf, count);
10784 +}
10785 +
10786 +static inline void if_cs_write8(struct if_cs_card *card, uint reg, u8 val)
10787 +{
10788 +       if (debug_output)
10789 +               printk(KERN_INFO "##outb %08x>%02x\n", reg, val);
10790 +       iowrite8(val, card->iobase + reg);
10791 +}
10792 +
10793 +static inline void if_cs_write16(struct if_cs_card *card, uint reg, u16 val)
10794 +{
10795 +       if (debug_output)
10796 +               printk(KERN_INFO "##outw %08x>%04x\n", reg, val);
10797 +       iowrite16(val, card->iobase + reg);
10798 +}
10799 +
10800 +static inline void if_cs_write16_rep(
10801 +       struct if_cs_card *card,
10802 +       uint reg,
10803 +       void *buf,
10804 +       unsigned long count)
10805 +{
10806 +       if (debug_output)
10807 +               printk(KERN_INFO "##outsw %08x>(0x%lx words)\n",
10808 +                       reg, count);
10809 +       iowrite16_rep(card->iobase + reg, buf, count);
10810 +}
10811 +
10812 +
10813 +/*
10814 + * I know that polling/delaying is frowned upon. However, this procedure
10815 + * with polling is needed while downloading the firmware. At this stage,
10816 + * the hardware does unfortunately not create any interrupts.
10817 + *
10818 + * Fortunately, this function is never used once the firmware is in
10819 + * the card. :-)
10820 + *
10821 + * As a reference, see the "Firmware Specification v5.1", page 18
10822 + * and 19. I did not follow their suggested timing to the word,
10823 + * but this works nice & fast anyway.
10824 + */
10825 +static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 reg)
10826 +{
10827 +       int i;
10828 +
10829 +       for (i = 0; i < 1000; i++) {
10830 +               u8 val = if_cs_read8(card, addr);
10831 +               if (val == reg)
10832 +                       return i;
10833 +               udelay(500);
10834 +       }
10835 +       return -ETIME;
10836 +}
10837 +
10838 +
10839 +
10840 +/* Host control registers and their bit definitions */
10841 +
10842 +#define IF_CS_H_STATUS                 0x00000000
10843 +#define IF_CS_H_STATUS_TX_OVER         0x0001
10844 +#define IF_CS_H_STATUS_RX_OVER         0x0002
10845 +#define IF_CS_H_STATUS_DNLD_OVER       0x0004
10846 +
10847 +#define IF_CS_H_INT_CAUSE              0x00000002
10848 +#define IF_CS_H_IC_TX_OVER             0x0001
10849 +#define IF_CS_H_IC_RX_OVER             0x0002
10850 +#define IF_CS_H_IC_DNLD_OVER           0x0004
10851 +#define IF_CS_H_IC_POWER_DOWN          0x0008
10852 +#define IF_CS_H_IC_HOST_EVENT          0x0010
10853 +#define IF_CS_H_IC_MASK                        0x001f
10854 +
10855 +#define IF_CS_H_INT_MASK               0x00000004
10856 +#define        IF_CS_H_IM_MASK                 0x001f
10857 +
10858 +#define IF_CS_H_WRITE_LEN              0x00000014
10859 +
10860 +#define IF_CS_H_WRITE                  0x00000016
10861 +
10862 +#define IF_CS_H_CMD_LEN                        0x00000018
10863 +
10864 +#define IF_CS_H_CMD                    0x0000001A
10865 +
10866 +#define IF_CS_C_READ_LEN               0x00000024
10867 +
10868 +#define IF_CS_H_READ                   0x00000010
10869 +
10870 +/* Card control registers and their bit definitions */
10871 +
10872 +#define IF_CS_C_STATUS                 0x00000020
10873 +#define IF_CS_C_S_TX_DNLD_RDY          0x0001
10874 +#define IF_CS_C_S_RX_UPLD_RDY          0x0002
10875 +#define IF_CS_C_S_CMD_DNLD_RDY         0x0004
10876 +#define IF_CS_C_S_CMD_UPLD_RDY         0x0008
10877 +#define IF_CS_C_S_CARDEVENT            0x0010
10878 +#define IF_CS_C_S_MASK                 0x001f
10879 +#define IF_CS_C_S_STATUS_MASK          0x7f00
10880 +/* The following definitions should be the same as the MRVDRV_ ones */
10881 +
10882 +#if MRVDRV_CMD_DNLD_RDY != IF_CS_C_S_CMD_DNLD_RDY
10883 +#error MRVDRV_CMD_DNLD_RDY and IF_CS_C_S_CMD_DNLD_RDY not in sync
10884 +#endif
10885 +#if MRVDRV_CMD_UPLD_RDY != IF_CS_C_S_CMD_UPLD_RDY
10886 +#error MRVDRV_CMD_UPLD_RDY and IF_CS_C_S_CMD_UPLD_RDY not in sync
10887 +#endif
10888 +#if MRVDRV_CARDEVENT != IF_CS_C_S_CARDEVENT
10889 +#error MRVDRV_CARDEVENT and IF_CS_C_S_CARDEVENT not in sync
10890 +#endif
10891 +
10892 +#define IF_CS_C_INT_CAUSE              0x00000022
10893 +#define        IF_CS_C_IC_MASK                 0x001f
10894 +
10895 +#define IF_CS_C_SQ_READ_LOW            0x00000028
10896 +#define IF_CS_C_SQ_HELPER_OK           0x10
10897 +
10898 +#define IF_CS_C_CMD_LEN                        0x00000030
10899 +
10900 +#define IF_CS_C_CMD                    0x00000012
10901 +
10902 +#define IF_CS_SCRATCH                  0x0000003F
10903 +
10904 +
10905 +
10906 +/********************************************************************/
10907 +/* Interrupts                                                       */
10908 +/********************************************************************/
10909 +
10910 +static inline void if_cs_enable_ints(struct if_cs_card *card)
10911 +{
10912 +       lbs_deb_enter(LBS_DEB_CS);
10913 +       if_cs_write16(card, IF_CS_H_INT_MASK, 0);
10914 +}
10915 +
10916 +static inline void if_cs_disable_ints(struct if_cs_card *card)
10917 +{
10918 +       lbs_deb_enter(LBS_DEB_CS);
10919 +       if_cs_write16(card, IF_CS_H_INT_MASK, IF_CS_H_IM_MASK);
10920 +}
10921 +
10922 +static irqreturn_t if_cs_interrupt(int irq, void *data)
10923 +{
10924 +       struct if_cs_card *card = data;
10925 +       u16 int_cause;
10926 +
10927 +       lbs_deb_enter(LBS_DEB_CS);
10928 +
10929 +       int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
10930 +       if(int_cause == 0x0) {
10931 +               /* Not for us */
10932 +               return IRQ_NONE;
10933 +
10934 +       } else if (int_cause == 0xffff) {
10935 +               /* Read in junk, the card has probably been removed */
10936 +               card->priv->surpriseremoved = 1;
10937 +
10938 +       } else {
10939 +               if (int_cause & IF_CS_H_IC_TX_OVER)
10940 +                       lbs_host_to_card_done(card->priv);
10941 +
10942 +               /* clear interrupt */
10943 +               if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK);
10944 +       }
10945 +       spin_lock(&card->priv->driver_lock);
10946 +       lbs_interrupt(card->priv);
10947 +       spin_unlock(&card->priv->driver_lock);
10948 +
10949 +       return IRQ_HANDLED;
10950 +}
10951 +
10952 +
10953 +
10954 +
10955 +/********************************************************************/
10956 +/* I/O                                                              */
10957 +/********************************************************************/
10958 +
10959 +/*
10960 + * Called from if_cs_host_to_card to send a command to the hardware
10961 + */
10962 +static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
10963 +{
10964 +       struct if_cs_card *card = (struct if_cs_card *)priv->card;
10965 +       int ret = -1;
10966 +       int loops = 0;
10967 +
10968 +       lbs_deb_enter(LBS_DEB_CS);
10969 +
10970 +       /* Is hardware ready? */
10971 +       while (1) {
10972 +               u16 val = if_cs_read16(card, IF_CS_C_STATUS);
10973 +               if (val & IF_CS_C_S_CMD_DNLD_RDY)
10974 +                       break;
10975 +               if (++loops > 100) {
10976 +                       lbs_pr_err("card not ready for commands\n");
10977 +                       goto done;
10978 +               }
10979 +               mdelay(1);
10980 +       }
10981 +
10982 +       if_cs_write16(card, IF_CS_H_CMD_LEN, nb);
10983 +
10984 +       if_cs_write16_rep(card, IF_CS_H_CMD, buf, nb / 2);
10985 +       /* Are we supposed to transfer an odd amount of bytes? */
10986 +       if (nb & 1)
10987 +               if_cs_write8(card, IF_CS_H_CMD, buf[nb-1]);
10988 +
10989 +       /* "Assert the download over interrupt command in the Host
10990 +        * status register" */
10991 +       if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
10992 +
10993 +       /* "Assert the download over interrupt command in the Card
10994 +        * interrupt case register" */
10995 +       if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
10996 +       ret = 0;
10997 +
10998 +done:
10999 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
11000 +       return ret;
11001 +}
11002 +
11003 +
11004 +/*
11005 + * Called from if_cs_host_to_card to send a data to the hardware
11006 + */
11007 +static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb)
11008 +{
11009 +       struct if_cs_card *card = (struct if_cs_card *)priv->card;
11010 +
11011 +       lbs_deb_enter(LBS_DEB_CS);
11012 +
11013 +       if_cs_write16(card, IF_CS_H_WRITE_LEN, nb);
11014 +
11015 +       /* write even number of bytes, then odd byte if necessary */
11016 +       if_cs_write16_rep(card, IF_CS_H_WRITE, buf, nb / 2);
11017 +       if (nb & 1)
11018 +               if_cs_write8(card, IF_CS_H_WRITE, buf[nb-1]);
11019 +
11020 +       if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_TX_OVER);
11021 +       if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_STATUS_TX_OVER);
11022 +
11023 +       lbs_deb_leave(LBS_DEB_CS);
11024 +}
11025 +
11026 +
11027 +/*
11028 + * Get the command result out of the card.
11029 + */
11030 +static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
11031 +{
11032 +       int ret = -1;
11033 +       u16 val;
11034 +
11035 +       lbs_deb_enter(LBS_DEB_CS);
11036 +
11037 +       /* is hardware ready? */
11038 +       val = if_cs_read16(priv->card, IF_CS_C_STATUS);
11039 +       if ((val & IF_CS_C_S_CMD_UPLD_RDY) == 0) {
11040 +               lbs_pr_err("card not ready for CMD\n");
11041 +               goto out;
11042 +       }
11043 +
11044 +       *len = if_cs_read16(priv->card, IF_CS_C_CMD_LEN);
11045 +       if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
11046 +               lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
11047 +               goto out;
11048 +       }
11049 +
11050 +       /* read even number of bytes, then odd byte if necessary */
11051 +       if_cs_read16_rep(priv->card, IF_CS_C_CMD, data, *len/sizeof(u16));
11052 +       if (*len & 1)
11053 +               data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD);
11054 +
11055 +       /* This is a workaround for a firmware that reports too much
11056 +        * bytes */
11057 +       *len -= 8;
11058 +       ret = 0;
11059 +out:
11060 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len);
11061 +       return ret;
11062 +}
11063 +
11064 +
11065 +static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
11066 +{
11067 +       struct sk_buff *skb = NULL;
11068 +       u16 len;
11069 +       u8 *data;
11070 +
11071 +       lbs_deb_enter(LBS_DEB_CS);
11072 +
11073 +       len = if_cs_read16(priv->card, IF_CS_C_READ_LEN);
11074 +       if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
11075 +               lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
11076 +               priv->stats.rx_dropped++;
11077 +               printk(KERN_INFO "##HS %s:%d TODO\n", __FUNCTION__, __LINE__);
11078 +               goto dat_err;
11079 +       }
11080 +
11081 +       //TODO: skb = dev_alloc_skb(len+ETH_FRAME_LEN+MRVDRV_SNAP_HEADER_LEN+EXTRA_LEN);
11082 +       skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + 2);
11083 +       if (!skb)
11084 +               goto out;
11085 +       skb_put(skb, len);
11086 +       skb_reserve(skb, 2);/* 16 byte align */
11087 +       data = skb->data;
11088 +
11089 +       /* read even number of bytes, then odd byte if necessary */
11090 +       if_cs_read16_rep(priv->card, IF_CS_H_READ, data, len/sizeof(u16));
11091 +       if (len & 1)
11092 +               data[len-1] = if_cs_read8(priv->card, IF_CS_H_READ);
11093 +
11094 +dat_err:
11095 +       if_cs_write16(priv->card, IF_CS_H_STATUS, IF_CS_H_STATUS_RX_OVER);
11096 +       if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_RX_OVER);
11097 +
11098 +out:
11099 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %p", skb);
11100 +       return skb;
11101 +}
11102 +
11103 +
11104 +
11105 +/********************************************************************/
11106 +/* Firmware                                                         */
11107 +/********************************************************************/
11108 +
11109 +/*
11110 + * Tries to program the helper firmware.
11111 + *
11112 + * Return 0 on success
11113 + */
11114 +static int if_cs_prog_helper(struct if_cs_card *card)
11115 +{
11116 +       int ret = 0;
11117 +       int sent = 0;
11118 +       u8  scratch;
11119 +       const struct firmware *fw;
11120 +
11121 +       lbs_deb_enter(LBS_DEB_CS);
11122 +
11123 +       scratch = if_cs_read8(card, IF_CS_SCRATCH);
11124 +
11125 +       /* "If the value is 0x5a, the firmware is already
11126 +        * downloaded successfully"
11127 +        */
11128 +       if (scratch == 0x5a)
11129 +               goto done;
11130 +
11131 +       /* "If the value is != 00, it is invalid value of register */
11132 +       if (scratch != 0x00) {
11133 +               ret = -ENODEV;
11134 +               goto done;
11135 +       }
11136 +
11137 +       /* TODO: make firmware file configurable */
11138 +       ret = request_firmware(&fw, "libertas_cs_helper.fw",
11139 +               &handle_to_dev(card->p_dev));
11140 +       if (ret) {
11141 +               lbs_pr_err("can't load helper firmware\n");
11142 +               ret = -ENODEV;
11143 +               goto done;
11144 +       }
11145 +       lbs_deb_cs("helper size %td\n", fw->size);
11146 +
11147 +       /* "Set the 5 bytes of the helper image to 0" */
11148 +       /* Not needed, this contains an ARM branch instruction */
11149 +
11150 +       for (;;) {
11151 +               /* "the number of bytes to send is 256" */
11152 +               int count = 256;
11153 +               int remain = fw->size - sent;
11154 +
11155 +               if (remain < count)
11156 +                       count = remain;
11157 +               /* printk(KERN_INFO "//HS %d loading %d of %d bytes\n",
11158 +                       __LINE__, sent, fw->size); */
11159 +
11160 +               /* "write the number of bytes to be sent to the I/O Command
11161 +                * write length register" */
11162 +               if_cs_write16(card, IF_CS_H_CMD_LEN, count);
11163 +
11164 +               /* "write this to I/O Command port register as 16 bit writes */
11165 +               if (count)
11166 +                       if_cs_write16_rep(card, IF_CS_H_CMD,
11167 +                               &fw->data[sent],
11168 +                               count >> 1);
11169 +
11170 +               /* "Assert the download over interrupt command in the Host
11171 +                * status register" */
11172 +               if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
11173 +
11174 +               /* "Assert the download over interrupt command in the Card
11175 +                * interrupt case register" */
11176 +               if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
11177 +
11178 +               /* "The host polls the Card Status register ... for 50 ms before
11179 +                  declaring a failure */
11180 +               ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS,
11181 +                       IF_CS_C_S_CMD_DNLD_RDY);
11182 +               if (ret < 0) {
11183 +                       lbs_pr_err("can't download helper at 0x%x, ret %d\n",
11184 +                               sent, ret);
11185 +                       goto done;
11186 +               }
11187 +
11188 +               if (count == 0)
11189 +                       break;
11190 +
11191 +               sent += count;
11192 +       }
11193 +
11194 +       release_firmware(fw);
11195 +       ret = 0;
11196 +
11197 +done:
11198 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
11199 +       return ret;
11200 +}
11201 +
11202 +
11203 +static int if_cs_prog_real(struct if_cs_card *card)
11204 +{
11205 +       const struct firmware *fw;
11206 +       int ret = 0;
11207 +       int retry = 0;
11208 +       int len = 0;
11209 +       int sent;
11210 +
11211 +       lbs_deb_enter(LBS_DEB_CS);
11212 +
11213 +       /* TODO: make firmware file configurable */
11214 +       ret = request_firmware(&fw, "libertas_cs.fw",
11215 +               &handle_to_dev(card->p_dev));
11216 +       if (ret) {
11217 +               lbs_pr_err("can't load firmware\n");
11218 +               ret = -ENODEV;
11219 +               goto done;
11220 +       }
11221 +       lbs_deb_cs("fw size %td\n", fw->size);
11222 +
11223 +       ret = if_cs_poll_while_fw_download(card, IF_CS_C_SQ_READ_LOW, IF_CS_C_SQ_HELPER_OK);
11224 +       if (ret < 0) {
11225 +               int i;
11226 +               lbs_pr_err("helper firmware doesn't answer\n");
11227 +               for (i = 0; i < 0x50; i += 2)
11228 +                       printk(KERN_INFO "## HS %02x: %04x\n",
11229 +                               i, if_cs_read16(card, i));
11230 +               goto err_release;
11231 +       }
11232 +
11233 +       for (sent = 0; sent < fw->size; sent += len) {
11234 +               len = if_cs_read16(card, IF_CS_C_SQ_READ_LOW);
11235 +               /* printk(KERN_INFO "//HS %d loading %d of %d bytes\n",
11236 +                       __LINE__, sent, fw->size); */
11237 +               if (len & 1) {
11238 +                       retry++;
11239 +                       lbs_pr_info("odd, need to retry this firmware block\n");
11240 +               } else {
11241 +                       retry = 0;
11242 +               }
11243 +
11244 +               if (retry > 20) {
11245 +                       lbs_pr_err("could not download firmware\n");
11246 +                       ret = -ENODEV;
11247 +                       goto err_release;
11248 +               }
11249 +               if (retry) {
11250 +                       sent -= len;
11251 +               }
11252 +
11253 +
11254 +               if_cs_write16(card, IF_CS_H_CMD_LEN, len);
11255 +
11256 +               if_cs_write16_rep(card, IF_CS_H_CMD,
11257 +                       &fw->data[sent],
11258 +                       (len+1) >> 1);
11259 +               if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
11260 +               if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
11261 +
11262 +               ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS,
11263 +                       IF_CS_C_S_CMD_DNLD_RDY);
11264 +               if (ret < 0) {
11265 +                       lbs_pr_err("can't download firmware at 0x%x\n", sent);
11266 +                       goto err_release;
11267 +               }
11268 +       }
11269 +
11270 +       ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
11271 +       if (ret < 0) {
11272 +               lbs_pr_err("firmware download failed\n");
11273 +               goto err_release;
11274 +       }
11275 +
11276 +       ret = 0;
11277 +       goto done;
11278 +
11279 +
11280 +err_release:
11281 +       release_firmware(fw);
11282 +
11283 +done:
11284 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
11285 +       return ret;
11286 +}
11287 +
11288 +
11289 +
11290 +/********************************************************************/
11291 +/* Callback functions for libertas.ko                               */
11292 +/********************************************************************/
11293 +
11294 +/* Send commands or data packets to the card */
11295 +static int if_cs_host_to_card(struct lbs_private *priv,
11296 +       u8 type,
11297 +       u8 *buf,
11298 +       u16 nb)
11299 +{
11300 +       int ret = -1;
11301 +
11302 +       lbs_deb_enter_args(LBS_DEB_CS, "type %d, bytes %d", type, nb);
11303 +
11304 +       switch (type) {
11305 +       case MVMS_DAT:
11306 +               priv->dnld_sent = DNLD_DATA_SENT;
11307 +               if_cs_send_data(priv, buf, nb);
11308 +               ret = 0;
11309 +               break;
11310 +       case MVMS_CMD:
11311 +               priv->dnld_sent = DNLD_CMD_SENT;
11312 +               ret = if_cs_send_cmd(priv, buf, nb);
11313 +               break;
11314 +       default:
11315 +               lbs_pr_err("%s: unsupported type %d\n", __FUNCTION__, type);
11316 +       }
11317 +
11318 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
11319 +       return ret;
11320 +}
11321 +
11322 +
11323 +static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg)
11324 +{
11325 +       struct if_cs_card *card = (struct if_cs_card *)priv->card;
11326 +       int ret = 0;
11327 +       u16 int_cause;
11328 +       *ireg = 0;
11329 +
11330 +       lbs_deb_enter(LBS_DEB_CS);
11331 +
11332 +       if (priv->surpriseremoved)
11333 +               goto out;
11334 +
11335 +       int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE) & IF_CS_C_IC_MASK;
11336 +       if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause);
11337 +
11338 +       *ireg = if_cs_read16(card, IF_CS_C_STATUS) & IF_CS_C_S_MASK;
11339 +
11340 +       if (!*ireg)
11341 +               goto sbi_get_int_status_exit;
11342 +
11343 +sbi_get_int_status_exit:
11344 +
11345 +       /* is there a data packet for us? */
11346 +       if (*ireg & IF_CS_C_S_RX_UPLD_RDY) {
11347 +               struct sk_buff *skb = if_cs_receive_data(priv);
11348 +               lbs_process_rxed_packet(priv, skb);
11349 +               *ireg &= ~IF_CS_C_S_RX_UPLD_RDY;
11350 +       }
11351 +
11352 +       if (*ireg & IF_CS_C_S_TX_DNLD_RDY) {
11353 +               priv->dnld_sent = DNLD_RES_RECEIVED;
11354 +       }
11355 +
11356 +       /* Card has a command result for us */
11357 +       if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
11358 +               spin_lock(&priv->driver_lock);
11359 +               ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
11360 +               spin_unlock(&priv->driver_lock);
11361 +               if (ret < 0)
11362 +                       lbs_pr_err("could not receive cmd from card\n");
11363 +       }
11364 +
11365 +out:
11366 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->hisregcpy);
11367 +       return ret;
11368 +}
11369 +
11370 +
11371 +static int if_cs_read_event_cause(struct lbs_private *priv)
11372 +{
11373 +       lbs_deb_enter(LBS_DEB_CS);
11374 +
11375 +       priv->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5;
11376 +       if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_HOST_EVENT);
11377 +
11378 +       return 0;
11379 +}
11380 +
11381 +
11382 +
11383 +/********************************************************************/
11384 +/* Card Services                                                    */
11385 +/********************************************************************/
11386 +
11387 +/*
11388 + * After a card is removed, if_cs_release() will unregister the
11389 + * device, and release the PCMCIA configuration.  If the device is
11390 + * still open, this will be postponed until it is closed.
11391 + */
11392 +static void if_cs_release(struct pcmcia_device *p_dev)
11393 +{
11394 +       struct if_cs_card *card = p_dev->priv;
11395 +
11396 +       lbs_deb_enter(LBS_DEB_CS);
11397 +
11398 +       pcmcia_disable_device(p_dev);
11399 +       free_irq(p_dev->irq.AssignedIRQ, card);
11400 +       if (card->iobase)
11401 +               ioport_unmap(card->iobase);
11402 +
11403 +       lbs_deb_leave(LBS_DEB_CS);
11404 +}
11405 +
11406 +
11407 +/*
11408 + * This creates an "instance" of the driver, allocating local data
11409 + * structures for one device.  The device is registered with Card
11410 + * Services.
11411 + *
11412 + * The dev_link structure is initialized, but we don't actually
11413 + * configure the card at this point -- we wait until we receive a card
11414 + * insertion event.
11415 + */
11416 +static int if_cs_probe(struct pcmcia_device *p_dev)
11417 +{
11418 +       int ret = -ENOMEM;
11419 +       struct lbs_private *priv;
11420 +       struct if_cs_card *card;
11421 +       /* CIS parsing */
11422 +       tuple_t tuple;
11423 +       cisparse_t parse;
11424 +       cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
11425 +       cistpl_io_t *io = &cfg->io;
11426 +       u_char buf[64];
11427 +
11428 +       lbs_deb_enter(LBS_DEB_CS);
11429 +
11430 +       card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
11431 +       if (!card) {
11432 +               lbs_pr_err("error in kzalloc\n");
11433 +               goto out;
11434 +       }
11435 +       card->p_dev = p_dev;
11436 +       p_dev->priv = card;
11437 +
11438 +       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
11439 +       p_dev->irq.Handler = NULL;
11440 +       p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
11441 +
11442 +       p_dev->conf.Attributes = 0;
11443 +       p_dev->conf.IntType = INT_MEMORY_AND_IO;
11444 +
11445 +       tuple.Attributes = 0;
11446 +       tuple.TupleData = buf;
11447 +       tuple.TupleDataMax = sizeof(buf);
11448 +       tuple.TupleOffset = 0;
11449 +
11450 +       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
11451 +       if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
11452 +           (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
11453 +           (ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0)
11454 +       {
11455 +               lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
11456 +               goto out1;
11457 +       }
11458 +
11459 +       p_dev->conf.ConfigIndex = cfg->index;
11460 +
11461 +       /* Do we need to allocate an interrupt? */
11462 +       if (cfg->irq.IRQInfo1) {
11463 +               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
11464 +       }
11465 +
11466 +       /* IO window settings */
11467 +       if (cfg->io.nwin != 1) {
11468 +               lbs_pr_err("wrong CIS (check number of IO windows)\n");
11469 +               ret = -ENODEV;
11470 +               goto out1;
11471 +       }
11472 +       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
11473 +       p_dev->io.BasePort1 = io->win[0].base;
11474 +       p_dev->io.NumPorts1 = io->win[0].len;
11475 +
11476 +       /* This reserves IO space but doesn't actually enable it */
11477 +       ret = pcmcia_request_io(p_dev, &p_dev->io);
11478 +       if (ret) {
11479 +               lbs_pr_err("error in pcmcia_request_io\n");
11480 +               goto out1;
11481 +       }
11482 +
11483 +       /*
11484 +        * Allocate an interrupt line.  Note that this does not assign
11485 +        * a handler to the interrupt, unless the 'Handler' member of
11486 +        * the irq structure is initialized.
11487 +        */
11488 +       if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) {
11489 +               ret = pcmcia_request_irq(p_dev, &p_dev->irq);
11490 +               if (ret) {
11491 +                       lbs_pr_err("error in pcmcia_request_irq\n");
11492 +                       goto out1;
11493 +               }
11494 +       }
11495 +
11496 +       /* Initialize io access */
11497 +       card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
11498 +       if (!card->iobase) {
11499 +               lbs_pr_err("error in ioport_map\n");
11500 +               ret = -EIO;
11501 +               goto out1;
11502 +       }
11503 +
11504 +       /*
11505 +        * This actually configures the PCMCIA socket -- setting up
11506 +        * the I/O windows and the interrupt mapping, and putting the
11507 +        * card and host interface into "Memory and IO" mode.
11508 +        */
11509 +       ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
11510 +       if (ret) {
11511 +               lbs_pr_err("error in pcmcia_request_configuration\n");
11512 +               goto out2;
11513 +       }
11514 +
11515 +       /* Finally, report what we've done */
11516 +       lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n",
11517 +              p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,
11518 +              p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
11519 +
11520 +
11521 +       /* Load the firmware early, before calling into libertas.ko */
11522 +       ret = if_cs_prog_helper(card);
11523 +       if (ret == 0)
11524 +               ret = if_cs_prog_real(card);
11525 +       if (ret)
11526 +               goto out2;
11527 +
11528 +       /* Make this card known to the libertas driver */
11529 +       priv = lbs_add_card(card, &p_dev->dev);
11530 +       if (!priv) {
11531 +               ret = -ENOMEM;
11532 +               goto out2;
11533 +       }
11534 +
11535 +       /* Store pointers to our call-back functions */
11536 +       card->priv = priv;
11537 +       priv->card = card;
11538 +       priv->hw_host_to_card     = if_cs_host_to_card;
11539 +       priv->hw_get_int_status   = if_cs_get_int_status;
11540 +       priv->hw_read_event_cause = if_cs_read_event_cause;
11541 +
11542 +       priv->fw_ready = 1;
11543 +
11544 +       /* Now actually get the IRQ */
11545 +       ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
11546 +               IRQF_SHARED, DRV_NAME, card);
11547 +       if (ret) {
11548 +               lbs_pr_err("error in request_irq\n");
11549 +               goto out3;
11550 +       }
11551 +
11552 +       /* Clear any interrupt cause that happend while sending
11553 +        * firmware/initializing card */
11554 +       if_cs_write16(card, IF_CS_C_INT_CAUSE, IF_CS_C_IC_MASK);
11555 +       if_cs_enable_ints(card);
11556 +
11557 +       /* And finally bring the card up */
11558 +       if (lbs_start_card(priv) != 0) {
11559 +               lbs_pr_err("could not activate card\n");
11560 +               goto out3;
11561 +       }
11562 +
11563 +       ret = 0;
11564 +       goto out;
11565 +
11566 +out3:
11567 +       lbs_remove_card(priv);
11568 +out2:
11569 +       ioport_unmap(card->iobase);
11570 +out1:
11571 +       pcmcia_disable_device(p_dev);
11572 +out:
11573 +       lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
11574 +       return ret;
11575 +}
11576 +
11577 +
11578 +/*
11579 + * This deletes a driver "instance".  The device is de-registered with
11580 + * Card Services.  If it has been released, all local data structures
11581 + * are freed.  Otherwise, the structures will be freed when the device
11582 + * is released.
11583 + */
11584 +static void if_cs_detach(struct pcmcia_device *p_dev)
11585 +{
11586 +       struct if_cs_card *card = p_dev->priv;
11587 +
11588 +       lbs_deb_enter(LBS_DEB_CS);
11589 +
11590 +       lbs_stop_card(card->priv);
11591 +       lbs_remove_card(card->priv);
11592 +       if_cs_disable_ints(card);
11593 +       if_cs_release(p_dev);
11594 +       kfree(card);
11595 +
11596 +       lbs_deb_leave(LBS_DEB_CS);
11597 +}
11598 +
11599 +
11600 +
11601 +/********************************************************************/
11602 +/* Module initialization                                            */
11603 +/********************************************************************/
11604 +
11605 +static struct pcmcia_device_id if_cs_ids[] = {
11606 +       PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103),
11607 +       PCMCIA_DEVICE_NULL,
11608 +};
11609 +MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
11610 +
11611 +
11612 +static struct pcmcia_driver lbs_driver = {
11613 +       .owner          = THIS_MODULE,
11614 +       .drv            = {
11615 +               .name   = DRV_NAME,
11616 +       },
11617 +       .probe          = if_cs_probe,
11618 +       .remove         = if_cs_detach,
11619 +       .id_table       = if_cs_ids,
11620 +};
11621 +
11622 +
11623 +static int __init if_cs_init(void)
11624 +{
11625 +       int ret;
11626 +
11627 +       lbs_deb_enter(LBS_DEB_CS);
11628 +       ret = pcmcia_register_driver(&lbs_driver);
11629 +       lbs_deb_leave(LBS_DEB_CS);
11630 +       return ret;
11631 +}
11632 +
11633 +
11634 +static void __exit if_cs_exit(void)
11635 +{
11636 +       lbs_deb_enter(LBS_DEB_CS);
11637 +       pcmcia_unregister_driver(&lbs_driver);
11638 +       lbs_deb_leave(LBS_DEB_CS);
11639 +}
11640 +
11641 +
11642 +module_init(if_cs_init);
11643 +module_exit(if_cs_exit);
11644 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_sdio.c linux-2.6.22-300/drivers/net/wireless/libertas/if_sdio.c
11645 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_sdio.c    1969-12-31 19:00:00.000000000 -0500
11646 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_sdio.c    2008-06-05 18:10:06.000000000 -0400
11647 @@ -0,0 +1,1073 @@
11648 +/*
11649 + *  linux/drivers/net/wireless/libertas/if_sdio.c
11650 + *
11651 + *  Copyright 2007 Pierre Ossman
11652 + *
11653 + * Inspired by if_cs.c, Copyright 2007 Holger Schurig
11654 + *
11655 + * This program is free software; you can redistribute it and/or modify
11656 + * it under the terms of the GNU General Public License as published by
11657 + * the Free Software Foundation; either version 2 of the License, or (at
11658 + * your option) any later version.
11659 + *
11660 + * This hardware has more or less no CMD53 support, so all registers
11661 + * must be accessed using sdio_readb()/sdio_writeb().
11662 + *
11663 + * Transfers must be in one transaction or the firmware goes bonkers.
11664 + * This means that the transfer must either be small enough to do a
11665 + * byte based transfer or it must be padded to a multiple of the
11666 + * current block size.
11667 + *
11668 + * As SDIO is still new to the kernel, it is unfortunately common with
11669 + * bugs in the host controllers related to that. One such bug is that
11670 + * controllers cannot do transfers that aren't a multiple of 4 bytes.
11671 + * If you don't have time to fix the host controller driver, you can
11672 + * work around the problem by modifying if_sdio_host_to_card() and
11673 + * if_sdio_card_to_host() to pad the data.
11674 + */
11675 +
11676 +#include <linux/moduleparam.h>
11677 +#include <linux/firmware.h>
11678 +#include <linux/netdevice.h>
11679 +#include <linux/delay.h>
11680 +#include <linux/mmc/card.h>
11681 +#include <linux/mmc/sdio_func.h>
11682 +#include <linux/mmc/sdio_ids.h>
11683 +
11684 +#include "host.h"
11685 +#include "decl.h"
11686 +#include "defs.h"
11687 +#include "dev.h"
11688 +#include "if_sdio.h"
11689 +
11690 +static char *lbs_helper_name = NULL;
11691 +module_param_named(helper_name, lbs_helper_name, charp, 0644);
11692 +
11693 +static char *lbs_fw_name = NULL;
11694 +module_param_named(fw_name, lbs_fw_name, charp, 0644);
11695 +
11696 +static const struct sdio_device_id if_sdio_ids[] = {
11697 +       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
11698 +       { /* end: all zeroes */                                         },
11699 +};
11700 +
11701 +MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
11702 +
11703 +struct if_sdio_model {
11704 +       int model;
11705 +       const char *helper;
11706 +       const char *firmware;
11707 +};
11708 +
11709 +static struct if_sdio_model if_sdio_models[] = {
11710 +       {
11711 +               /* 8385 */
11712 +               .model = 0x04,
11713 +               .helper = "sd8385_helper.bin",
11714 +               .firmware = "sd8385.bin",
11715 +       },
11716 +       {
11717 +               /* 8686 */
11718 +               .model = 0x0B,
11719 +               .helper = "sd8686_helper.bin",
11720 +               .firmware = "sd8686.bin",
11721 +       },
11722 +};
11723 +
11724 +struct if_sdio_packet {
11725 +       struct if_sdio_packet   *next;
11726 +       u16                     nb;
11727 +       u8                      buffer[0] __attribute__((aligned(4)));
11728 +};
11729 +
11730 +struct if_sdio_card {
11731 +       struct sdio_func        *func;
11732 +       struct lbs_private      *priv;
11733 +
11734 +       int                     model;
11735 +       unsigned long           ioport;
11736 +
11737 +       const char              *helper;
11738 +       const char              *firmware;
11739 +
11740 +       u8                      buffer[65536];
11741 +       u8                      int_cause;
11742 +       u32                     event;
11743 +
11744 +       spinlock_t              lock;
11745 +       struct if_sdio_packet   *packets;
11746 +       struct work_struct      packet_worker;
11747 +};
11748 +
11749 +/********************************************************************/
11750 +/* I/O                                                              */
11751 +/********************************************************************/
11752 +
11753 +static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
11754 +{
11755 +       int ret, reg;
11756 +       u16 scratch;
11757 +
11758 +       if (card->model == 0x04)
11759 +               reg = IF_SDIO_SCRATCH_OLD;
11760 +       else
11761 +               reg = IF_SDIO_SCRATCH;
11762 +
11763 +       scratch = sdio_readb(card->func, reg, &ret);
11764 +       if (!ret)
11765 +               scratch |= sdio_readb(card->func, reg + 1, &ret) << 8;
11766 +
11767 +       if (err)
11768 +               *err = ret;
11769 +
11770 +       if (ret)
11771 +               return 0xffff;
11772 +
11773 +       return scratch;
11774 +}
11775 +
11776 +static int if_sdio_handle_cmd(struct if_sdio_card *card,
11777 +               u8 *buffer, unsigned size)
11778 +{
11779 +       int ret;
11780 +       unsigned long flags;
11781 +
11782 +       lbs_deb_enter(LBS_DEB_SDIO);
11783 +
11784 +       spin_lock_irqsave(&card->priv->driver_lock, flags);
11785 +
11786 +       if (size > LBS_CMD_BUFFER_SIZE) {
11787 +               lbs_deb_sdio("response packet too large (%d bytes)\n",
11788 +                       (int)size);
11789 +               ret = -E2BIG;
11790 +               goto out;
11791 +       }
11792 +
11793 +       memcpy(card->priv->upld_buf, buffer, size);
11794 +       card->priv->upld_len = size;
11795 +
11796 +       card->int_cause |= MRVDRV_CMD_UPLD_RDY;
11797 +
11798 +       lbs_interrupt(card->priv);
11799 +
11800 +       ret = 0;
11801 +
11802 +out:
11803 +       spin_unlock_irqrestore(&card->priv->driver_lock, flags);
11804 +
11805 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
11806 +
11807 +       return ret;
11808 +}
11809 +
11810 +static int if_sdio_handle_data(struct if_sdio_card *card,
11811 +               u8 *buffer, unsigned size)
11812 +{
11813 +       int ret;
11814 +       struct sk_buff *skb;
11815 +       char *data;
11816 +
11817 +       lbs_deb_enter(LBS_DEB_SDIO);
11818 +
11819 +       if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
11820 +               lbs_deb_sdio("response packet too large (%d bytes)\n",
11821 +                       (int)size);
11822 +               ret = -E2BIG;
11823 +               goto out;
11824 +       }
11825 +
11826 +       skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN);
11827 +       if (!skb) {
11828 +               ret = -ENOMEM;
11829 +               goto out;
11830 +       }
11831 +
11832 +       skb_reserve(skb, NET_IP_ALIGN);
11833 +
11834 +       data = skb_put(skb, size);
11835 +
11836 +       memcpy(data, buffer, size);
11837 +
11838 +       lbs_process_rxed_packet(card->priv, skb);
11839 +
11840 +       ret = 0;
11841 +
11842 +out:
11843 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
11844 +
11845 +       return ret;
11846 +}
11847 +
11848 +static int if_sdio_handle_event(struct if_sdio_card *card,
11849 +               u8 *buffer, unsigned size)
11850 +{
11851 +       int ret;
11852 +       unsigned long flags;
11853 +       u32 event;
11854 +
11855 +       lbs_deb_enter(LBS_DEB_SDIO);
11856 +
11857 +       if (card->model == 0x04) {
11858 +               event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
11859 +               if (ret)
11860 +                       goto out;
11861 +       } else {
11862 +               if (size < 4) {
11863 +                       lbs_deb_sdio("event packet too small (%d bytes)\n",
11864 +                               (int)size);
11865 +                       ret = -EINVAL;
11866 +                       goto out;
11867 +               }
11868 +               event = buffer[3] << 24;
11869 +               event |= buffer[2] << 16;
11870 +               event |= buffer[1] << 8;
11871 +               event |= buffer[0] << 0;
11872 +               event <<= SBI_EVENT_CAUSE_SHIFT;
11873 +       }
11874 +
11875 +       spin_lock_irqsave(&card->priv->driver_lock, flags);
11876 +
11877 +       card->event = event;
11878 +       card->int_cause |= MRVDRV_CARDEVENT;
11879 +
11880 +       lbs_interrupt(card->priv);
11881 +
11882 +       spin_unlock_irqrestore(&card->priv->driver_lock, flags);
11883 +
11884 +       ret = 0;
11885 +
11886 +out:
11887 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
11888 +
11889 +       return ret;
11890 +}
11891 +
11892 +static int if_sdio_card_to_host(struct if_sdio_card *card)
11893 +{
11894 +       int ret;
11895 +       u8 status;
11896 +       u16 size, type, chunk;
11897 +       unsigned long timeout;
11898 +
11899 +       lbs_deb_enter(LBS_DEB_SDIO);
11900 +
11901 +       size = if_sdio_read_scratch(card, &ret);
11902 +       if (ret)
11903 +               goto out;
11904 +
11905 +       if (size < 4) {
11906 +               lbs_deb_sdio("invalid packet size (%d bytes) from firmware\n",
11907 +                       (int)size);
11908 +               ret = -EINVAL;
11909 +               goto out;
11910 +       }
11911 +
11912 +       timeout = jiffies + HZ;
11913 +       while (1) {
11914 +               status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
11915 +               if (ret)
11916 +                       goto out;
11917 +               if (status & IF_SDIO_IO_RDY)
11918 +                       break;
11919 +               if (time_after(jiffies, timeout)) {
11920 +                       ret = -ETIMEDOUT;
11921 +                       goto out;
11922 +               }
11923 +               mdelay(1);
11924 +       }
11925 +
11926 +       /*
11927 +        * The transfer must be in one transaction or the firmware
11928 +        * goes suicidal.
11929 +        */
11930 +       chunk = size;
11931 +       if ((chunk > card->func->cur_blksize) || (chunk > 512)) {
11932 +               chunk = (chunk + card->func->cur_blksize - 1) /
11933 +                       card->func->cur_blksize * card->func->cur_blksize;
11934 +       }
11935 +
11936 +       ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk);
11937 +       if (ret)
11938 +               goto out;
11939 +
11940 +       chunk = card->buffer[0] | (card->buffer[1] << 8);
11941 +       type = card->buffer[2] | (card->buffer[3] << 8);
11942 +
11943 +       lbs_deb_sdio("packet of type %d and size %d bytes\n",
11944 +               (int)type, (int)chunk);
11945 +
11946 +       if (chunk > size) {
11947 +               lbs_deb_sdio("packet fragment (%d > %d)\n",
11948 +                       (int)chunk, (int)size);
11949 +               ret = -EINVAL;
11950 +               goto out;
11951 +       }
11952 +
11953 +       if (chunk < size) {
11954 +               lbs_deb_sdio("packet fragment (%d < %d)\n",
11955 +                       (int)chunk, (int)size);
11956 +       }
11957 +
11958 +       switch (type) {
11959 +       case MVMS_CMD:
11960 +               ret = if_sdio_handle_cmd(card, card->buffer + 4, chunk - 4);
11961 +               if (ret)
11962 +                       goto out;
11963 +               break;
11964 +       case MVMS_DAT:
11965 +               ret = if_sdio_handle_data(card, card->buffer + 4, chunk - 4);
11966 +               if (ret)
11967 +                       goto out;
11968 +               break;
11969 +       case MVMS_EVENT:
11970 +               ret = if_sdio_handle_event(card, card->buffer + 4, chunk - 4);
11971 +               if (ret)
11972 +                       goto out;
11973 +               break;
11974 +       default:
11975 +               lbs_deb_sdio("invalid type (%d) from firmware\n",
11976 +                               (int)type);
11977 +               ret = -EINVAL;
11978 +               goto out;
11979 +       }
11980 +
11981 +out:
11982 +       if (ret)
11983 +               lbs_pr_err("problem fetching packet from firmware\n");
11984 +
11985 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
11986 +
11987 +       return ret;
11988 +}
11989 +
11990 +static void if_sdio_host_to_card_worker(struct work_struct *work)
11991 +{
11992 +       struct if_sdio_card *card;
11993 +       struct if_sdio_packet *packet;
11994 +       unsigned long timeout;
11995 +       u8 status;
11996 +       int ret;
11997 +       unsigned long flags;
11998 +
11999 +       lbs_deb_enter(LBS_DEB_SDIO);
12000 +
12001 +       card = container_of(work, struct if_sdio_card, packet_worker);
12002 +
12003 +       while (1) {
12004 +               spin_lock_irqsave(&card->lock, flags);
12005 +               packet = card->packets;
12006 +               if (packet)
12007 +                       card->packets = packet->next;
12008 +               spin_unlock_irqrestore(&card->lock, flags);
12009 +
12010 +               if (!packet)
12011 +                       break;
12012 +
12013 +               sdio_claim_host(card->func);
12014 +
12015 +               timeout = jiffies + HZ;
12016 +               while (1) {
12017 +                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
12018 +                       if (ret)
12019 +                               goto release;
12020 +                       if (status & IF_SDIO_IO_RDY)
12021 +                               break;
12022 +                       if (time_after(jiffies, timeout)) {
12023 +                               ret = -ETIMEDOUT;
12024 +                               goto release;
12025 +                       }
12026 +                       mdelay(1);
12027 +               }
12028 +
12029 +               ret = sdio_writesb(card->func, card->ioport,
12030 +                               packet->buffer, packet->nb);
12031 +               if (ret)
12032 +                       goto release;
12033 +release:
12034 +               sdio_release_host(card->func);
12035 +
12036 +               kfree(packet);
12037 +       }
12038 +
12039 +       lbs_deb_leave(LBS_DEB_SDIO);
12040 +}
12041 +
12042 +/********************************************************************/
12043 +/* Firmware                                                         */
12044 +/********************************************************************/
12045 +
12046 +static int if_sdio_prog_helper(struct if_sdio_card *card)
12047 +{
12048 +       int ret;
12049 +       u8 status;
12050 +       const struct firmware *fw;
12051 +       unsigned long timeout;
12052 +       u8 *chunk_buffer;
12053 +       u32 chunk_size;
12054 +       u8 *firmware;
12055 +       size_t size;
12056 +
12057 +       lbs_deb_enter(LBS_DEB_SDIO);
12058 +
12059 +       ret = request_firmware(&fw, card->helper, &card->func->dev);
12060 +       if (ret) {
12061 +               lbs_pr_err("can't load helper firmware\n");
12062 +               goto out;
12063 +       }
12064 +
12065 +       chunk_buffer = kzalloc(64, GFP_KERNEL);
12066 +       if (!chunk_buffer) {
12067 +               ret = -ENOMEM;
12068 +               goto release_fw;
12069 +       }
12070 +
12071 +       sdio_claim_host(card->func);
12072 +
12073 +       ret = sdio_set_block_size(card->func, 32);
12074 +       if (ret)
12075 +               goto release;
12076 +
12077 +       firmware = fw->data;
12078 +       size = fw->size;
12079 +
12080 +       while (size) {
12081 +               timeout = jiffies + HZ;
12082 +               while (1) {
12083 +                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
12084 +                       if (ret)
12085 +                               goto release;
12086 +                       if ((status & IF_SDIO_IO_RDY) &&
12087 +                                       (status & IF_SDIO_DL_RDY))
12088 +                               break;
12089 +                       if (time_after(jiffies, timeout)) {
12090 +                               ret = -ETIMEDOUT;
12091 +                               goto release;
12092 +                       }
12093 +                       mdelay(1);
12094 +               }
12095 +
12096 +               chunk_size = min(size, (size_t)60);
12097 +
12098 +               *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size);
12099 +               memcpy(chunk_buffer + 4, firmware, chunk_size);
12100 +/*
12101 +               lbs_deb_sdio("sending %d bytes chunk\n", chunk_size);
12102 +*/
12103 +               ret = sdio_writesb(card->func, card->ioport,
12104 +                               chunk_buffer, 64);
12105 +               if (ret)
12106 +                       goto release;
12107 +
12108 +               firmware += chunk_size;
12109 +               size -= chunk_size;
12110 +       }
12111 +
12112 +       /* an empty block marks the end of the transfer */
12113 +       memset(chunk_buffer, 0, 4);
12114 +       ret = sdio_writesb(card->func, card->ioport, chunk_buffer, 64);
12115 +       if (ret)
12116 +               goto release;
12117 +
12118 +       lbs_deb_sdio("waiting for helper to boot...\n");
12119 +
12120 +       /* wait for the helper to boot by looking at the size register */
12121 +       timeout = jiffies + HZ;
12122 +       while (1) {
12123 +               u16 req_size;
12124 +
12125 +               req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
12126 +               if (ret)
12127 +                       goto release;
12128 +
12129 +               req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
12130 +               if (ret)
12131 +                       goto release;
12132 +
12133 +               if (req_size != 0)
12134 +                       break;
12135 +
12136 +               if (time_after(jiffies, timeout)) {
12137 +                       ret = -ETIMEDOUT;
12138 +                       goto release;
12139 +               }
12140 +
12141 +               msleep(10);
12142 +       }
12143 +
12144 +       ret = 0;
12145 +
12146 +release:
12147 +       sdio_set_block_size(card->func, 0);
12148 +       sdio_release_host(card->func);
12149 +       kfree(chunk_buffer);
12150 +release_fw:
12151 +       release_firmware(fw);
12152 +
12153 +out:
12154 +       if (ret)
12155 +               lbs_pr_err("failed to load helper firmware\n");
12156 +
12157 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12158 +
12159 +       return ret;
12160 +}
12161 +
12162 +static int if_sdio_prog_real(struct if_sdio_card *card)
12163 +{
12164 +       int ret;
12165 +       u8 status;
12166 +       const struct firmware *fw;
12167 +       unsigned long timeout;
12168 +       u8 *chunk_buffer;
12169 +       u32 chunk_size;
12170 +       u8 *firmware;
12171 +       size_t size, req_size;
12172 +
12173 +       lbs_deb_enter(LBS_DEB_SDIO);
12174 +
12175 +       ret = request_firmware(&fw, card->firmware, &card->func->dev);
12176 +       if (ret) {
12177 +               lbs_pr_err("can't load firmware\n");
12178 +               goto out;
12179 +       }
12180 +
12181 +       chunk_buffer = kzalloc(512, GFP_KERNEL);
12182 +       if (!chunk_buffer) {
12183 +               ret = -ENOMEM;
12184 +               goto release_fw;
12185 +       }
12186 +
12187 +       sdio_claim_host(card->func);
12188 +
12189 +       ret = sdio_set_block_size(card->func, 32);
12190 +       if (ret)
12191 +               goto release;
12192 +
12193 +       firmware = fw->data;
12194 +       size = fw->size;
12195 +
12196 +       while (size) {
12197 +               timeout = jiffies + HZ;
12198 +               while (1) {
12199 +                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
12200 +                       if (ret)
12201 +                               goto release;
12202 +                       if ((status & IF_SDIO_IO_RDY) &&
12203 +                                       (status & IF_SDIO_DL_RDY))
12204 +                               break;
12205 +                       if (time_after(jiffies, timeout)) {
12206 +                               ret = -ETIMEDOUT;
12207 +                               goto release;
12208 +                       }
12209 +                       mdelay(1);
12210 +               }
12211 +
12212 +               req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
12213 +               if (ret)
12214 +                       goto release;
12215 +
12216 +               req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
12217 +               if (ret)
12218 +                       goto release;
12219 +/*
12220 +               lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size);
12221 +*/
12222 +               if (req_size == 0) {
12223 +                       lbs_deb_sdio("firmware helper gave up early\n");
12224 +                       ret = -EIO;
12225 +                       goto release;
12226 +               }
12227 +
12228 +               if (req_size & 0x01) {
12229 +                       lbs_deb_sdio("firmware helper signalled error\n");
12230 +                       ret = -EIO;
12231 +                       goto release;
12232 +               }
12233 +
12234 +               if (req_size > size)
12235 +                       req_size = size;
12236 +
12237 +               while (req_size) {
12238 +                       chunk_size = min(req_size, (size_t)512);
12239 +
12240 +                       memcpy(chunk_buffer, firmware, chunk_size);
12241 +/*
12242 +                       lbs_deb_sdio("sending %d bytes (%d bytes) chunk\n",
12243 +                               chunk_size, (chunk_size + 31) / 32 * 32);
12244 +*/
12245 +                       ret = sdio_writesb(card->func, card->ioport,
12246 +                               chunk_buffer, (chunk_size + 31) / 32 * 32);
12247 +                       if (ret)
12248 +                               goto release;
12249 +
12250 +                       firmware += chunk_size;
12251 +                       size -= chunk_size;
12252 +                       req_size -= chunk_size;
12253 +               }
12254 +       }
12255 +
12256 +       ret = 0;
12257 +
12258 +       lbs_deb_sdio("waiting for firmware to boot...\n");
12259 +
12260 +       /* wait for the firmware to boot */
12261 +       timeout = jiffies + HZ;
12262 +       while (1) {
12263 +               u16 scratch;
12264 +
12265 +               scratch = if_sdio_read_scratch(card, &ret);
12266 +               if (ret)
12267 +                       goto release;
12268 +
12269 +               if (scratch == IF_SDIO_FIRMWARE_OK)
12270 +                       break;
12271 +
12272 +               if (time_after(jiffies, timeout)) {
12273 +                       ret = -ETIMEDOUT;
12274 +                       goto release;
12275 +               }
12276 +
12277 +               msleep(10);
12278 +       }
12279 +
12280 +       ret = 0;
12281 +
12282 +release:
12283 +       sdio_set_block_size(card->func, 0);
12284 +       sdio_release_host(card->func);
12285 +       kfree(chunk_buffer);
12286 +release_fw:
12287 +       release_firmware(fw);
12288 +
12289 +out:
12290 +       if (ret)
12291 +               lbs_pr_err("failed to load firmware\n");
12292 +
12293 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12294 +
12295 +       return ret;
12296 +}
12297 +
12298 +static int if_sdio_prog_firmware(struct if_sdio_card *card)
12299 +{
12300 +       int ret;
12301 +       u16 scratch;
12302 +
12303 +       lbs_deb_enter(LBS_DEB_SDIO);
12304 +
12305 +       sdio_claim_host(card->func);
12306 +       scratch = if_sdio_read_scratch(card, &ret);
12307 +       sdio_release_host(card->func);
12308 +
12309 +       if (ret)
12310 +               goto out;
12311 +
12312 +       if (scratch == IF_SDIO_FIRMWARE_OK) {
12313 +               lbs_deb_sdio("firmware already loaded\n");
12314 +               goto success;
12315 +       }
12316 +
12317 +       ret = if_sdio_prog_helper(card);
12318 +       if (ret)
12319 +               goto out;
12320 +
12321 +       ret = if_sdio_prog_real(card);
12322 +       if (ret)
12323 +               goto out;
12324 +
12325 +success:
12326 +       ret = 0;
12327 +
12328 +out:
12329 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12330 +
12331 +       return ret;
12332 +}
12333 +
12334 +/*******************************************************************/
12335 +/* Libertas callbacks                                              */
12336 +/*******************************************************************/
12337 +
12338 +static int if_sdio_host_to_card(struct lbs_private *priv,
12339 +               u8 type, u8 *buf, u16 nb)
12340 +{
12341 +       int ret;
12342 +       struct if_sdio_card *card;
12343 +       struct if_sdio_packet *packet, *cur;
12344 +       u16 size;
12345 +       unsigned long flags;
12346 +
12347 +       lbs_deb_enter_args(LBS_DEB_SDIO, "type %d, bytes %d", type, nb);
12348 +
12349 +       card = priv->card;
12350 +
12351 +       if (nb > (65536 - sizeof(struct if_sdio_packet) - 4)) {
12352 +               ret = -EINVAL;
12353 +               goto out;
12354 +       }
12355 +
12356 +       /*
12357 +        * The transfer must be in one transaction or the firmware
12358 +        * goes suicidal.
12359 +        */
12360 +       size = nb + 4;
12361 +       if ((size > card->func->cur_blksize) || (size > 512)) {
12362 +               size = (size + card->func->cur_blksize - 1) /
12363 +                       card->func->cur_blksize * card->func->cur_blksize;
12364 +       }
12365 +
12366 +       packet = kzalloc(sizeof(struct if_sdio_packet) + size,
12367 +                       GFP_ATOMIC);
12368 +       if (!packet) {
12369 +               ret = -ENOMEM;
12370 +               goto out;
12371 +       }
12372 +
12373 +       packet->next = NULL;
12374 +       packet->nb = size;
12375 +
12376 +       /*
12377 +        * SDIO specific header.
12378 +        */
12379 +       packet->buffer[0] = (nb + 4) & 0xff;
12380 +       packet->buffer[1] = ((nb + 4) >> 8) & 0xff;
12381 +       packet->buffer[2] = type;
12382 +       packet->buffer[3] = 0;
12383 +
12384 +       memcpy(packet->buffer + 4, buf, nb);
12385 +
12386 +       spin_lock_irqsave(&card->lock, flags);
12387 +
12388 +       if (!card->packets)
12389 +               card->packets = packet;
12390 +       else {
12391 +               cur = card->packets;
12392 +               while (cur->next)
12393 +                       cur = cur->next;
12394 +               cur->next = packet;
12395 +       }
12396 +
12397 +       switch (type) {
12398 +       case MVMS_CMD:
12399 +               priv->dnld_sent = DNLD_CMD_SENT;
12400 +               break;
12401 +       case MVMS_DAT:
12402 +               priv->dnld_sent = DNLD_DATA_SENT;
12403 +               break;
12404 +       default:
12405 +               lbs_deb_sdio("unknown packet type %d\n", (int)type);
12406 +       }
12407 +
12408 +       spin_unlock_irqrestore(&card->lock, flags);
12409 +
12410 +       schedule_work(&card->packet_worker);
12411 +
12412 +       ret = 0;
12413 +
12414 +out:
12415 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12416 +
12417 +       return ret;
12418 +}
12419 +
12420 +static int if_sdio_get_int_status(struct lbs_private *priv, u8 *ireg)
12421 +{
12422 +       struct if_sdio_card *card;
12423 +
12424 +       lbs_deb_enter(LBS_DEB_SDIO);
12425 +
12426 +       card = priv->card;
12427 +
12428 +       *ireg = card->int_cause;
12429 +       card->int_cause = 0;
12430 +
12431 +       lbs_deb_leave(LBS_DEB_SDIO);
12432 +
12433 +       return 0;
12434 +}
12435 +
12436 +static int if_sdio_read_event_cause(struct lbs_private *priv)
12437 +{
12438 +       struct if_sdio_card *card;
12439 +
12440 +       lbs_deb_enter(LBS_DEB_SDIO);
12441 +
12442 +       card = priv->card;
12443 +
12444 +       priv->eventcause = card->event;
12445 +
12446 +       lbs_deb_leave(LBS_DEB_SDIO);
12447 +
12448 +       return 0;
12449 +}
12450 +
12451 +/*******************************************************************/
12452 +/* SDIO callbacks                                                  */
12453 +/*******************************************************************/
12454 +
12455 +static void if_sdio_interrupt(struct sdio_func *func)
12456 +{
12457 +       int ret;
12458 +       struct if_sdio_card *card;
12459 +       u8 cause;
12460 +
12461 +       lbs_deb_enter(LBS_DEB_SDIO);
12462 +
12463 +       card = sdio_get_drvdata(func);
12464 +
12465 +       cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
12466 +       if (ret)
12467 +               goto out;
12468 +
12469 +       lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
12470 +
12471 +       sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret);
12472 +       if (ret)
12473 +               goto out;
12474 +
12475 +       /*
12476 +        * Ignore the define name, this really means the card has
12477 +        * successfully received the command.
12478 +        */
12479 +       if (cause & IF_SDIO_H_INT_DNLD)
12480 +               lbs_host_to_card_done(card->priv);
12481 +
12482 +
12483 +       if (cause & IF_SDIO_H_INT_UPLD) {
12484 +               ret = if_sdio_card_to_host(card);
12485 +               if (ret)
12486 +                       goto out;
12487 +       }
12488 +
12489 +       ret = 0;
12490 +
12491 +out:
12492 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12493 +}
12494 +
12495 +static int if_sdio_probe(struct sdio_func *func,
12496 +               const struct sdio_device_id *id)
12497 +{
12498 +       struct if_sdio_card *card;
12499 +       struct lbs_private *priv;
12500 +       int ret, i;
12501 +       unsigned int model;
12502 +       struct if_sdio_packet *packet;
12503 +
12504 +       lbs_deb_enter(LBS_DEB_SDIO);
12505 +
12506 +       for (i = 0;i < func->card->num_info;i++) {
12507 +               if (sscanf(func->card->info[i],
12508 +                               "802.11 SDIO ID: %x", &model) == 1)
12509 +                       break;
12510 +               if (sscanf(func->card->info[i],
12511 +                               "ID: %x", &model) == 1)
12512 +                       break;
12513 +       }
12514 +
12515 +       if (i == func->card->num_info) {
12516 +               lbs_pr_err("unable to identify card model\n");
12517 +               return -ENODEV;
12518 +       }
12519 +
12520 +       card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL);
12521 +       if (!card)
12522 +               return -ENOMEM;
12523 +
12524 +       card->func = func;
12525 +       card->model = model;
12526 +       spin_lock_init(&card->lock);
12527 +       INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
12528 +
12529 +       for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
12530 +               if (card->model == if_sdio_models[i].model)
12531 +                       break;
12532 +       }
12533 +
12534 +       if (i == ARRAY_SIZE(if_sdio_models)) {
12535 +               lbs_pr_err("unkown card model 0x%x\n", card->model);
12536 +               ret = -ENODEV;
12537 +               goto free;
12538 +       }
12539 +
12540 +       card->helper = if_sdio_models[i].helper;
12541 +       card->firmware = if_sdio_models[i].firmware;
12542 +
12543 +       if (lbs_helper_name) {
12544 +               lbs_deb_sdio("overriding helper firmware: %s\n",
12545 +                       lbs_helper_name);
12546 +               card->helper = lbs_helper_name;
12547 +       }
12548 +
12549 +       if (lbs_fw_name) {
12550 +               lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
12551 +               card->firmware = lbs_fw_name;
12552 +       }
12553 +
12554 +       sdio_claim_host(func);
12555 +
12556 +       ret = sdio_enable_func(func);
12557 +       if (ret)
12558 +               goto release;
12559 +
12560 +       ret = sdio_claim_irq(func, if_sdio_interrupt);
12561 +       if (ret)
12562 +               goto disable;
12563 +
12564 +       card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
12565 +       if (ret)
12566 +               goto release_int;
12567 +
12568 +       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
12569 +       if (ret)
12570 +               goto release_int;
12571 +
12572 +       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
12573 +       if (ret)
12574 +               goto release_int;
12575 +
12576 +       sdio_release_host(func);
12577 +
12578 +       sdio_set_drvdata(func, card);
12579 +
12580 +       lbs_deb_sdio("class = 0x%X, vendor = 0x%X, "
12581 +                       "device = 0x%X, model = 0x%X, ioport = 0x%X\n",
12582 +                       func->class, func->vendor, func->device,
12583 +                       model, (unsigned)card->ioport);
12584 +
12585 +       ret = if_sdio_prog_firmware(card);
12586 +       if (ret)
12587 +               goto reclaim;
12588 +
12589 +       priv = lbs_add_card(card, &func->dev);
12590 +       if (!priv) {
12591 +               ret = -ENOMEM;
12592 +               goto reclaim;
12593 +       }
12594 +
12595 +       card->priv = priv;
12596 +
12597 +       priv->card = card;
12598 +       priv->hw_host_to_card = if_sdio_host_to_card;
12599 +       priv->hw_get_int_status = if_sdio_get_int_status;
12600 +       priv->hw_read_event_cause = if_sdio_read_event_cause;
12601 +
12602 +       priv->fw_ready = 1;
12603 +
12604 +       /*
12605 +        * Enable interrupts now that everything is set up
12606 +        */
12607 +       sdio_claim_host(func);
12608 +       sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
12609 +       sdio_release_host(func);
12610 +       if (ret)
12611 +               goto reclaim;
12612 +
12613 +       ret = lbs_start_card(priv);
12614 +       if (ret)
12615 +               goto err_activate_card;
12616 +
12617 +out:
12618 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12619 +
12620 +       return ret;
12621 +
12622 +err_activate_card:
12623 +       flush_scheduled_work();
12624 +       free_netdev(priv->dev);
12625 +       kfree(priv);
12626 +reclaim:
12627 +       sdio_claim_host(func);
12628 +release_int:
12629 +       sdio_release_irq(func);
12630 +disable:
12631 +       sdio_disable_func(func);
12632 +release:
12633 +       sdio_release_host(func);
12634 +free:
12635 +       while (card->packets) {
12636 +               packet = card->packets;
12637 +               card->packets = card->packets->next;
12638 +               kfree(packet);
12639 +       }
12640 +
12641 +       kfree(card);
12642 +
12643 +       goto out;
12644 +}
12645 +
12646 +static void if_sdio_remove(struct sdio_func *func)
12647 +{
12648 +       struct if_sdio_card *card;
12649 +       struct if_sdio_packet *packet;
12650 +
12651 +       lbs_deb_enter(LBS_DEB_SDIO);
12652 +
12653 +       card = sdio_get_drvdata(func);
12654 +
12655 +       card->priv->surpriseremoved = 1;
12656 +
12657 +       lbs_deb_sdio("call remove card\n");
12658 +       lbs_stop_card(card->priv);
12659 +       lbs_remove_card(card->priv);
12660 +
12661 +       flush_scheduled_work();
12662 +
12663 +       sdio_claim_host(func);
12664 +       sdio_release_irq(func);
12665 +       sdio_disable_func(func);
12666 +       sdio_release_host(func);
12667 +
12668 +       while (card->packets) {
12669 +               packet = card->packets;
12670 +               card->packets = card->packets->next;
12671 +               kfree(packet);
12672 +       }
12673 +
12674 +       kfree(card);
12675 +
12676 +       lbs_deb_leave(LBS_DEB_SDIO);
12677 +}
12678 +
12679 +static struct sdio_driver if_sdio_driver = {
12680 +       .name           = "libertas_sdio",
12681 +       .id_table       = if_sdio_ids,
12682 +       .probe          = if_sdio_probe,
12683 +       .remove         = if_sdio_remove,
12684 +};
12685 +
12686 +/*******************************************************************/
12687 +/* Module functions                                                */
12688 +/*******************************************************************/
12689 +
12690 +static int __init if_sdio_init_module(void)
12691 +{
12692 +       int ret = 0;
12693 +
12694 +       lbs_deb_enter(LBS_DEB_SDIO);
12695 +
12696 +       printk(KERN_INFO "libertas_sdio: Libertas SDIO driver\n");
12697 +       printk(KERN_INFO "libertas_sdio: Copyright Pierre Ossman\n");
12698 +
12699 +       ret = sdio_register_driver(&if_sdio_driver);
12700 +
12701 +       lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
12702 +
12703 +       return ret;
12704 +}
12705 +
12706 +static void __exit if_sdio_exit_module(void)
12707 +{
12708 +       lbs_deb_enter(LBS_DEB_SDIO);
12709 +
12710 +       sdio_unregister_driver(&if_sdio_driver);
12711 +
12712 +       lbs_deb_leave(LBS_DEB_SDIO);
12713 +}
12714 +
12715 +module_init(if_sdio_init_module);
12716 +module_exit(if_sdio_exit_module);
12717 +
12718 +MODULE_DESCRIPTION("Libertas SDIO WLAN Driver");
12719 +MODULE_AUTHOR("Pierre Ossman");
12720 +MODULE_LICENSE("GPL");
12721 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_sdio.h linux-2.6.22-300/drivers/net/wireless/libertas/if_sdio.h
12722 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_sdio.h    1969-12-31 19:00:00.000000000 -0500
12723 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_sdio.h    2008-05-27 16:42:14.000000000 -0400
12724 @@ -0,0 +1,45 @@
12725 +/*
12726 + *  linux/drivers/net/wireless/libertas/if_sdio.h
12727 + *
12728 + *  Copyright 2007 Pierre Ossman
12729 + *
12730 + * This program is free software; you can redistribute it and/or modify
12731 + * it under the terms of the GNU General Public License as published by
12732 + * the Free Software Foundation; either version 2 of the License, or (at
12733 + * your option) any later version.
12734 + */
12735 +
12736 +#ifndef _LBS_IF_SDIO_H
12737 +#define _LBS_IF_SDIO_H
12738 +
12739 +#define IF_SDIO_IOPORT         0x00
12740 +
12741 +#define IF_SDIO_H_INT_MASK     0x04
12742 +#define   IF_SDIO_H_INT_OFLOW  0x08
12743 +#define   IF_SDIO_H_INT_UFLOW  0x04
12744 +#define   IF_SDIO_H_INT_DNLD   0x02
12745 +#define   IF_SDIO_H_INT_UPLD   0x01
12746 +
12747 +#define IF_SDIO_H_INT_STATUS   0x05
12748 +#define IF_SDIO_H_INT_RSR      0x06
12749 +#define IF_SDIO_H_INT_STATUS2  0x07
12750 +
12751 +#define IF_SDIO_RD_BASE                0x10
12752 +
12753 +#define IF_SDIO_STATUS         0x20
12754 +#define   IF_SDIO_IO_RDY       0x08
12755 +#define   IF_SDIO_CIS_RDY      0x04
12756 +#define   IF_SDIO_UL_RDY       0x02
12757 +#define   IF_SDIO_DL_RDY       0x01
12758 +
12759 +#define IF_SDIO_C_INT_MASK     0x24
12760 +#define IF_SDIO_C_INT_STATUS   0x28
12761 +#define IF_SDIO_C_INT_RSR      0x2C
12762 +
12763 +#define IF_SDIO_SCRATCH                0x34
12764 +#define IF_SDIO_SCRATCH_OLD    0x80fe
12765 +#define   IF_SDIO_FIRMWARE_OK  0xfedc
12766 +
12767 +#define IF_SDIO_EVENT           0x80fc
12768 +
12769 +#endif
12770 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.c linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.c
12771 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.c     2007-07-08 19:32:17.000000000 -0400
12772 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.c     2008-06-05 18:29:37.000000000 -0400
12773 @@ -5,8 +5,8 @@
12774  #include <linux/moduleparam.h>
12775  #include <linux/firmware.h>
12776  #include <linux/netdevice.h>
12777 -#include <linux/list.h>
12778  #include <linux/usb.h>
12779 +#include <asm/olpc.h>
12780  
12781  #define DRV_NAME "usb8xxx"
12782  
12783 @@ -14,24 +14,16 @@
12784  #include "decl.h"
12785  #include "defs.h"
12786  #include "dev.h"
12787 +#include "cmd.h"
12788  #include "if_usb.h"
12789  
12790 -#define MESSAGE_HEADER_LEN     4
12791 -
12792 -static const char usbdriver_name[] = "usb8xxx";
12793 -static u8 *default_fw_name = "usb8388.bin";
12794 +#define INSANEDEBUG    0
12795 +#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
12796  
12797 -char *libertas_fw_name = NULL;
12798 -module_param_named(fw_name, libertas_fw_name, charp, 0644);
12799 +#define MESSAGE_HEADER_LEN     4
12800  
12801 -/*
12802 - * We need to send a RESET command to all USB devices before
12803 - * we tear down the USB connection. Otherwise we would not
12804 - * be able to re-init device the device if the module gets
12805 - * loaded again. This is a list of all initialized USB devices,
12806 - * for the reset code see if_usb_reset_device()
12807 -*/
12808 -static LIST_HEAD(usb_devices);
12809 +static char *lbs_fw_name = "usb8388.bin";
12810 +module_param_named(fw_name, lbs_fw_name, charp, 0644);
12811  
12812  static struct usb_device_id if_usb_table[] = {
12813         /* Enter the device signature inside */
12814 @@ -44,13 +36,73 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
12815  
12816  static void if_usb_receive(struct urb *urb);
12817  static void if_usb_receive_fwload(struct urb *urb);
12818 -static int if_usb_reset_device(wlan_private *priv);
12819 -static int if_usb_register_dev(wlan_private * priv);
12820 -static int if_usb_unregister_dev(wlan_private *);
12821 -static int if_usb_prog_firmware(wlan_private *);
12822 -static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
12823 -static int if_usb_get_int_status(wlan_private * priv, u8 *);
12824 -static int if_usb_read_event_cause(wlan_private *);
12825 +static int if_usb_prog_firmware(struct if_usb_card *cardp,
12826 +                                       const char *fwname, int cmd);
12827 +static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
12828 +                              uint8_t *payload, uint16_t nb);
12829 +static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *);
12830 +static int if_usb_read_event_cause(struct lbs_private *);
12831 +static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
12832 +                       uint16_t nb);
12833 +static void if_usb_free(struct if_usb_card *cardp);
12834 +static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
12835 +static int if_usb_reset_device(struct if_usb_card *cardp);
12836 +
12837 +/* sysfs hooks */
12838 +
12839 +/**
12840 + *  Set function to write firmware to device's persistent memory
12841 + */
12842 +static ssize_t if_usb_firmware_set(struct device *dev,
12843 +               struct device_attribute *attr, const char *buf, size_t count)
12844 +{
12845 +       struct lbs_private *priv = to_net_dev(dev)->priv;
12846 +       struct if_usb_card *cardp = priv->card;
12847 +       char fwname[FIRMWARE_NAME_MAX];
12848 +       int ret;
12849 +
12850 +       sscanf(buf, "%29s", fwname); /* FIRMWARE_NAME_MAX - 1 = 29 */
12851 +       ret = if_usb_prog_firmware(cardp, fwname, BOOT_CMD_UPDATE_FW);
12852 +       if (ret == 0)
12853 +               return count;
12854 +
12855 +       return ret;
12856 +}
12857 +
12858 +/**
12859 + * lbs_fw attribute to be exported per ethX interface through sysfs
12860 + * (/sys/class/net/ethX/lbs_fw).  Use this like so to write firmware to the
12861 + * device's persistent memory:
12862 + * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_fw
12863 + */
12864 +static DEVICE_ATTR(lbs_fw, 0200, NULL, if_usb_firmware_set);
12865 +
12866 +/**
12867 + *  Set function to write firmware to device's persistent memory
12868 + */
12869 +static ssize_t if_usb_boot2_set(struct device *dev,
12870 +               struct device_attribute *attr, const char *buf, size_t count)
12871 +{
12872 +       struct lbs_private *priv = to_net_dev(dev)->priv;
12873 +       struct if_usb_card *cardp = priv->card;
12874 +       char fwname[FIRMWARE_NAME_MAX];
12875 +       int ret;
12876 +
12877 +       sscanf(buf, "%29s", fwname); /* FIRMWARE_NAME_MAX - 1 = 29 */
12878 +       ret = if_usb_prog_firmware(cardp, fwname, BOOT_CMD_UPDATE_BOOT2);
12879 +       if (ret == 0)
12880 +               return count;
12881 +
12882 +       return ret;
12883 +}
12884 +
12885 +/**
12886 + * lbs_boot2 attribute to be exported per ethX interface through sysfs
12887 + * (/sys/class/net/ethX/lbs_boot2).  Use this like so to write firmware to the
12888 + * device's persistent memory:
12889 + * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_boot2
12890 + */
12891 +static DEVICE_ATTR(lbs_boot2, 0200, NULL, if_usb_boot2_set);
12892  
12893  /**
12894   *  @brief  call back function to handle the status of the URB
12895 @@ -59,29 +111,25 @@ static int if_usb_read_event_cause(wlan_
12896   */
12897  static void if_usb_write_bulk_callback(struct urb *urb)
12898  {
12899 -       wlan_private *priv = (wlan_private *) (urb->context);
12900 -       wlan_adapter *adapter = priv->adapter;
12901 -       struct net_device *dev = priv->dev;
12902 +       struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
12903  
12904         /* handle the transmission complete validations */
12905  
12906 -       if (urb->status != 0) {
12907 +       if (urb->status == 0) {
12908 +               struct lbs_private *priv = cardp->priv;
12909 +
12910 +               lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
12911 +               lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
12912 +                            urb->actual_length);
12913 +
12914 +               /* Used for both firmware TX and regular TX.  priv isn't
12915 +                * valid at firmware load time.
12916 +                */
12917 +               if (priv)
12918 +                       lbs_host_to_card_done(priv);
12919 +       } else {
12920                 /* print the failure status number for debug */
12921                 lbs_pr_info("URB in failure status: %d\n", urb->status);
12922 -       } else {
12923 -               /*
12924 -               lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
12925 -               lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
12926 -                      urb->actual_length);
12927 -               */
12928 -               priv->dnld_sent = DNLD_RES_RECEIVED;
12929 -               /* Wake main thread if commands are pending */
12930 -               if (!adapter->cur_cmd)
12931 -                       wake_up_interruptible(&priv->mainthread.waitq);
12932 -               if ((adapter->connect_status == libertas_connected)) {
12933 -                       netif_wake_queue(dev);
12934 -                       netif_wake_queue(priv->mesh_dev);
12935 -               }
12936         }
12937  
12938         return;
12939 @@ -89,10 +137,10 @@ static void if_usb_write_bulk_callback(s
12940  
12941  /**
12942   *  @brief  free tx/rx urb, skb and rx buffer
12943 - *  @param cardp       pointer usb_card_rec
12944 + *  @param cardp       pointer if_usb_card
12945   *  @return            N/A
12946   */
12947 -void if_usb_free(struct usb_card_rec *cardp)
12948 +static void if_usb_free(struct if_usb_card *cardp)
12949  {
12950         lbs_deb_enter(LBS_DEB_USB);
12951  
12952 @@ -106,12 +154,57 @@ void if_usb_free(struct usb_card_rec *ca
12953         usb_free_urb(cardp->rx_urb);
12954         cardp->rx_urb = NULL;
12955  
12956 -       kfree(cardp->bulk_out_buffer);
12957 -       cardp->bulk_out_buffer = NULL;
12958 +       kfree(cardp->ep_out_buf);
12959 +       cardp->ep_out_buf = NULL;
12960  
12961         lbs_deb_leave(LBS_DEB_USB);
12962  }
12963  
12964 +static void if_usb_setup_firmware(struct lbs_private *priv)
12965 +{
12966 +       struct cmd_ds_set_boot2_ver b2_cmd;
12967 +       struct cmd_ds_802_11_fw_wake_method wake_method;
12968 +
12969 +       b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
12970 +       b2_cmd.action = 0;
12971 +       b2_cmd.version = priv->boot2_version;
12972 +
12973 +       if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
12974 +               lbs_deb_usb("Setting boot2 version failed\n");
12975 +
12976 +       priv->wol_gpio = 2; /* Wake via GPIO2... */
12977 +       priv->wol_gap = 20; /* ... after 20ms    */
12978 +       lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
12979 +
12980 +       wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
12981 +       wake_method.action = cpu_to_le16(CMD_ACT_GET);
12982 +       if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
12983 +               lbs_pr_info("Firmware does not seem to support PS mode\n");
12984 +       } else {
12985 +               if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
12986 +                       lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
12987 +                       priv->ps_supported = 1;
12988 +               } else {
12989 +                       /* The versions which boot up this way don't seem to
12990 +                          work even if we set it to the command interrupt */
12991 +                       lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
12992 +               }
12993 +       }
12994 +}
12995 +
12996 +static void if_usb_fw_timeo(unsigned long priv)
12997 +{
12998 +       struct if_usb_card *cardp = (void *)priv;
12999 +
13000 +       if (cardp->fwdnldover) {
13001 +               lbs_deb_usb("Download complete, no event. Assuming success\n");
13002 +       } else {
13003 +               lbs_pr_err("Download timed out\n");
13004 +               cardp->surprise_removed = 1;
13005 +       }
13006 +       wake_up(&cardp->fw_wq);
13007 +}
13008 +
13009  /**
13010   *  @brief sets the configuration values
13011   *  @param ifnum       interface number
13012 @@ -124,23 +217,26 @@ static int if_usb_probe(struct usb_inter
13013         struct usb_device *udev;
13014         struct usb_host_interface *iface_desc;
13015         struct usb_endpoint_descriptor *endpoint;
13016 -       wlan_private *priv;
13017 -       struct usb_card_rec *cardp;
13018 +       struct lbs_private *priv;
13019 +       struct if_usb_card *cardp;
13020         int i;
13021  
13022         udev = interface_to_usbdev(intf);
13023  
13024 -       cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
13025 +       cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
13026         if (!cardp) {
13027                 lbs_pr_err("Out of memory allocating private data.\n");
13028                 goto error;
13029         }
13030  
13031 +       setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
13032 +       init_waitqueue_head(&cardp->fw_wq);
13033 +
13034         cardp->udev = udev;
13035         iface_desc = intf->cur_altsetting;
13036  
13037         lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
13038 -              " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
13039 +                    " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
13040                      le16_to_cpu(udev->descriptor.bcdUSB),
13041                      udev->descriptor.bDeviceClass,
13042                      udev->descriptor.bDeviceSubClass,
13043 @@ -148,89 +244,78 @@ static int if_usb_probe(struct usb_inter
13044  
13045         for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
13046                 endpoint = &iface_desc->endpoint[i].desc;
13047 -               if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
13048 -                   && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
13049 -                       USB_ENDPOINT_XFER_BULK)) {
13050 -                       /* we found a bulk in endpoint */
13051 -                       lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
13052 -                                    le16_to_cpu(endpoint->wMaxPacketSize));
13053 -                       if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
13054 -                               lbs_deb_usbd(&udev->dev,
13055 -                                      "Rx URB allocation failed\n");
13056 -                               goto dealloc;
13057 -                       }
13058 -                       cardp->rx_urb_recall = 0;
13059 +               if (usb_endpoint_is_bulk_in(endpoint)) {
13060 +                       cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
13061 +                       cardp->ep_in = usb_endpoint_num(endpoint);
13062 +
13063 +                       lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
13064 +                       lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
13065 +
13066 +               } else if (usb_endpoint_is_bulk_out(endpoint)) {
13067 +                       cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
13068 +                       cardp->ep_out = usb_endpoint_num(endpoint);
13069  
13070 -                       cardp->bulk_in_size =
13071 -                               le16_to_cpu(endpoint->wMaxPacketSize);
13072 -                       cardp->bulk_in_endpointAddr =
13073 -                           (endpoint->
13074 -                            bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
13075 -                       lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
13076 -                              endpoint->bEndpointAddress);
13077 +                       lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
13078 +                       lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
13079                 }
13080 +       }
13081 +       if (!cardp->ep_out_size || !cardp->ep_in_size) {
13082 +               lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
13083 +               goto dealloc;
13084 +       }
13085 +       if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
13086 +               lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
13087 +               goto dealloc;
13088 +       }
13089 +       if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
13090 +               lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
13091 +               goto dealloc;
13092 +       }
13093 +       cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
13094 +       if (!cardp->ep_out_buf) {
13095 +               lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
13096 +               goto dealloc;
13097 +       }
13098  
13099 -               if (((endpoint->
13100 -                     bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
13101 -                    USB_DIR_OUT)
13102 -                   && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
13103 -                       USB_ENDPOINT_XFER_BULK)) {
13104 -                       /* We found bulk out endpoint */
13105 -                       if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
13106 -                               lbs_deb_usbd(&udev->dev,
13107 -                                      "Tx URB allocation failed\n");
13108 -                               goto dealloc;
13109 -                       }
13110 -
13111 -                       cardp->bulk_out_size =
13112 -                               le16_to_cpu(endpoint->wMaxPacketSize);
13113 -                       lbs_deb_usbd(&udev->dev,
13114 -                                    "Bulk out size is %d\n",
13115 -                                    le16_to_cpu(endpoint->wMaxPacketSize));
13116 -                       cardp->bulk_out_endpointAddr =
13117 -                           endpoint->bEndpointAddress;
13118 -                       lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
13119 -                                   endpoint->bEndpointAddress);
13120 -                       cardp->bulk_out_buffer =
13121 -                           kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
13122 -                                   GFP_KERNEL);
13123 -
13124 -                       if (!cardp->bulk_out_buffer) {
13125 -                               lbs_deb_usbd(&udev->dev,
13126 -                                      "Could not allocate buffer\n");
13127 -                               goto dealloc;
13128 -                       }
13129 -               }
13130 +       /* Upload firmware */
13131 +       if (if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
13132 +               lbs_deb_usbd(&udev->dev, "FW upload failed\n");
13133 +               goto err_prog_firmware;
13134         }
13135  
13136 -       if (!(priv = libertas_add_card(cardp, &udev->dev)))
13137 -               goto dealloc;
13138 +       if (!(priv = lbs_add_card(cardp, &udev->dev)))
13139 +               goto err_prog_firmware;
13140  
13141 -       if (libertas_add_mesh(priv, &udev->dev))
13142 -               goto err_add_mesh;
13143 +       cardp->priv = priv;
13144 +       cardp->priv->fw_ready = 1;
13145  
13146 -       priv->hw_register_dev = if_usb_register_dev;
13147 -       priv->hw_unregister_dev = if_usb_unregister_dev;
13148 -       priv->hw_prog_firmware = if_usb_prog_firmware;
13149         priv->hw_host_to_card = if_usb_host_to_card;
13150         priv->hw_get_int_status = if_usb_get_int_status;
13151         priv->hw_read_event_cause = if_usb_read_event_cause;
13152 +       priv->boot2_version = udev->descriptor.bcdDevice;
13153 +
13154 +       if_usb_submit_rx_urb(cardp);
13155  
13156 -       if (libertas_activate_card(priv, libertas_fw_name))
13157 -               goto err_activate_card;
13158 +       if (lbs_start_card(priv))
13159 +               goto err_start_card;
13160  
13161 -       list_add_tail(&cardp->list, &usb_devices);
13162 +       if_usb_setup_firmware(priv);
13163  
13164         usb_get_dev(udev);
13165         usb_set_intfdata(intf, cardp);
13166  
13167 +       if (device_create_file(&priv->dev->dev, &dev_attr_lbs_fw))
13168 +               lbs_pr_err("cannot register lbs_fw attribute\n");
13169 +
13170 +       if (device_create_file(&priv->dev->dev, &dev_attr_lbs_boot2))
13171 +               lbs_pr_err("cannot register lbs_boot2 attribute\n");
13172 +
13173         return 0;
13174  
13175 -err_activate_card:
13176 -       libertas_remove_mesh(priv);
13177 -err_add_mesh:
13178 -       free_netdev(priv->dev);
13179 -       kfree(priv->adapter);
13180 +err_start_card:
13181 +       lbs_remove_card(priv);
13182 +err_prog_firmware:
13183 +       if_usb_reset_device(cardp);
13184  dealloc:
13185         if_usb_free(cardp);
13186  
13187 @@ -245,23 +330,21 @@ error:
13188   */
13189  static void if_usb_disconnect(struct usb_interface *intf)
13190  {
13191 -       struct usb_card_rec *cardp = usb_get_intfdata(intf);
13192 -       wlan_private *priv = (wlan_private *) cardp->priv;
13193 -       wlan_adapter *adapter = NULL;
13194 -
13195 -       adapter = priv->adapter;
13196 -
13197 -       /*
13198 -        * Update Surprise removed to TRUE
13199 -        */
13200 -       adapter->surpriseremoved = 1;
13201 -
13202 -       list_del(&cardp->list);
13203 -
13204 -       /* card is removed and we can call wlan_remove_card */
13205 -       lbs_deb_usbd(&cardp->udev->dev, "call remove card\n");
13206 -       libertas_remove_mesh(priv);
13207 -       libertas_remove_card(priv);
13208 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
13209 +       struct lbs_private *priv = (struct lbs_private *) cardp->priv;
13210 +
13211 +       lbs_deb_enter(LBS_DEB_MAIN);
13212 +
13213 +       device_remove_file(&priv->dev->dev, &dev_attr_lbs_boot2);
13214 +       device_remove_file(&priv->dev->dev, &dev_attr_lbs_fw);
13215 +
13216 +       cardp->surprise_removed = 1;
13217 +
13218 +       if (priv) {
13219 +               priv->surpriseremoved = 1;
13220 +               lbs_stop_card(priv);
13221 +               lbs_remove_card(priv);
13222 +       }
13223  
13224         /* Unlink and free urb */
13225         if_usb_free(cardp);
13226 @@ -269,105 +352,94 @@ static void if_usb_disconnect(struct usb
13227         usb_set_intfdata(intf, NULL);
13228         usb_put_dev(interface_to_usbdev(intf));
13229  
13230 -       return;
13231 +       lbs_deb_leave(LBS_DEB_MAIN);
13232  }
13233  
13234  /**
13235   *  @brief  This function download FW
13236 - *  @param priv                pointer to wlan_private
13237 + *  @param priv                pointer to struct lbs_private
13238   *  @return            0
13239   */
13240 -static int if_prog_firmware(wlan_private * priv)
13241 +static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
13242  {
13243 -       struct usb_card_rec *cardp = priv->card;
13244 -       struct FWData *fwdata;
13245 -       struct fwheader *fwheader;
13246 -       u8 *firmware = priv->firmware->data;
13247 -
13248 -       fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
13249 -
13250 -       if (!fwdata)
13251 -               return -1;
13252 -
13253 -       fwheader = &fwdata->fwheader;
13254 +       struct fwdata *fwdata = cardp->ep_out_buf;
13255 +       uint8_t *firmware = cardp->fw->data;
13256  
13257 +       /* If we got a CRC failure on the last block, back
13258 +          up and retry it */
13259         if (!cardp->CRC_OK) {
13260                 cardp->totalbytes = cardp->fwlastblksent;
13261 -               cardp->fwseqnum = cardp->lastseqnum - 1;
13262 +               cardp->fwseqnum--;
13263         }
13264  
13265 -       /*
13266 -       lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
13267 -                   cardp->totalbytes);
13268 -       */
13269 +       lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
13270 +                    cardp->totalbytes);
13271  
13272 -       memcpy(fwheader, &firmware[cardp->totalbytes],
13273 +       /* struct fwdata (which we sent to the card) has an
13274 +          extra __le32 field in between the header and the data,
13275 +          which is not in the struct fwheader in the actual
13276 +          firmware binary. Insert the seqnum in the middle... */
13277 +       memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
13278                sizeof(struct fwheader));
13279  
13280         cardp->fwlastblksent = cardp->totalbytes;
13281         cardp->totalbytes += sizeof(struct fwheader);
13282  
13283 -       /* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
13284         memcpy(fwdata->data, &firmware[cardp->totalbytes],
13285 -              le32_to_cpu(fwdata->fwheader.datalength));
13286 +              le32_to_cpu(fwdata->hdr.datalength));
13287  
13288 -       /*
13289 -       lbs_deb_usbd(&cardp->udev->dev,
13290 -                   "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
13291 -       */
13292 +       lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
13293 +                    le32_to_cpu(fwdata->hdr.datalength));
13294  
13295 -       cardp->fwseqnum = cardp->fwseqnum + 1;
13296 +       fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
13297 +       cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
13298  
13299 -       fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
13300 -       cardp->lastseqnum = cardp->fwseqnum;
13301 -       cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
13302 -
13303 -       if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
13304 -               /*
13305 -               lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
13306 -               lbs_deb_usbd(&cardp->udev->dev,
13307 -                           "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
13308 -                           cardp->totalbytes);
13309 -               */
13310 -               memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
13311 -               usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
13312 +       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
13313 +                    le32_to_cpu(fwdata->hdr.datalength));
13314 +
13315 +       if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
13316 +               lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
13317 +               lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
13318 +                            cardp->fwseqnum, cardp->totalbytes);
13319 +       } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
13320 +               lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
13321 +               lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
13322  
13323 -       } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
13324 -               /*
13325 -               lbs_deb_usbd(&cardp->udev->dev,
13326 -                           "Host has finished FW downloading\n");
13327 -               lbs_deb_usbd(&cardp->udev->dev,
13328 -                           "Donwloading FW JUMP BLOCK\n");
13329 -               */
13330 -               memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
13331 -               usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
13332                 cardp->fwfinalblk = 1;
13333         }
13334  
13335 -       /*
13336 -       lbs_deb_usbd(&cardp->udev->dev,
13337 -                   "The firmware download is done size is %d\n",
13338 -                   cardp->totalbytes);
13339 -       */
13340 -
13341 -       kfree(fwdata);
13342 +       lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
13343 +                    cardp->totalbytes);
13344  
13345         return 0;
13346  }
13347  
13348 -static int libertas_do_reset(wlan_private *priv)
13349 +static int if_usb_reset_device(struct if_usb_card *cardp)
13350  {
13351 +       struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
13352         int ret;
13353 -       struct usb_card_rec *cardp = priv->card;
13354  
13355         lbs_deb_enter(LBS_DEB_USB);
13356  
13357 +       *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
13358 +
13359 +       cmd->command = cpu_to_le16(CMD_802_11_RESET);
13360 +       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
13361 +       cmd->result = cpu_to_le16(0);
13362 +       cmd->seqnum = cpu_to_le16(0x5a5a);
13363 +       cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
13364 +       usb_tx_block(cardp, cardp->ep_out_buf, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
13365 +
13366 +       msleep(100);
13367         ret = usb_reset_device(cardp->udev);
13368 -       if (!ret) {
13369 -               msleep(10);
13370 -               if_usb_reset_device(priv);
13371 -               msleep(10);
13372 +       msleep(100);
13373 +
13374 +#ifdef CONFIG_OLPC
13375 +       if (ret && machine_is_olpc()) {
13376 +               printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
13377 +               olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
13378         }
13379 +#endif
13380  
13381         lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
13382  
13383 @@ -376,36 +448,33 @@ static int libertas_do_reset(wlan_privat
13384  
13385  /**
13386   *  @brief This function transfer the data to the device.
13387 - *  @param priv        pointer to wlan_private
13388 + *  @param priv        pointer to struct lbs_private
13389   *  @param payload     pointer to payload data
13390   *  @param nb          data length
13391   *  @return            0 or -1
13392   */
13393 -int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
13394 +static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
13395  {
13396 -       /* pointer to card structure */
13397 -       struct usb_card_rec *cardp = priv->card;
13398         int ret = -1;
13399  
13400         /* check if device is removed */
13401 -       if (priv->adapter->surpriseremoved) {
13402 +       if (cardp->surprise_removed) {
13403                 lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
13404                 goto tx_ret;
13405         }
13406  
13407         usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
13408                           usb_sndbulkpipe(cardp->udev,
13409 -                                         cardp->bulk_out_endpointAddr),
13410 -                         payload, nb, if_usb_write_bulk_callback, priv);
13411 +                                         cardp->ep_out),
13412 +                         payload, nb, if_usb_write_bulk_callback, cardp);
13413  
13414         cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
13415  
13416         if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
13417 -               /*  transfer failed */
13418 -               lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
13419 +               lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
13420                 ret = -1;
13421         } else {
13422 -               /* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
13423 +               lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
13424                 ret = 0;
13425         }
13426  
13427 @@ -413,13 +482,10 @@ tx_ret:
13428         return ret;
13429  }
13430  
13431 -static int __if_usb_submit_rx_urb(wlan_private * priv,
13432 -                                 void (*callbackfn)
13433 -                                 (struct urb *urb))
13434 +static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
13435 +                                 void (*callbackfn)(struct urb *urb))
13436  {
13437 -       struct usb_card_rec *cardp = priv->card;
13438         struct sk_buff *skb;
13439 -       struct read_cb_info *rinfo = &cardp->rinfo;
13440         int ret = -1;
13441  
13442         if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
13443 @@ -427,25 +493,25 @@ static int __if_usb_submit_rx_urb(wlan_p
13444                 goto rx_ret;
13445         }
13446  
13447 -       rinfo->skb = skb;
13448 +       cardp->rx_skb = skb;
13449  
13450         /* Fill the receive configuration URB and initialise the Rx call back */
13451         usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
13452 -                         usb_rcvbulkpipe(cardp->udev,
13453 -                                         cardp->bulk_in_endpointAddr),
13454 +                         usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
13455                           (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
13456                           MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
13457 -                         rinfo);
13458 +                         cardp);
13459  
13460         cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
13461  
13462 -       /* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
13463 +       lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
13464         if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
13465 -               /* handle failure conditions */
13466 -               lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
13467 +               lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
13468 +               kfree_skb(skb);
13469 +               cardp->rx_skb = NULL;
13470                 ret = -1;
13471         } else {
13472 -               /* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
13473 +               lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
13474                 ret = 0;
13475         }
13476  
13477 @@ -453,62 +519,83 @@ rx_ret:
13478         return ret;
13479  }
13480  
13481 -static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv)
13482 +static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
13483  {
13484 -       return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload);
13485 +       return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
13486  }
13487  
13488 -static inline int if_usb_submit_rx_urb(wlan_private * priv)
13489 +static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
13490  {
13491 -       return __if_usb_submit_rx_urb(priv, &if_usb_receive);
13492 +       return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
13493  }
13494  
13495  static void if_usb_receive_fwload(struct urb *urb)
13496  {
13497 -       struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
13498 -       wlan_private *priv = rinfo->priv;
13499 -       struct sk_buff *skb = rinfo->skb;
13500 -       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
13501 +       struct if_usb_card *cardp = urb->context;
13502 +       struct sk_buff *skb = cardp->rx_skb;
13503         struct fwsyncheader *syncfwheader;
13504 -       struct bootcmdrespStr bootcmdresp;
13505 +       struct bootcmdresp bootcmdresp;
13506  
13507         if (urb->status) {
13508                 lbs_deb_usbd(&cardp->udev->dev,
13509 -                           "URB status is failed during fw load\n");
13510 +                            "URB status is failed during fw load\n");
13511                 kfree_skb(skb);
13512                 return;
13513         }
13514  
13515 -       if (cardp->bootcmdresp == 0) {
13516 +       if (cardp->fwdnldover) {
13517 +               __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
13518 +
13519 +               if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
13520 +                   tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
13521 +                       lbs_pr_info("Firmware ready event received\n");
13522 +                       wake_up(&cardp->fw_wq);
13523 +               } else {
13524 +                       lbs_deb_usb("Waiting for confirmation; got %x %x\n",
13525 +                                   le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
13526 +                       if_usb_submit_rx_urb_fwload(cardp);
13527 +               }
13528 +               kfree_skb(skb);
13529 +               return;
13530 +       }
13531 +       if (cardp->bootcmdresp <= 0) {
13532                 memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
13533                         sizeof(bootcmdresp));
13534 +
13535                 if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
13536                         kfree_skb(skb);
13537 -                       if_usb_submit_rx_urb_fwload(priv);
13538 +                       if_usb_submit_rx_urb_fwload(cardp);
13539                         cardp->bootcmdresp = 1;
13540                         lbs_deb_usbd(&cardp->udev->dev,
13541 -                                   "Received valid boot command response\n");
13542 +                                    "Received valid boot command response\n");
13543                         return;
13544                 }
13545 -               if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
13546 -                       lbs_pr_info(
13547 -                               "boot cmd response wrong magic number (0x%x)\n",
13548 -                               le32_to_cpu(bootcmdresp.u32magicnumber));
13549 -               } else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
13550 -                       lbs_pr_info(
13551 -                               "boot cmd response cmd_tag error (%d)\n",
13552 -                               bootcmdresp.u8cmd_tag);
13553 -               } else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
13554 -                       lbs_pr_info(
13555 -                               "boot cmd response result error (%d)\n",
13556 -                               bootcmdresp.u8result);
13557 +               if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
13558 +                       if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
13559 +                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
13560 +                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
13561 +                               if (!cardp->bootcmdresp)
13562 +                                       lbs_pr_info("Firmware already seems alive; resetting\n");
13563 +                               cardp->bootcmdresp = -1;
13564 +                       } else {
13565 +                               lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
13566 +                                           le32_to_cpu(bootcmdresp.magic));
13567 +                       }
13568 +               } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
13569 +                          (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
13570 +                          (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
13571 +                       lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
13572 +                                   bootcmdresp.cmd);
13573 +               } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
13574 +                       lbs_pr_info("boot cmd response result error (%d)\n",
13575 +                                   bootcmdresp.result);
13576                 } else {
13577                         cardp->bootcmdresp = 1;
13578                         lbs_deb_usbd(&cardp->udev->dev,
13579 -                                   "Received valid boot command response\n");
13580 +                                    "Received valid boot command response\n");
13581                 }
13582                 kfree_skb(skb);
13583 -               if_usb_submit_rx_urb_fwload(priv);
13584 +               if_usb_submit_rx_urb_fwload(cardp);
13585                 return;
13586         }
13587  
13588 @@ -520,50 +607,47 @@ static void if_usb_receive_fwload(struct
13589         }
13590  
13591         memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
13592 -                       sizeof(struct fwsyncheader));
13593 +              sizeof(struct fwsyncheader));
13594  
13595         if (!syncfwheader->cmd) {
13596 -               /*
13597 -               lbs_deb_usbd(&cardp->udev->dev,
13598 -                           "FW received Blk with correct CRC\n");
13599 -               lbs_deb_usbd(&cardp->udev->dev,
13600 -                           "FW received Blk seqnum = %d\n",
13601 -                      syncfwheader->seqnum);
13602 -               */
13603 +               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
13604 +               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
13605 +                            le32_to_cpu(syncfwheader->seqnum));
13606                 cardp->CRC_OK = 1;
13607         } else {
13608 -               lbs_deb_usbd(&cardp->udev->dev,
13609 -                           "FW received Blk with CRC error\n");
13610 +               lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
13611                 cardp->CRC_OK = 0;
13612         }
13613  
13614         kfree_skb(skb);
13615  
13616 +       /* Give device 5s to either write firmware to its RAM or eeprom */
13617 +       mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
13618 +
13619         if (cardp->fwfinalblk) {
13620                 cardp->fwdnldover = 1;
13621                 goto exit;
13622         }
13623  
13624 -       if_prog_firmware(priv);
13625 +       if_usb_send_fw_pkt(cardp);
13626 +
13627 + exit:
13628 +       if_usb_submit_rx_urb_fwload(cardp);
13629  
13630 -       if_usb_submit_rx_urb_fwload(priv);
13631 -exit:
13632         kfree(syncfwheader);
13633  
13634         return;
13635 -
13636  }
13637  
13638  #define MRVDRV_MIN_PKT_LEN     30
13639  
13640  static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
13641 -                                      struct usb_card_rec *cardp,
13642 -                                      wlan_private *priv)
13643 +                                      struct if_usb_card *cardp,
13644 +                                      struct lbs_private *priv)
13645  {
13646 -       if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
13647 -           MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
13648 -               lbs_deb_usbd(&cardp->udev->dev,
13649 -                           "Packet length is Invalid\n");
13650 +       if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
13651 +           || recvlength < MRVDRV_MIN_PKT_LEN) {
13652 +               lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
13653                 kfree_skb(skb);
13654                 return;
13655         }
13656 @@ -571,19 +655,19 @@ static inline void process_cmdtypedata(i
13657         skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
13658         skb_put(skb, recvlength);
13659         skb_pull(skb, MESSAGE_HEADER_LEN);
13660 -       libertas_process_rxed_packet(priv, skb);
13661 +
13662 +       lbs_process_rxed_packet(priv, skb);
13663         priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
13664  }
13665  
13666 -static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
13667 +static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
13668                                       struct sk_buff *skb,
13669 -                                     struct usb_card_rec *cardp,
13670 -                                     wlan_private *priv)
13671 +                                     struct if_usb_card *cardp,
13672 +                                     struct lbs_private *priv)
13673  {
13674 -       u8 *cmdbuf;
13675 -       if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
13676 +       if (recvlength > LBS_CMD_BUFFER_SIZE) {
13677                 lbs_deb_usbd(&cardp->udev->dev,
13678 -                           "The receive buffer is too large\n");
13679 +                            "The receive buffer is too large\n");
13680                 kfree_skb(skb);
13681                 return;
13682         }
13683 @@ -591,28 +675,17 @@ static inline void process_cmdrequest(in
13684         if (!in_interrupt())
13685                 BUG();
13686  
13687 -       spin_lock(&priv->adapter->driver_lock);
13688 -       /* take care of cur_cmd = NULL case by reading the
13689 -        * data to clear the interrupt */
13690 -       if (!priv->adapter->cur_cmd) {
13691 -               cmdbuf = priv->upld_buf;
13692 -               priv->adapter->hisregcpy &= ~his_cmdupldrdy;
13693 -       } else
13694 -               cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
13695 -
13696 -       cardp->usb_int_cause |= his_cmdupldrdy;
13697 +       spin_lock(&priv->driver_lock);
13698 +       cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
13699         priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
13700 -       memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
13701 -              priv->upld_len);
13702 +       memcpy(priv->upld_buf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
13703  
13704         kfree_skb(skb);
13705 -       libertas_interrupt(priv->dev);
13706 -       spin_unlock(&priv->adapter->driver_lock);
13707 +       lbs_interrupt(priv);
13708 +       spin_unlock(&priv->driver_lock);
13709  
13710         lbs_deb_usbd(&cardp->udev->dev,
13711                     "Wake up main thread to handle cmd response\n");
13712 -
13713 -       return;
13714  }
13715  
13716  /**
13717 @@ -624,37 +697,33 @@ static inline void process_cmdrequest(in
13718   */
13719  static void if_usb_receive(struct urb *urb)
13720  {
13721 -       struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
13722 -       wlan_private *priv = rinfo->priv;
13723 -       struct sk_buff *skb = rinfo->skb;
13724 -       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
13725 -
13726 +       struct if_usb_card *cardp = urb->context;
13727 +       struct sk_buff *skb = cardp->rx_skb;
13728 +       struct lbs_private *priv = cardp->priv;
13729         int recvlength = urb->actual_length;
13730 -       u8 *recvbuff = NULL;
13731 -       u32 recvtype;
13732 +       uint8_t *recvbuff = NULL;
13733 +       uint32_t recvtype = 0;
13734 +       __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
13735  
13736         lbs_deb_enter(LBS_DEB_USB);
13737  
13738         if (recvlength) {
13739                 if (urb->status) {
13740 -                       lbs_deb_usbd(&cardp->udev->dev,
13741 -                                   "URB status is failed\n");
13742 +                       lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
13743 +                                    urb->status);
13744                         kfree_skb(skb);
13745                         goto setup_for_next;
13746                 }
13747  
13748                 recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
13749 -               memcpy(&recvtype, recvbuff, sizeof(u32));
13750 +               recvtype = le32_to_cpu(pkt[0]);
13751                 lbs_deb_usbd(&cardp->udev->dev,
13752 -                           "Recv length = 0x%x\n", recvlength);
13753 -               lbs_deb_usbd(&cardp->udev->dev,
13754 -                           "Receive type = 0x%X\n", recvtype);
13755 -               recvtype = le32_to_cpu(recvtype);
13756 -               lbs_deb_usbd(&cardp->udev->dev,
13757 -                           "Receive type after = 0x%X\n", recvtype);
13758 -       } else if (urb->status)
13759 +                           "Recv length = 0x%x, Recv type = 0x%X\n",
13760 +                           recvlength, recvtype);
13761 +       } else if (urb->status) {
13762 +               kfree_skb(skb);
13763                 goto rx_exit;
13764 -
13765 +       }
13766  
13767         switch (recvtype) {
13768         case CMD_TYPE_DATA:
13769 @@ -667,168 +736,219 @@ static void if_usb_receive(struct urb *u
13770  
13771         case CMD_TYPE_INDICATION:
13772                 /* Event cause handling */
13773 -               spin_lock(&priv->adapter->driver_lock);
13774 -               cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
13775 +               spin_lock(&priv->driver_lock);
13776 +
13777 +               cardp->usb_event_cause = le32_to_cpu(pkt[1]);
13778 +
13779                 lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
13780 -                           cardp->usb_event_cause);
13781 +                            cardp->usb_event_cause);
13782 +
13783 +               /* Icky undocumented magic special case */
13784                 if (cardp->usb_event_cause & 0xffff0000) {
13785 -                       libertas_send_tx_feedback(priv);
13786 -                       spin_unlock(&priv->adapter->driver_lock);
13787 +                       lbs_send_tx_feedback(priv);
13788 +                       spin_unlock(&priv->driver_lock);
13789                         break;
13790                 }
13791                 cardp->usb_event_cause <<= 3;
13792 -               cardp->usb_int_cause |= his_cardevent;
13793 +               cardp->usb_int_cause |= MRVDRV_CARDEVENT;
13794                 kfree_skb(skb);
13795 -               libertas_interrupt(priv->dev);
13796 -               spin_unlock(&priv->adapter->driver_lock);
13797 +               lbs_interrupt(priv);
13798 +               spin_unlock(&priv->driver_lock);
13799                 goto rx_exit;
13800         default:
13801 +               lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
13802 +                            recvtype);
13803                 kfree_skb(skb);
13804                 break;
13805         }
13806  
13807  setup_for_next:
13808 -       if_usb_submit_rx_urb(priv);
13809 +       if_usb_submit_rx_urb(cardp);
13810  rx_exit:
13811         lbs_deb_leave(LBS_DEB_USB);
13812  }
13813  
13814  /**
13815   *  @brief This function downloads data to FW
13816 - *  @param priv                pointer to wlan_private structure
13817 + *  @param priv                pointer to struct lbs_private structure
13818   *  @param type                type of data
13819   *  @param buf         pointer to data buffer
13820   *  @param len         number of bytes
13821   *  @return            0 or -1
13822   */
13823 -static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
13824 +static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
13825 +                              uint8_t *payload, uint16_t nb)
13826  {
13827 -       int ret = -1;
13828 -       u32 tmp;
13829 -       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
13830 +       struct if_usb_card *cardp = priv->card;
13831  
13832         lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
13833         lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
13834  
13835         if (type == MVMS_CMD) {
13836 -               tmp = cpu_to_le32(CMD_TYPE_REQUEST);
13837 +               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
13838                 priv->dnld_sent = DNLD_CMD_SENT;
13839 -               memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
13840 -                      MESSAGE_HEADER_LEN);
13841 -
13842         } else {
13843 -               tmp = cpu_to_le32(CMD_TYPE_DATA);
13844 +               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
13845                 priv->dnld_sent = DNLD_DATA_SENT;
13846 -               memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
13847 -                      MESSAGE_HEADER_LEN);
13848         }
13849  
13850 -       memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
13851 -
13852 -       ret =
13853 -           usb_tx_block(priv, cardp->bulk_out_buffer, nb + MESSAGE_HEADER_LEN);
13854 +       memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
13855  
13856 -       return ret;
13857 +       return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
13858  }
13859  
13860 -/* called with adapter->driver_lock held */
13861 -static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
13862 +/* called with priv->driver_lock held */
13863 +static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *ireg)
13864  {
13865 -       struct usb_card_rec *cardp = priv->card;
13866 +       struct if_usb_card *cardp = priv->card;
13867  
13868         *ireg = cardp->usb_int_cause;
13869         cardp->usb_int_cause = 0;
13870  
13871 -       lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
13872 +       lbs_deb_usbd(&cardp->udev->dev, "Int cause is 0x%X\n", *ireg);
13873  
13874         return 0;
13875  }
13876  
13877 -static int if_usb_read_event_cause(wlan_private * priv)
13878 +static int if_usb_read_event_cause(struct lbs_private *priv)
13879  {
13880 -       struct usb_card_rec *cardp = priv->card;
13881 -       priv->adapter->eventcause = cardp->usb_event_cause;
13882 +       struct if_usb_card *cardp = priv->card;
13883 +
13884 +       priv->eventcause = cardp->usb_event_cause;
13885         /* Re-submit rx urb here to avoid event lost issue */
13886 -       if_usb_submit_rx_urb(priv);
13887 +       if_usb_submit_rx_urb(cardp);
13888 +
13889         return 0;
13890  }
13891  
13892 -static int if_usb_reset_device(wlan_private *priv)
13893 +/**
13894 + *  @brief This function issues Boot command to the Boot2 code
13895 + *  @param ivalue   1:Boot from FW by USB-Download
13896 + *                  2:Boot from FW in EEPROM
13897 + *  @return            0
13898 + */
13899 +static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
13900  {
13901 -       int ret;
13902 -
13903 -       lbs_deb_enter(LBS_DEB_USB);
13904 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
13905 -                                   cmd_act_halt, 0, 0, NULL);
13906 -       msleep_interruptible(10);
13907 -
13908 -       lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
13909 -       return ret;
13910 -}
13911 +       struct bootcmd *bootcmd = cardp->ep_out_buf;
13912  
13913 -static int if_usb_unregister_dev(wlan_private * priv)
13914 -{
13915 -       int ret = 0;
13916 +       /* Prepare command */
13917 +       bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
13918 +       bootcmd->cmd = ivalue;
13919 +       memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
13920  
13921 -       /* Need to send a Reset command to device before USB resources freed
13922 -        * and wlan_remove_card() called, then device can handle FW download
13923 -        * again.
13924 -        */
13925 -       if (priv)
13926 -               if_usb_reset_device(priv);
13927 +       /* Issue command */
13928 +       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
13929  
13930 -       return ret;
13931 +       return 0;
13932  }
13933  
13934  
13935  /**
13936 - *  @brief  This function register usb device and initialize parameter
13937 - *  @param             priv pointer to wlan_private
13938 - *  @return            0 or -1
13939 + *  @brief This function checks the validity of Boot2/FW image.
13940 + *
13941 + *  @param data              pointer to image
13942 + *         len               image length
13943 + *  @return     0 or -1
13944   */
13945 -static int if_usb_register_dev(wlan_private * priv)
13946 +static int check_fwfile_format(uint8_t *data, uint32_t totlen)
13947  {
13948 -       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
13949 -
13950 -       lbs_deb_enter(LBS_DEB_USB);
13951 +       uint32_t bincmd, exit;
13952 +       uint32_t blksize, offset, len;
13953 +       int ret;
13954  
13955 -       cardp->priv = priv;
13956 -       cardp->eth_dev = priv->dev;
13957 -       priv->hotplug_device = &(cardp->udev->dev);
13958 +       ret = 1;
13959 +       exit = len = 0;
13960  
13961 -       lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
13962 -                   cardp->udev);
13963 +       do {
13964 +               struct fwheader *fwh = (void *)data;
13965  
13966 -       lbs_deb_leave(LBS_DEB_USB);
13967 -       return 0;
13968 -}
13969 +               bincmd = le32_to_cpu(fwh->dnldcmd);
13970 +               blksize = le32_to_cpu(fwh->datalength);
13971 +               switch (bincmd) {
13972 +               case FW_HAS_DATA_TO_RECV:
13973 +                       offset = sizeof(struct fwheader) + blksize;
13974 +                       data += offset;
13975 +                       len += offset;
13976 +                       if (len >= totlen)
13977 +                               exit = 1;
13978 +                       break;
13979 +               case FW_HAS_LAST_BLOCK:
13980 +                       exit = 1;
13981 +                       ret = 0;
13982 +                       break;
13983 +               default:
13984 +                       exit = 1;
13985 +                       break;
13986 +               }
13987 +       } while (!exit);
13988  
13989 +       if (ret)
13990 +               lbs_pr_err("firmware file format check FAIL\n");
13991 +       else
13992 +               lbs_deb_fw("firmware file format check PASS\n");
13993  
13994 +       return ret;
13995 +}
13996  
13997 -static int if_usb_prog_firmware(wlan_private * priv)
13998 +/**
13999 + *  @brief This function programs the firmware subject to cmd
14000 + *
14001 + *  @param cardp             the if_usb_card descriptor
14002 + *         fwname            firmware or boot2 image file name
14003 + *         cmd               either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
14004 + *                           or BOOT_CMD_UPDATE_BOOT2.
14005 + *  @return     0 or error code
14006 + */
14007 +static int if_usb_prog_firmware(struct if_usb_card *cardp,
14008 +                                       const char *fwname, int cmd)
14009  {
14010 -       struct usb_card_rec *cardp = priv->card;
14011         int i = 0;
14012         static int reset_count = 10;
14013         int ret = 0;
14014  
14015         lbs_deb_enter(LBS_DEB_USB);
14016  
14017 -       cardp->rinfo.priv = priv;
14018 +       /* Don't mess with the firmware if the interface is up */
14019 +       if (cardp->priv &&
14020 +               (cardp->priv->mesh_open || cardp->priv->infra_open)) {
14021 +               ret = -EPERM;
14022 +               goto done;
14023 +       }
14024 +
14025 +       ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
14026 +       if (ret < 0) {
14027 +               lbs_pr_err("request_firmware() failed with %#x\n", ret);
14028 +               lbs_pr_err("firmware %s not found\n", fwname);
14029 +               goto done;
14030 +       }
14031 +
14032 +       if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
14033 +               ret = -EINVAL;
14034 +               goto release_fw;
14035 +       }
14036 +
14037 +       /* Cancel any pending usb business */
14038 +       usb_kill_urb(cardp->rx_urb);
14039 +       usb_kill_urb(cardp->tx_urb);
14040 +
14041 +       cardp->fwlastblksent = 0;
14042 +       cardp->fwdnldover = 0;
14043 +       cardp->totalbytes = 0;
14044 +       cardp->fwfinalblk = 0;
14045 +       cardp->bootcmdresp = 0;
14046  
14047  restart:
14048 -       if (if_usb_submit_rx_urb_fwload(priv) < 0) {
14049 +       if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
14050                 lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
14051 -               ret = -1;
14052 -               goto done;
14053 +               ret = -EIO;
14054 +               goto release_fw;
14055         }
14056  
14057         cardp->bootcmdresp = 0;
14058         do {
14059                 int j = 0;
14060                 i++;
14061 -               /* Issue Boot command = 1, Boot from Download-FW */
14062 -               if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
14063 +               if_usb_issue_boot_command(cardp, cmd);
14064                 /* wait for command response */
14065                 do {
14066                         j++;
14067 @@ -836,16 +956,15 @@ restart:
14068                 } while (cardp->bootcmdresp == 0 && j < 10);
14069         } while (cardp->bootcmdresp == 0 && i < 5);
14070  
14071 -       if (cardp->bootcmdresp == 0) {
14072 +       if (cardp->bootcmdresp <= 0) {
14073                 if (--reset_count >= 0) {
14074 -                       libertas_do_reset(priv);
14075 +                       if_usb_reset_device(cardp);
14076                         goto restart;
14077                 }
14078 -               return -1;
14079 +               return -EIO;
14080         }
14081  
14082         i = 0;
14083 -       priv->adapter->fw_ready = 0;
14084  
14085         cardp->totalbytes = 0;
14086         cardp->fwlastblksent = 0;
14087 @@ -855,77 +974,72 @@ restart:
14088         cardp->totalbytes = 0;
14089         cardp->fwfinalblk = 0;
14090  
14091 -       if_prog_firmware(priv);
14092 +       /* Send the first firmware packet... */
14093 +       if_usb_send_fw_pkt(cardp);
14094  
14095 -       do {
14096 -               lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
14097 -               i++;
14098 -               msleep_interruptible(100);
14099 -               if (priv->adapter->surpriseremoved || i >= 20)
14100 -                       break;
14101 -       } while (!cardp->fwdnldover);
14102 +       /* ... and wait for the process to complete */
14103 +       wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
14104 +
14105 +       del_timer_sync(&cardp->fw_timeout);
14106 +       usb_kill_urb(cardp->rx_urb);
14107  
14108         if (!cardp->fwdnldover) {
14109                 lbs_pr_info("failed to load fw, resetting device!\n");
14110                 if (--reset_count >= 0) {
14111 -                       libertas_do_reset(priv);
14112 +                       if_usb_reset_device(cardp);
14113                         goto restart;
14114                 }
14115  
14116                 lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
14117 -               ret = -1;
14118 -               goto done;
14119 +               ret = -EIO;
14120 +               goto release_fw;
14121         }
14122  
14123 -       if_usb_submit_rx_urb(priv);
14124 + release_fw:
14125 +       release_firmware(cardp->fw);
14126 +       cardp->fw = NULL;
14127  
14128 -       /* Delay 200 ms to waiting for the FW ready */
14129 -       msleep_interruptible(200);
14130 -
14131 -       priv->adapter->fw_ready = 1;
14132 -
14133 -done:
14134 + done:
14135         lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
14136         return ret;
14137  }
14138  
14139 +
14140  #ifdef CONFIG_PM
14141  static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
14142  {
14143 -       struct usb_card_rec *cardp = usb_get_intfdata(intf);
14144 -       wlan_private *priv = cardp->priv;
14145 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
14146 +       struct lbs_private *priv = cardp->priv;
14147 +       int ret;
14148  
14149         lbs_deb_enter(LBS_DEB_USB);
14150  
14151 -       if (priv->adapter->psstate != PS_STATE_FULL_POWER)
14152 +       if (priv->psstate != PS_STATE_FULL_POWER)
14153                 return -1;
14154  
14155 -       netif_device_detach(cardp->eth_dev);
14156 -       netif_device_detach(priv->mesh_dev);
14157 +       ret = lbs_suspend(priv);
14158 +       if (ret)
14159 +               goto out;
14160  
14161         /* Unlink tx & rx urb */
14162         usb_kill_urb(cardp->tx_urb);
14163         usb_kill_urb(cardp->rx_urb);
14164  
14165 -       cardp->rx_urb_recall = 1;
14166 -
14167 + out:
14168         lbs_deb_leave(LBS_DEB_USB);
14169 -       return 0;
14170 +       return ret;
14171  }
14172  
14173  static int if_usb_resume(struct usb_interface *intf)
14174  {
14175 -       struct usb_card_rec *cardp = usb_get_intfdata(intf);
14176 -       wlan_private *priv = cardp->priv;
14177 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
14178 +       struct lbs_private *priv = cardp->priv;
14179  
14180         lbs_deb_enter(LBS_DEB_USB);
14181  
14182 -       cardp->rx_urb_recall = 0;
14183 -
14184 -       if_usb_submit_rx_urb(cardp->priv);
14185 +       if_usb_submit_rx_urb(cardp);
14186  
14187 -       netif_device_attach(cardp->eth_dev);
14188 -       netif_device_attach(priv->mesh_dev);
14189 +       lbs_resume(priv);
14190  
14191         lbs_deb_leave(LBS_DEB_USB);
14192         return 0;
14193 @@ -936,44 +1050,30 @@ static int if_usb_resume(struct usb_inte
14194  #endif
14195  
14196  static struct usb_driver if_usb_driver = {
14197 -       /* driver name */
14198 -       .name = usbdriver_name,
14199 -       /* probe function name */
14200 +       .name = DRV_NAME,
14201         .probe = if_usb_probe,
14202 -       /* disconnect function  name */
14203         .disconnect = if_usb_disconnect,
14204 -       /* device signature table */
14205         .id_table = if_usb_table,
14206         .suspend = if_usb_suspend,
14207         .resume = if_usb_resume,
14208  };
14209  
14210 -static int if_usb_init_module(void)
14211 +static int __init if_usb_init_module(void)
14212  {
14213         int ret = 0;
14214  
14215         lbs_deb_enter(LBS_DEB_MAIN);
14216  
14217 -       if (libertas_fw_name == NULL) {
14218 -               libertas_fw_name = default_fw_name;
14219 -       }
14220 -
14221         ret = usb_register(&if_usb_driver);
14222  
14223         lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
14224         return ret;
14225  }
14226  
14227 -static void if_usb_exit_module(void)
14228 +static void __exit if_usb_exit_module(void)
14229  {
14230 -       struct usb_card_rec *cardp, *cardp_temp;
14231 -
14232         lbs_deb_enter(LBS_DEB_MAIN);
14233  
14234 -       list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list)
14235 -               if_usb_reset_device((wlan_private *) cardp->priv);
14236 -
14237 -       /* API unregisters the driver from USB subsystem */
14238         usb_deregister(&if_usb_driver);
14239  
14240         lbs_deb_leave(LBS_DEB_MAIN);
14241 @@ -983,5 +1083,5 @@ module_init(if_usb_init_module);
14242  module_exit(if_usb_exit_module);
14243  
14244  MODULE_DESCRIPTION("8388 USB WLAN Driver");
14245 -MODULE_AUTHOR("Marvell International Ltd.");
14246 +MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
14247  MODULE_LICENSE("GPL");
14248 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.c.orig linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.c.orig
14249 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.c.orig        1969-12-31 19:00:00.000000000 -0500
14250 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.c.orig        2008-06-05 18:29:26.000000000 -0400
14251 @@ -0,0 +1,1022 @@
14252 +/**
14253 +  * This file contains functions used in USB interface module.
14254 +  */
14255 +#include <linux/delay.h>
14256 +#include <linux/moduleparam.h>
14257 +#include <linux/firmware.h>
14258 +#include <linux/netdevice.h>
14259 +#include <linux/usb.h>
14260 +#include <asm/olpc.h>
14261 +
14262 +#define DRV_NAME "usb8xxx"
14263 +
14264 +#include "host.h"
14265 +#include "decl.h"
14266 +#include "defs.h"
14267 +#include "dev.h"
14268 +#include "cmd.h"
14269 +#include "if_usb.h"
14270 +
14271 +#define INSANEDEBUG    0
14272 +#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
14273 +
14274 +#define MESSAGE_HEADER_LEN     4
14275 +
14276 +static char *lbs_fw_name = "usb8388.bin";
14277 +module_param_named(fw_name, lbs_fw_name, charp, 0644);
14278 +
14279 +static struct usb_device_id if_usb_table[] = {
14280 +       /* Enter the device signature inside */
14281 +       { USB_DEVICE(0x1286, 0x2001) },
14282 +       { USB_DEVICE(0x05a3, 0x8388) },
14283 +       {}      /* Terminating entry */
14284 +};
14285 +
14286 +MODULE_DEVICE_TABLE(usb, if_usb_table);
14287 +
14288 +static void if_usb_receive(struct urb *urb);
14289 +static void if_usb_receive_fwload(struct urb *urb);
14290 +static int if_usb_prog_firmware(struct if_usb_card *cardp,
14291 +                                       const char *fwname, int cmd);
14292 +static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
14293 +                              uint8_t *payload, uint16_t nb);
14294 +static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *);
14295 +static int if_usb_read_event_cause(struct lbs_private *);
14296 +static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
14297 +                       uint16_t nb);
14298 +static void if_usb_free(struct if_usb_card *cardp);
14299 +static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
14300 +static int if_usb_reset_device(struct if_usb_card *cardp);
14301 +
14302 +/**
14303 + *  @brief  call back function to handle the status of the URB
14304 + *  @param urb                 pointer to urb structure
14305 + *  @return            N/A
14306 + */
14307 +static void if_usb_write_bulk_callback(struct urb *urb)
14308 +{
14309 +       struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
14310 +
14311 +       /* handle the transmission complete validations */
14312 +
14313 +       if (urb->status == 0) {
14314 +               struct lbs_private *priv = cardp->priv;
14315 +
14316 +               lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
14317 +               lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
14318 +                            urb->actual_length);
14319 +
14320 +               /* Used for both firmware TX and regular TX.  priv isn't
14321 +                * valid at firmware load time.
14322 +                */
14323 +               if (priv)
14324 +                       lbs_host_to_card_done(priv);
14325 +       } else {
14326 +               /* print the failure status number for debug */
14327 +               lbs_pr_info("URB in failure status: %d\n", urb->status);
14328 +       }
14329 +
14330 +       return;
14331 +}
14332 +
14333 +/**
14334 + *  @brief  free tx/rx urb, skb and rx buffer
14335 + *  @param cardp       pointer if_usb_card
14336 + *  @return            N/A
14337 + */
14338 +static void if_usb_free(struct if_usb_card *cardp)
14339 +{
14340 +       lbs_deb_enter(LBS_DEB_USB);
14341 +
14342 +       /* Unlink tx & rx urb */
14343 +       usb_kill_urb(cardp->tx_urb);
14344 +       usb_kill_urb(cardp->rx_urb);
14345 +
14346 +       usb_free_urb(cardp->tx_urb);
14347 +       cardp->tx_urb = NULL;
14348 +
14349 +       usb_free_urb(cardp->rx_urb);
14350 +       cardp->rx_urb = NULL;
14351 +
14352 +       kfree(cardp->ep_out_buf);
14353 +       cardp->ep_out_buf = NULL;
14354 +
14355 +       lbs_deb_leave(LBS_DEB_USB);
14356 +}
14357 +
14358 +static void if_usb_setup_firmware(struct lbs_private *priv)
14359 +{
14360 +       struct cmd_ds_set_boot2_ver b2_cmd;
14361 +       struct cmd_ds_802_11_fw_wake_method wake_method;
14362 +
14363 +       b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
14364 +       b2_cmd.action = 0;
14365 +       b2_cmd.version = priv->boot2_version;
14366 +
14367 +       if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
14368 +               lbs_deb_usb("Setting boot2 version failed\n");
14369 +
14370 +       priv->wol_gpio = 2; /* Wake via GPIO2... */
14371 +       priv->wol_gap = 20; /* ... after 20ms    */
14372 +       lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
14373 +
14374 +       wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
14375 +       wake_method.action = cpu_to_le16(CMD_ACT_GET);
14376 +       if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
14377 +               lbs_pr_info("Firmware does not seem to support PS mode\n");
14378 +       } else {
14379 +               if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
14380 +                       lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
14381 +                       priv->ps_supported = 1;
14382 +               } else {
14383 +                       /* The versions which boot up this way don't seem to
14384 +                          work even if we set it to the command interrupt */
14385 +                       lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
14386 +               }
14387 +       }
14388 +}
14389 +
14390 +static void if_usb_fw_timeo(unsigned long priv)
14391 +{
14392 +       struct if_usb_card *cardp = (void *)priv;
14393 +
14394 +       if (cardp->fwdnldover) {
14395 +               lbs_deb_usb("Download complete, no event. Assuming success\n");
14396 +       } else {
14397 +               lbs_pr_err("Download timed out\n");
14398 +               cardp->surprise_removed = 1;
14399 +       }
14400 +       wake_up(&cardp->fw_wq);
14401 +}
14402 +
14403 +/**
14404 + *  @brief sets the configuration values
14405 + *  @param ifnum       interface number
14406 + *  @param id          pointer to usb_device_id
14407 + *  @return            0 on success, error code on failure
14408 + */
14409 +static int if_usb_probe(struct usb_interface *intf,
14410 +                       const struct usb_device_id *id)
14411 +{
14412 +       struct usb_device *udev;
14413 +       struct usb_host_interface *iface_desc;
14414 +       struct usb_endpoint_descriptor *endpoint;
14415 +       struct lbs_private *priv;
14416 +       struct if_usb_card *cardp;
14417 +       int i;
14418 +
14419 +       udev = interface_to_usbdev(intf);
14420 +
14421 +       cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
14422 +       if (!cardp) {
14423 +               lbs_pr_err("Out of memory allocating private data.\n");
14424 +               goto error;
14425 +       }
14426 +
14427 +       setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
14428 +       init_waitqueue_head(&cardp->fw_wq);
14429 +
14430 +       cardp->udev = udev;
14431 +       iface_desc = intf->cur_altsetting;
14432 +
14433 +       lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
14434 +                    " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
14435 +                    le16_to_cpu(udev->descriptor.bcdUSB),
14436 +                    udev->descriptor.bDeviceClass,
14437 +                    udev->descriptor.bDeviceSubClass,
14438 +                    udev->descriptor.bDeviceProtocol);
14439 +
14440 +       for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
14441 +               endpoint = &iface_desc->endpoint[i].desc;
14442 +               if (usb_endpoint_is_bulk_in(endpoint)) {
14443 +                       cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
14444 +                       cardp->ep_in = usb_endpoint_num(endpoint);
14445 +
14446 +                       lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
14447 +                       lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
14448 +
14449 +               } else if (usb_endpoint_is_bulk_out(endpoint)) {
14450 +                       cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
14451 +                       cardp->ep_out = usb_endpoint_num(endpoint);
14452 +
14453 +                       lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
14454 +                       lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
14455 +               }
14456 +       }
14457 +       if (!cardp->ep_out_size || !cardp->ep_in_size) {
14458 +               lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
14459 +               goto dealloc;
14460 +       }
14461 +       if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
14462 +               lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
14463 +               goto dealloc;
14464 +       }
14465 +       if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
14466 +               lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
14467 +               goto dealloc;
14468 +       }
14469 +       cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
14470 +       if (!cardp->ep_out_buf) {
14471 +               lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
14472 +               goto dealloc;
14473 +       }
14474 +
14475 +       /* Upload firmware */
14476 +       if (if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
14477 +               lbs_deb_usbd(&udev->dev, "FW upload failed\n");
14478 +               goto err_prog_firmware;
14479 +       }
14480 +
14481 +       if (!(priv = lbs_add_card(cardp, &udev->dev)))
14482 +               goto err_prog_firmware;
14483 +
14484 +       cardp->priv = priv;
14485 +       cardp->priv->fw_ready = 1;
14486 +
14487 +       priv->hw_host_to_card = if_usb_host_to_card;
14488 +       priv->hw_get_int_status = if_usb_get_int_status;
14489 +       priv->hw_read_event_cause = if_usb_read_event_cause;
14490 +       priv->boot2_version = udev->descriptor.bcdDevice;
14491 +
14492 +       if_usb_submit_rx_urb(cardp);
14493 +
14494 +       if (lbs_start_card(priv))
14495 +               goto err_start_card;
14496 +
14497 +       if_usb_setup_firmware(priv);
14498 +
14499 +       usb_get_dev(udev);
14500 +       usb_set_intfdata(intf, cardp);
14501 +
14502 +       return 0;
14503 +
14504 +err_start_card:
14505 +       lbs_remove_card(priv);
14506 +err_prog_firmware:
14507 +       if_usb_reset_device(cardp);
14508 +dealloc:
14509 +       if_usb_free(cardp);
14510 +
14511 +error:
14512 +       return -ENOMEM;
14513 +}
14514 +
14515 +/**
14516 + *  @brief free resource and cleanup
14517 + *  @param intf                USB interface structure
14518 + *  @return            N/A
14519 + */
14520 +static void if_usb_disconnect(struct usb_interface *intf)
14521 +{
14522 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
14523 +       struct lbs_private *priv = (struct lbs_private *) cardp->priv;
14524 +
14525 +       lbs_deb_enter(LBS_DEB_MAIN);
14526 +
14527 +       cardp->surprise_removed = 1;
14528 +
14529 +       if (priv) {
14530 +               priv->surpriseremoved = 1;
14531 +               lbs_stop_card(priv);
14532 +               lbs_remove_card(priv);
14533 +       }
14534 +
14535 +       /* Unlink and free urb */
14536 +       if_usb_free(cardp);
14537 +
14538 +       usb_set_intfdata(intf, NULL);
14539 +       usb_put_dev(interface_to_usbdev(intf));
14540 +
14541 +       lbs_deb_leave(LBS_DEB_MAIN);
14542 +}
14543 +
14544 +/**
14545 + *  @brief  This function download FW
14546 + *  @param priv                pointer to struct lbs_private
14547 + *  @return            0
14548 + */
14549 +static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
14550 +{
14551 +       struct fwdata *fwdata = cardp->ep_out_buf;
14552 +       uint8_t *firmware = cardp->fw->data;
14553 +
14554 +       /* If we got a CRC failure on the last block, back
14555 +          up and retry it */
14556 +       if (!cardp->CRC_OK) {
14557 +               cardp->totalbytes = cardp->fwlastblksent;
14558 +               cardp->fwseqnum--;
14559 +       }
14560 +
14561 +       lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
14562 +                    cardp->totalbytes);
14563 +
14564 +       /* struct fwdata (which we sent to the card) has an
14565 +          extra __le32 field in between the header and the data,
14566 +          which is not in the struct fwheader in the actual
14567 +          firmware binary. Insert the seqnum in the middle... */
14568 +       memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
14569 +              sizeof(struct fwheader));
14570 +
14571 +       cardp->fwlastblksent = cardp->totalbytes;
14572 +       cardp->totalbytes += sizeof(struct fwheader);
14573 +
14574 +       memcpy(fwdata->data, &firmware[cardp->totalbytes],
14575 +              le32_to_cpu(fwdata->hdr.datalength));
14576 +
14577 +       lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
14578 +                    le32_to_cpu(fwdata->hdr.datalength));
14579 +
14580 +       fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
14581 +       cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
14582 +
14583 +       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
14584 +                    le32_to_cpu(fwdata->hdr.datalength));
14585 +
14586 +       if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
14587 +               lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
14588 +               lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
14589 +                            cardp->fwseqnum, cardp->totalbytes);
14590 +       } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
14591 +               lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
14592 +               lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
14593 +
14594 +               cardp->fwfinalblk = 1;
14595 +       }
14596 +
14597 +       lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
14598 +                    cardp->totalbytes);
14599 +
14600 +       return 0;
14601 +}
14602 +
14603 +static int if_usb_reset_device(struct if_usb_card *cardp)
14604 +{
14605 +       struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
14606 +       int ret;
14607 +
14608 +       lbs_deb_enter(LBS_DEB_USB);
14609 +
14610 +       *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
14611 +
14612 +       cmd->command = cpu_to_le16(CMD_802_11_RESET);
14613 +       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
14614 +       cmd->result = cpu_to_le16(0);
14615 +       cmd->seqnum = cpu_to_le16(0x5a5a);
14616 +       cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
14617 +       usb_tx_block(cardp, cardp->ep_out_buf, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
14618 +
14619 +       msleep(100);
14620 +       ret = usb_reset_device(cardp->udev);
14621 +       msleep(100);
14622 +
14623 +#ifdef CONFIG_OLPC
14624 +       if (ret && machine_is_olpc()) {
14625 +               printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
14626 +               olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
14627 +       }
14628 +#endif
14629 +
14630 +       lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
14631 +
14632 +       return ret;
14633 +}
14634 +
14635 +/**
14636 + *  @brief This function transfer the data to the device.
14637 + *  @param priv        pointer to struct lbs_private
14638 + *  @param payload     pointer to payload data
14639 + *  @param nb          data length
14640 + *  @return            0 or -1
14641 + */
14642 +static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
14643 +{
14644 +       int ret = -1;
14645 +
14646 +       /* check if device is removed */
14647 +       if (cardp->surprise_removed) {
14648 +               lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
14649 +               goto tx_ret;
14650 +       }
14651 +
14652 +       usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
14653 +                         usb_sndbulkpipe(cardp->udev,
14654 +                                         cardp->ep_out),
14655 +                         payload, nb, if_usb_write_bulk_callback, cardp);
14656 +
14657 +       cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
14658 +
14659 +       if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
14660 +               lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
14661 +               ret = -1;
14662 +       } else {
14663 +               lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
14664 +               ret = 0;
14665 +       }
14666 +
14667 +tx_ret:
14668 +       return ret;
14669 +}
14670 +
14671 +static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
14672 +                                 void (*callbackfn)(struct urb *urb))
14673 +{
14674 +       struct sk_buff *skb;
14675 +       int ret = -1;
14676 +
14677 +       if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
14678 +               lbs_pr_err("No free skb\n");
14679 +               goto rx_ret;
14680 +       }
14681 +
14682 +       cardp->rx_skb = skb;
14683 +
14684 +       /* Fill the receive configuration URB and initialise the Rx call back */
14685 +       usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
14686 +                         usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
14687 +                         (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
14688 +                         MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
14689 +                         cardp);
14690 +
14691 +       cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
14692 +
14693 +       lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
14694 +       if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
14695 +               lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
14696 +               kfree_skb(skb);
14697 +               cardp->rx_skb = NULL;
14698 +               ret = -1;
14699 +       } else {
14700 +               lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
14701 +               ret = 0;
14702 +       }
14703 +
14704 +rx_ret:
14705 +       return ret;
14706 +}
14707 +
14708 +static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
14709 +{
14710 +       return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
14711 +}
14712 +
14713 +static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
14714 +{
14715 +       return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
14716 +}
14717 +
14718 +static void if_usb_receive_fwload(struct urb *urb)
14719 +{
14720 +       struct if_usb_card *cardp = urb->context;
14721 +       struct sk_buff *skb = cardp->rx_skb;
14722 +       struct fwsyncheader *syncfwheader;
14723 +       struct bootcmdresp bootcmdresp;
14724 +
14725 +       if (urb->status) {
14726 +               lbs_deb_usbd(&cardp->udev->dev,
14727 +                            "URB status is failed during fw load\n");
14728 +               kfree_skb(skb);
14729 +               return;
14730 +       }
14731 +
14732 +       if (cardp->fwdnldover) {
14733 +               __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
14734 +
14735 +               if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
14736 +                   tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
14737 +                       lbs_pr_info("Firmware ready event received\n");
14738 +                       wake_up(&cardp->fw_wq);
14739 +               } else {
14740 +                       lbs_deb_usb("Waiting for confirmation; got %x %x\n",
14741 +                                   le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
14742 +                       if_usb_submit_rx_urb_fwload(cardp);
14743 +               }
14744 +               kfree_skb(skb);
14745 +               return;
14746 +       }
14747 +       if (cardp->bootcmdresp <= 0) {
14748 +               memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
14749 +                       sizeof(bootcmdresp));
14750 +
14751 +               if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
14752 +                       kfree_skb(skb);
14753 +                       if_usb_submit_rx_urb_fwload(cardp);
14754 +                       cardp->bootcmdresp = 1;
14755 +                       lbs_deb_usbd(&cardp->udev->dev,
14756 +                                    "Received valid boot command response\n");
14757 +                       return;
14758 +               }
14759 +               if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
14760 +                       if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
14761 +                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
14762 +                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
14763 +                               if (!cardp->bootcmdresp)
14764 +                                       lbs_pr_info("Firmware already seems alive; resetting\n");
14765 +                               cardp->bootcmdresp = -1;
14766 +                       } else {
14767 +                               lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
14768 +                                           le32_to_cpu(bootcmdresp.magic));
14769 +                       }
14770 +               } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
14771 +                          (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
14772 +                          (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
14773 +                       lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
14774 +                                   bootcmdresp.cmd);
14775 +               } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
14776 +                       lbs_pr_info("boot cmd response result error (%d)\n",
14777 +                                   bootcmdresp.result);
14778 +               } else {
14779 +                       cardp->bootcmdresp = 1;
14780 +                       lbs_deb_usbd(&cardp->udev->dev,
14781 +                                    "Received valid boot command response\n");
14782 +               }
14783 +               kfree_skb(skb);
14784 +               if_usb_submit_rx_urb_fwload(cardp);
14785 +               return;
14786 +       }
14787 +
14788 +       syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
14789 +       if (!syncfwheader) {
14790 +               lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
14791 +               kfree_skb(skb);
14792 +               return;
14793 +       }
14794 +
14795 +       memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
14796 +              sizeof(struct fwsyncheader));
14797 +
14798 +       if (!syncfwheader->cmd) {
14799 +               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
14800 +               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
14801 +                            le32_to_cpu(syncfwheader->seqnum));
14802 +               cardp->CRC_OK = 1;
14803 +       } else {
14804 +               lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
14805 +               cardp->CRC_OK = 0;
14806 +       }
14807 +
14808 +       kfree_skb(skb);
14809 +
14810 +       /* Give device 5s to either write firmware to its RAM or eeprom */
14811 +       mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
14812 +
14813 +       if (cardp->fwfinalblk) {
14814 +               cardp->fwdnldover = 1;
14815 +               goto exit;
14816 +       }
14817 +
14818 +       if_usb_send_fw_pkt(cardp);
14819 +
14820 + exit:
14821 +       if_usb_submit_rx_urb_fwload(cardp);
14822 +
14823 +       kfree(syncfwheader);
14824 +
14825 +       return;
14826 +}
14827 +
14828 +#define MRVDRV_MIN_PKT_LEN     30
14829 +
14830 +static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
14831 +                                      struct if_usb_card *cardp,
14832 +                                      struct lbs_private *priv)
14833 +{
14834 +       if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
14835 +           || recvlength < MRVDRV_MIN_PKT_LEN) {
14836 +               lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
14837 +               kfree_skb(skb);
14838 +               return;
14839 +       }
14840 +
14841 +       skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
14842 +       skb_put(skb, recvlength);
14843 +       skb_pull(skb, MESSAGE_HEADER_LEN);
14844 +
14845 +       lbs_process_rxed_packet(priv, skb);
14846 +       priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
14847 +}
14848 +
14849 +static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
14850 +                                     struct sk_buff *skb,
14851 +                                     struct if_usb_card *cardp,
14852 +                                     struct lbs_private *priv)
14853 +{
14854 +       if (recvlength > LBS_CMD_BUFFER_SIZE) {
14855 +               lbs_deb_usbd(&cardp->udev->dev,
14856 +                            "The receive buffer is too large\n");
14857 +               kfree_skb(skb);
14858 +               return;
14859 +       }
14860 +
14861 +       if (!in_interrupt())
14862 +               BUG();
14863 +
14864 +       spin_lock(&priv->driver_lock);
14865 +       cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
14866 +       priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
14867 +       memcpy(priv->upld_buf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
14868 +
14869 +       kfree_skb(skb);
14870 +       lbs_interrupt(priv);
14871 +       spin_unlock(&priv->driver_lock);
14872 +
14873 +       lbs_deb_usbd(&cardp->udev->dev,
14874 +                   "Wake up main thread to handle cmd response\n");
14875 +}
14876 +
14877 +/**
14878 + *  @brief This function reads of the packet into the upload buff,
14879 + *  wake up the main thread and initialise the Rx callack.
14880 + *
14881 + *  @param urb         pointer to struct urb
14882 + *  @return            N/A
14883 + */
14884 +static void if_usb_receive(struct urb *urb)
14885 +{
14886 +       struct if_usb_card *cardp = urb->context;
14887 +       struct sk_buff *skb = cardp->rx_skb;
14888 +       struct lbs_private *priv = cardp->priv;
14889 +       int recvlength = urb->actual_length;
14890 +       uint8_t *recvbuff = NULL;
14891 +       uint32_t recvtype = 0;
14892 +       __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
14893 +
14894 +       lbs_deb_enter(LBS_DEB_USB);
14895 +
14896 +       if (recvlength) {
14897 +               if (urb->status) {
14898 +                       lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
14899 +                                    urb->status);
14900 +                       kfree_skb(skb);
14901 +                       goto setup_for_next;
14902 +               }
14903 +
14904 +               recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
14905 +               recvtype = le32_to_cpu(pkt[0]);
14906 +               lbs_deb_usbd(&cardp->udev->dev,
14907 +                           "Recv length = 0x%x, Recv type = 0x%X\n",
14908 +                           recvlength, recvtype);
14909 +       } else if (urb->status) {
14910 +               kfree_skb(skb);
14911 +               goto rx_exit;
14912 +       }
14913 +
14914 +       switch (recvtype) {
14915 +       case CMD_TYPE_DATA:
14916 +               process_cmdtypedata(recvlength, skb, cardp, priv);
14917 +               break;
14918 +
14919 +       case CMD_TYPE_REQUEST:
14920 +               process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
14921 +               break;
14922 +
14923 +       case CMD_TYPE_INDICATION:
14924 +               /* Event cause handling */
14925 +               spin_lock(&priv->driver_lock);
14926 +
14927 +               cardp->usb_event_cause = le32_to_cpu(pkt[1]);
14928 +
14929 +               lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
14930 +                            cardp->usb_event_cause);
14931 +
14932 +               /* Icky undocumented magic special case */
14933 +               if (cardp->usb_event_cause & 0xffff0000) {
14934 +                       lbs_send_tx_feedback(priv);
14935 +                       spin_unlock(&priv->driver_lock);
14936 +                       break;
14937 +               }
14938 +               cardp->usb_event_cause <<= 3;
14939 +               cardp->usb_int_cause |= MRVDRV_CARDEVENT;
14940 +               kfree_skb(skb);
14941 +               lbs_interrupt(priv);
14942 +               spin_unlock(&priv->driver_lock);
14943 +               goto rx_exit;
14944 +       default:
14945 +               lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
14946 +                            recvtype);
14947 +               kfree_skb(skb);
14948 +               break;
14949 +       }
14950 +
14951 +setup_for_next:
14952 +       if_usb_submit_rx_urb(cardp);
14953 +rx_exit:
14954 +       lbs_deb_leave(LBS_DEB_USB);
14955 +}
14956 +
14957 +/**
14958 + *  @brief This function downloads data to FW
14959 + *  @param priv                pointer to struct lbs_private structure
14960 + *  @param type                type of data
14961 + *  @param buf         pointer to data buffer
14962 + *  @param len         number of bytes
14963 + *  @return            0 or -1
14964 + */
14965 +static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
14966 +                              uint8_t *payload, uint16_t nb)
14967 +{
14968 +       struct if_usb_card *cardp = priv->card;
14969 +
14970 +       lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
14971 +       lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
14972 +
14973 +       if (type == MVMS_CMD) {
14974 +               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
14975 +               priv->dnld_sent = DNLD_CMD_SENT;
14976 +       } else {
14977 +               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
14978 +               priv->dnld_sent = DNLD_DATA_SENT;
14979 +       }
14980 +
14981 +       memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
14982 +
14983 +       return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
14984 +}
14985 +
14986 +/* called with priv->driver_lock held */
14987 +static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *ireg)
14988 +{
14989 +       struct if_usb_card *cardp = priv->card;
14990 +
14991 +       *ireg = cardp->usb_int_cause;
14992 +       cardp->usb_int_cause = 0;
14993 +
14994 +       lbs_deb_usbd(&cardp->udev->dev, "Int cause is 0x%X\n", *ireg);
14995 +
14996 +       return 0;
14997 +}
14998 +
14999 +static int if_usb_read_event_cause(struct lbs_private *priv)
15000 +{
15001 +       struct if_usb_card *cardp = priv->card;
15002 +
15003 +       priv->eventcause = cardp->usb_event_cause;
15004 +       /* Re-submit rx urb here to avoid event lost issue */
15005 +       if_usb_submit_rx_urb(cardp);
15006 +
15007 +       return 0;
15008 +}
15009 +
15010 +/**
15011 + *  @brief This function issues Boot command to the Boot2 code
15012 + *  @param ivalue   1:Boot from FW by USB-Download
15013 + *                  2:Boot from FW in EEPROM
15014 + *  @return            0
15015 + */
15016 +static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
15017 +{
15018 +       struct bootcmd *bootcmd = cardp->ep_out_buf;
15019 +
15020 +       /* Prepare command */
15021 +       bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
15022 +       bootcmd->cmd = ivalue;
15023 +       memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
15024 +
15025 +       /* Issue command */
15026 +       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
15027 +
15028 +       return 0;
15029 +}
15030 +
15031 +
15032 +/**
15033 + *  @brief This function checks the validity of Boot2/FW image.
15034 + *
15035 + *  @param data              pointer to image
15036 + *         len               image length
15037 + *  @return     0 or -1
15038 + */
15039 +static int check_fwfile_format(uint8_t *data, uint32_t totlen)
15040 +{
15041 +       uint32_t bincmd, exit;
15042 +       uint32_t blksize, offset, len;
15043 +       int ret;
15044 +
15045 +       ret = 1;
15046 +       exit = len = 0;
15047 +
15048 +       do {
15049 +               struct fwheader *fwh = (void *)data;
15050 +
15051 +               bincmd = le32_to_cpu(fwh->dnldcmd);
15052 +               blksize = le32_to_cpu(fwh->datalength);
15053 +               switch (bincmd) {
15054 +               case FW_HAS_DATA_TO_RECV:
15055 +                       offset = sizeof(struct fwheader) + blksize;
15056 +                       data += offset;
15057 +                       len += offset;
15058 +                       if (len >= totlen)
15059 +                               exit = 1;
15060 +                       break;
15061 +               case FW_HAS_LAST_BLOCK:
15062 +                       exit = 1;
15063 +                       ret = 0;
15064 +                       break;
15065 +               default:
15066 +                       exit = 1;
15067 +                       break;
15068 +               }
15069 +       } while (!exit);
15070 +
15071 +       if (ret)
15072 +               lbs_pr_err("firmware file format check FAIL\n");
15073 +       else
15074 +               lbs_deb_fw("firmware file format check PASS\n");
15075 +
15076 +       return ret;
15077 +}
15078 +
15079 +/**
15080 + *  @brief This function programs the firmware subject to cmd
15081 + *
15082 + *  @param cardp             the if_usb_card descriptor
15083 + *         fwname            firmware or boot2 image file name
15084 + *         cmd               either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
15085 + *                           or BOOT_CMD_UPDATE_BOOT2.
15086 + *  @return     0 or error code
15087 + */
15088 +static int if_usb_prog_firmware(struct if_usb_card *cardp,
15089 +                                       const char *fwname, int cmd)
15090 +{
15091 +       int i = 0;
15092 +       static int reset_count = 10;
15093 +       int ret = 0;
15094 +
15095 +       lbs_deb_enter(LBS_DEB_USB);
15096 +
15097 +       /* Don't mess with the firmware if the interface is up */
15098 +       if (cardp->priv &&
15099 +               (cardp->priv->mesh_open || cardp->priv->infra_open)) {
15100 +               ret = -EPERM;
15101 +               goto done;
15102 +       }
15103 +
15104 +       ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
15105 +       if (ret < 0) {
15106 +               lbs_pr_err("request_firmware() failed with %#x\n", ret);
15107 +               lbs_pr_err("firmware %s not found\n", fwname);
15108 +               goto done;
15109 +       }
15110 +
15111 +       if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
15112 +               ret = -EINVAL;
15113 +               goto release_fw;
15114 +       }
15115 +
15116 +       /* Cancel any pending usb business */
15117 +       usb_kill_urb(cardp->rx_urb);
15118 +       usb_kill_urb(cardp->tx_urb);
15119 +
15120 +       cardp->fwlastblksent = 0;
15121 +       cardp->fwdnldover = 0;
15122 +       cardp->totalbytes = 0;
15123 +       cardp->fwfinalblk = 0;
15124 +       cardp->bootcmdresp = 0;
15125 +
15126 +restart:
15127 +       if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
15128 +               lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
15129 +               ret = -EIO;
15130 +               goto release_fw;
15131 +       }
15132 +
15133 +       cardp->bootcmdresp = 0;
15134 +       do {
15135 +               int j = 0;
15136 +               i++;
15137 +               if_usb_issue_boot_command(cardp, cmd);
15138 +               /* wait for command response */
15139 +               do {
15140 +                       j++;
15141 +                       msleep_interruptible(100);
15142 +               } while (cardp->bootcmdresp == 0 && j < 10);
15143 +       } while (cardp->bootcmdresp == 0 && i < 5);
15144 +
15145 +       if (cardp->bootcmdresp <= 0) {
15146 +               if (--reset_count >= 0) {
15147 +                       if_usb_reset_device(cardp);
15148 +                       goto restart;
15149 +               }
15150 +               return -EIO;
15151 +       }
15152 +
15153 +       i = 0;
15154 +
15155 +       cardp->totalbytes = 0;
15156 +       cardp->fwlastblksent = 0;
15157 +       cardp->CRC_OK = 1;
15158 +       cardp->fwdnldover = 0;
15159 +       cardp->fwseqnum = -1;
15160 +       cardp->totalbytes = 0;
15161 +       cardp->fwfinalblk = 0;
15162 +
15163 +       /* Send the first firmware packet... */
15164 +       if_usb_send_fw_pkt(cardp);
15165 +
15166 +       /* ... and wait for the process to complete */
15167 +       wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
15168 +
15169 +       del_timer_sync(&cardp->fw_timeout);
15170 +       usb_kill_urb(cardp->rx_urb);
15171 +
15172 +       if (!cardp->fwdnldover) {
15173 +               lbs_pr_info("failed to load fw, resetting device!\n");
15174 +               if (--reset_count >= 0) {
15175 +                       if_usb_reset_device(cardp);
15176 +                       goto restart;
15177 +               }
15178 +
15179 +               lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
15180 +               ret = -EIO;
15181 +               goto release_fw;
15182 +       }
15183 +
15184 + release_fw:
15185 +       release_firmware(cardp->fw);
15186 +       cardp->fw = NULL;
15187 +
15188 + done:
15189 +       lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
15190 +       return ret;
15191 +}
15192 +
15193 +
15194 +#ifdef CONFIG_PM
15195 +static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
15196 +{
15197 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
15198 +       struct lbs_private *priv = cardp->priv;
15199 +       int ret;
15200 +
15201 +       lbs_deb_enter(LBS_DEB_USB);
15202 +
15203 +       if (priv->psstate != PS_STATE_FULL_POWER)
15204 +               return -1;
15205 +
15206 +       ret = lbs_suspend(priv);
15207 +       if (ret)
15208 +               goto out;
15209 +
15210 +       /* Unlink tx & rx urb */
15211 +       usb_kill_urb(cardp->tx_urb);
15212 +       usb_kill_urb(cardp->rx_urb);
15213 +
15214 + out:
15215 +       lbs_deb_leave(LBS_DEB_USB);
15216 +       return ret;
15217 +}
15218 +
15219 +static int if_usb_resume(struct usb_interface *intf)
15220 +{
15221 +       struct if_usb_card *cardp = usb_get_intfdata(intf);
15222 +       struct lbs_private *priv = cardp->priv;
15223 +
15224 +       lbs_deb_enter(LBS_DEB_USB);
15225 +
15226 +       if_usb_submit_rx_urb(cardp);
15227 +
15228 +       lbs_resume(priv);
15229 +
15230 +       lbs_deb_leave(LBS_DEB_USB);
15231 +       return 0;
15232 +}
15233 +#else
15234 +#define if_usb_suspend NULL
15235 +#define if_usb_resume NULL
15236 +#endif
15237 +
15238 +static struct usb_driver if_usb_driver = {
15239 +       .name = DRV_NAME,
15240 +       .probe = if_usb_probe,
15241 +       .disconnect = if_usb_disconnect,
15242 +       .id_table = if_usb_table,
15243 +       .suspend = if_usb_suspend,
15244 +       .resume = if_usb_resume,
15245 +};
15246 +
15247 +static int __init if_usb_init_module(void)
15248 +{
15249 +       int ret = 0;
15250 +
15251 +       lbs_deb_enter(LBS_DEB_MAIN);
15252 +
15253 +       ret = usb_register(&if_usb_driver);
15254 +
15255 +       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
15256 +       return ret;
15257 +}
15258 +
15259 +static void __exit if_usb_exit_module(void)
15260 +{
15261 +       lbs_deb_enter(LBS_DEB_MAIN);
15262 +
15263 +       usb_deregister(&if_usb_driver);
15264 +
15265 +       lbs_deb_leave(LBS_DEB_MAIN);
15266 +}
15267 +
15268 +module_init(if_usb_init_module);
15269 +module_exit(if_usb_exit_module);
15270 +
15271 +MODULE_DESCRIPTION("8388 USB WLAN Driver");
15272 +MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
15273 +MODULE_LICENSE("GPL");
15274 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.h linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.h
15275 --- linux-2.6.22-250/drivers/net/wireless/libertas/if_usb.h     2007-07-08 19:32:17.000000000 -0400
15276 +++ linux-2.6.22-300/drivers/net/wireless/libertas/if_usb.h     2008-06-05 18:10:06.000000000 -0400
15277 @@ -1,77 +1,75 @@
15278 -#ifndef _LIBERTAS_IF_USB_H
15279 -#define _LIBERTAS_IF_USB_H
15280 +#ifndef _LBS_IF_USB_H
15281 +#define _LBS_IF_USB_H
15282  
15283 -#include <linux/list.h>
15284 +#include <linux/wait.h>
15285 +#include <linux/timer.h>
15286 +
15287 +struct lbs_private;
15288  
15289  /**
15290    * This file contains definition for USB interface.
15291    */
15292 -#define CMD_TYPE_REQUEST                0xF00DFACE
15293 -#define CMD_TYPE_DATA                   0xBEADC0DE
15294 -#define CMD_TYPE_INDICATION             0xBEEFFACE
15295 -
15296 -#define IPFIELD_ALIGN_OFFSET   2
15297 -
15298 -#define BOOT_CMD_FW_BY_USB     0x01
15299 -#define BOOT_CMD_FW_IN_EEPROM  0x02
15300 -#define BOOT_CMD_UPDATE_BOOT2  0x03
15301 -#define BOOT_CMD_UPDATE_FW     0x04
15302 -#define BOOT_CMD_MAGIC_NUMBER  0x4C56524D   /* M=>0x4D,R=>0x52,V=>0x56,L=>0x4C */
15303 +#define CMD_TYPE_REQUEST               0xF00DFACE
15304 +#define CMD_TYPE_DATA                  0xBEADC0DE
15305 +#define CMD_TYPE_INDICATION            0xBEEFFACE
15306 +
15307 +#define IPFIELD_ALIGN_OFFSET           2
15308 +
15309 +#define BOOT_CMD_FW_BY_USB             0x01
15310 +#define BOOT_CMD_FW_IN_EEPROM          0x02
15311 +#define BOOT_CMD_UPDATE_BOOT2          0x03
15312 +#define BOOT_CMD_UPDATE_FW             0x04
15313 +#define BOOT_CMD_MAGIC_NUMBER          0x4C56524D   /* LVRM */
15314  
15315 -struct bootcmdstr
15316 +struct bootcmd
15317  {
15318 -       __le32 u32magicnumber;
15319 -       u8  u8cmd_tag;
15320 -       u8  au8dumy[11];
15321 +       __le32  magic;
15322 +       uint8_t cmd;
15323 +       uint8_t pad[11];
15324  };
15325  
15326 -#define BOOT_CMD_RESP_OK     0x0001
15327 -#define BOOT_CMD_RESP_FAIL   0x0000
15328 +#define BOOT_CMD_RESP_OK               0x0001
15329 +#define BOOT_CMD_RESP_FAIL             0x0000
15330  
15331 -struct bootcmdrespStr
15332 +struct bootcmdresp
15333  {
15334 -       __le32 u32magicnumber;
15335 -       u8  u8cmd_tag;
15336 -       u8  u8result;
15337 -       u8  au8dumy[2];
15338 -};
15339 -
15340 -/* read callback private data */
15341 -struct read_cb_info {
15342 -        wlan_private *priv;
15343 -        struct sk_buff *skb;
15344 +       __le32  magic;
15345 +       uint8_t cmd;
15346 +       uint8_t result;
15347 +       uint8_t pad[2];
15348  };
15349  
15350  /** USB card description structure*/
15351 -struct usb_card_rec {
15352 -       struct list_head list;
15353 -       struct net_device *eth_dev;
15354 +struct if_usb_card {
15355         struct usb_device *udev;
15356         struct urb *rx_urb, *tx_urb;
15357 -       void *priv;
15358 -       struct read_cb_info rinfo;
15359 -
15360 -       int bulk_in_size;
15361 -       u8 bulk_in_endpointAddr;
15362 +       struct lbs_private *priv;
15363  
15364 -       u8 *bulk_out_buffer;
15365 -       int bulk_out_size;
15366 -       u8 bulk_out_endpointAddr;
15367 -
15368 -       u8 CRC_OK;
15369 -       u32 fwseqnum;
15370 -       u32 lastseqnum;
15371 -       u32 totalbytes;
15372 -       u32 fwlastblksent;
15373 -       u8 fwdnldover;
15374 -       u8 fwfinalblk;
15375 +       struct sk_buff *rx_skb;
15376 +       uint32_t usb_event_cause;
15377 +       uint8_t usb_int_cause;
15378 +
15379 +       uint8_t ep_in;
15380 +       uint8_t ep_out;
15381 +
15382 +       int8_t bootcmdresp;
15383 +
15384 +       int ep_in_size;
15385 +
15386 +       void *ep_out_buf;
15387 +       int ep_out_size;
15388 +
15389 +       const struct firmware *fw;
15390 +       struct timer_list fw_timeout;
15391 +       wait_queue_head_t fw_wq;
15392 +       uint32_t fwseqnum;
15393 +       uint32_t totalbytes;
15394 +       uint32_t fwlastblksent;
15395 +       uint8_t CRC_OK;
15396 +       uint8_t fwdnldover;
15397 +       uint8_t fwfinalblk;
15398 +       uint8_t surprise_removed;
15399  
15400 -       u32 usb_event_cause;
15401 -       u8 usb_int_cause;
15402 -
15403 -       u8 rx_urb_recall;
15404 -
15405 -       u8 bootcmdresp;
15406  };
15407  
15408  /** fwheader */
15409 @@ -84,10 +82,10 @@ struct fwheader {
15410  
15411  #define FW_MAX_DATA_BLK_SIZE   600
15412  /** FWData */
15413 -struct FWData {
15414 -       struct fwheader fwheader;
15415 +struct fwdata {
15416 +       struct fwheader hdr;
15417         __le32 seqnum;
15418 -       u8 data[FW_MAX_DATA_BLK_SIZE];
15419 +       uint8_t data[0];
15420  };
15421  
15422  /** fwsyncheader */
15423 @@ -99,11 +97,5 @@ struct fwsyncheader {
15424  #define FW_HAS_DATA_TO_RECV            0x00000001
15425  #define FW_HAS_LAST_BLOCK              0x00000004
15426  
15427 -#define FW_DATA_XMIT_SIZE \
15428 -       sizeof(struct fwheader) + le32_to_cpu(fwdata->fwheader.datalength) + sizeof(u32)
15429 -
15430 -int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
15431 -void if_usb_free(struct usb_card_rec *cardp);
15432 -int if_usb_issue_boot_command(wlan_private *priv, int ivalue);
15433  
15434  #endif
15435 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/ioctl.c linux-2.6.22-300/drivers/net/wireless/libertas/ioctl.c
15436 --- linux-2.6.22-250/drivers/net/wireless/libertas/ioctl.c      1969-12-31 19:00:00.000000000 -0500
15437 +++ linux-2.6.22-300/drivers/net/wireless/libertas/ioctl.c      2008-06-05 18:10:06.000000000 -0400
15438 @@ -0,0 +1,1251 @@
15439 +/**
15440 +  * This file contains ioctl functions
15441 +  */
15442 +
15443 +#include <linux/ctype.h>
15444 +#include <linux/delay.h>
15445 +#include <linux/if.h>
15446 +#include <linux/if_arp.h>
15447 +#include <linux/wireless.h>
15448 +
15449 +#include <net/iw_handler.h>
15450 +#include <net/ieee80211.h>
15451 +
15452 +#include "host.h"
15453 +#include "radiotap.h"
15454 +#include "decl.h"
15455 +#include "defs.h"
15456 +#include "dev.h"
15457 +#include "join.h"
15458 +#include "wext.h"
15459 +#include "cmd.h"
15460 +#include "ioctl.h"
15461 +
15462 +#define MAX_SCAN_CELL_SIZE      (IW_EV_ADDR_LEN + \
15463 +                               IW_ESSID_MAX_SIZE + \
15464 +                               IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \
15465 +                               IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \
15466 +                               IW_EV_PARAM_LEN + 40)   /* 40 for WPAIE */
15467 +
15468 +#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
15469 +
15470 +static int lbs_set_region(struct lbs_private * priv, u16 region_code)
15471 +{
15472 +       int i;
15473 +       int ret = 0;
15474 +
15475 +       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
15476 +               // use the region code to search for the index
15477 +               if (region_code == lbs_region_code_to_index[i]) {
15478 +                       priv->regioncode = region_code;
15479 +                       break;
15480 +               }
15481 +       }
15482 +
15483 +       // if it's unidentified region code
15484 +       if (i >= MRVDRV_MAX_REGION_CODE) {
15485 +               lbs_deb_ioctl("region Code not identified\n");
15486 +               ret = -1;
15487 +               goto done;
15488 +       }
15489 +
15490 +       if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
15491 +               ret = -EINVAL;
15492 +       }
15493 +
15494 +done:
15495 +       lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
15496 +       return ret;
15497 +}
15498 +
15499 +static inline int hex2int(char c)
15500 +{
15501 +       if (c >= '0' && c <= '9')
15502 +               return (c - '0');
15503 +       if (c >= 'a' && c <= 'f')
15504 +               return (c - 'a' + 10);
15505 +       if (c >= 'A' && c <= 'F')
15506 +               return (c - 'A' + 10);
15507 +       return -1;
15508 +}
15509 +
15510 +/* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx")
15511 +   into binary format (6 bytes).
15512 +
15513 +   This function expects that each byte is represented with 2 characters
15514 +   (e.g., 11:2:11:11:11:11 is invalid)
15515 +
15516 + */
15517 +static char *eth_str2addr(char *ethstr, u8 * addr)
15518 +{
15519 +       int i, val, val2;
15520 +       char *pos = ethstr;
15521 +
15522 +       /* get rid of initial blanks */
15523 +       while (*pos == ' ' || *pos == '\t')
15524 +               ++pos;
15525 +
15526 +       for (i = 0; i < 6; i++) {
15527 +               val = hex2int(*pos++);
15528 +               if (val < 0)
15529 +                       return NULL;
15530 +               val2 = hex2int(*pos++);
15531 +               if (val2 < 0)
15532 +                       return NULL;
15533 +               addr[i] = (val * 16 + val2) & 0xff;
15534 +
15535 +               if (i < 5 && *pos++ != ':')
15536 +                       return NULL;
15537 +       }
15538 +       return pos;
15539 +}
15540 +
15541 +/* this writes xx:xx:xx:xx:xx:xx into ethstr
15542 +   (ethstr must have space for 18 chars) */
15543 +static int eth_addr2str(u8 * addr, char *ethstr)
15544 +{
15545 +       int i;
15546 +       char *pos = ethstr;
15547 +
15548 +       for (i = 0; i < 6; i++) {
15549 +               sprintf(pos, "%02x", addr[i] & 0xff);
15550 +               pos += 2;
15551 +               if (i < 5)
15552 +                       *pos++ = ':';
15553 +       }
15554 +       return 17;
15555 +}
15556 +
15557 +/**
15558 + *  @brief          Add an entry to the BT table
15559 + *  @param priv     A pointer to struct lbs_private structure
15560 + *  @param req      A pointer to ifreq structure
15561 + *  @return         0 --success, otherwise fail
15562 + */
15563 +static int lbs_bt_add_ioctl(struct lbs_private * priv, struct ifreq *req)
15564 +{
15565 +       struct iwreq *wrq = (struct iwreq *)req;
15566 +       char ethaddrs_str[18];
15567 +       char *pos;
15568 +       u8 ethaddr[ETH_ALEN];
15569 +       int ret;
15570 +
15571 +       lbs_deb_enter(LBS_DEB_IOCTL);
15572 +
15573 +       if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
15574 +                          sizeof(ethaddrs_str)))
15575 +               return -EFAULT;
15576 +
15577 +       if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
15578 +               lbs_pr_info("BT_ADD: Invalid MAC address\n");
15579 +               return -EINVAL;
15580 +       }
15581 +
15582 +       lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str);
15583 +       ret = lbs_prepare_and_send_command(priv, CMD_BT_ACCESS,
15584 +                                     CMD_ACT_BT_ACCESS_ADD,
15585 +                                     CMD_OPTION_WAITFORRSP, 0, ethaddr);
15586 +       lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
15587 +       return ret;
15588 +}
15589 +
15590 +/**
15591 + *  @brief          Delete an entry from the BT table
15592 + *  @param priv     A pointer to struct lbs_private structure
15593 + *  @param req      A pointer to ifreq structure
15594 + *  @return         0 --success, otherwise fail
15595 + */
15596 +static int lbs_bt_del_ioctl(struct lbs_private * priv, struct ifreq *req)
15597 +{
15598 +       struct iwreq *wrq = (struct iwreq *)req;
15599 +       char ethaddrs_str[18];
15600 +       u8 ethaddr[ETH_ALEN];
15601 +       char *pos;
15602 +
15603 +       lbs_deb_enter(LBS_DEB_IOCTL);
15604 +
15605 +       if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
15606 +                          sizeof(ethaddrs_str)))
15607 +               return -EFAULT;
15608 +
15609 +       if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
15610 +               lbs_pr_info("Invalid MAC address\n");
15611 +               return -EINVAL;
15612 +       }
15613 +
15614 +       lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str);
15615 +
15616 +       return (lbs_prepare_and_send_command(priv,
15617 +                                     CMD_BT_ACCESS,
15618 +                                     CMD_ACT_BT_ACCESS_DEL,
15619 +                                     CMD_OPTION_WAITFORRSP, 0, ethaddr));
15620 +
15621 +       lbs_deb_leave(LBS_DEB_IOCTL);
15622 +       return 0;
15623 +}
15624 +
15625 +/**
15626 + *  @brief          Reset all entries from the BT table
15627 + *  @param priv     A pointer to struct lbs_private structure
15628 + *  @return         0 --success, otherwise fail
15629 + */
15630 +static int lbs_bt_reset_ioctl(struct lbs_private * priv)
15631 +{
15632 +       lbs_deb_enter(LBS_DEB_IOCTL);
15633 +
15634 +       lbs_pr_alert( "BT: resetting\n");
15635 +
15636 +       return (lbs_prepare_and_send_command(priv,
15637 +                                     CMD_BT_ACCESS,
15638 +                                     CMD_ACT_BT_ACCESS_RESET,
15639 +                                     CMD_OPTION_WAITFORRSP, 0, NULL));
15640 +
15641 +       lbs_deb_leave(LBS_DEB_IOCTL);
15642 +       return 0;
15643 +}
15644 +
15645 +/**
15646 + *  @brief          List an entry from the BT table
15647 + *  @param priv     A pointer to struct lbs_private structure
15648 + *  @param req      A pointer to ifreq structure
15649 + *  @return         0 --success, otherwise fail
15650 + */
15651 +static int lbs_bt_list_ioctl(struct lbs_private * priv, struct ifreq *req)
15652 +{
15653 +       int pos;
15654 +       char *addr1;
15655 +       struct iwreq *wrq = (struct iwreq *)req;
15656 +       /* used to pass id and store the bt entry returned by the FW */
15657 +       union {
15658 +               u32 id;
15659 +               char addr1addr2[2 * ETH_ALEN];
15660 +       } param;
15661 +       static char outstr[64];
15662 +       char *pbuf = outstr;
15663 +       int ret;
15664 +
15665 +       lbs_deb_enter(LBS_DEB_IOCTL);
15666 +
15667 +       if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
15668 +               lbs_deb_ioctl("Copy from user failed\n");
15669 +               return -1;
15670 +       }
15671 +       param.id = simple_strtoul(outstr, NULL, 10);
15672 +       pos = sprintf(pbuf, "%d: ", param.id);
15673 +       pbuf += pos;
15674 +
15675 +       ret = lbs_prepare_and_send_command(priv, CMD_BT_ACCESS,
15676 +                                   CMD_ACT_BT_ACCESS_LIST,
15677 +                                   CMD_OPTION_WAITFORRSP, 0,
15678 +                                   (char *)&param);
15679 +
15680 +       if (ret == 0) {
15681 +               addr1 = param.addr1addr2;
15682 +
15683 +               pos = sprintf(pbuf, "BT includes node ");
15684 +               pbuf += pos;
15685 +               pos = eth_addr2str(addr1, pbuf);
15686 +               pbuf += pos;
15687 +       } else {
15688 +               sprintf(pbuf, "(null)");
15689 +               pbuf += pos;
15690 +       }
15691 +
15692 +       wrq->u.data.length = strlen(outstr);
15693 +       if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
15694 +                        wrq->u.data.length)) {
15695 +               lbs_deb_ioctl("BT_LIST: Copy to user failed!\n");
15696 +               return -EFAULT;
15697 +       }
15698 +
15699 +       lbs_deb_leave(LBS_DEB_IOCTL);
15700 +       return 0 ;
15701 +}
15702 +
15703 +/**
15704 + *  @brief          Sets inverted state of blacklist (non-zero if inverted)
15705 + *  @param priv     A pointer to struct lbs_private structure
15706 + *  @param req      A pointer to ifreq structure
15707 + *  @return         0 --success, otherwise fail
15708 + */
15709 +static int lbs_bt_set_invert_ioctl(struct lbs_private * priv, struct ifreq *req)
15710 +{
15711 +       int ret;
15712 +       struct iwreq *wrq = (struct iwreq *)req;
15713 +       union {
15714 +               u32 id;
15715 +               char addr1addr2[2 * ETH_ALEN];
15716 +       } param;
15717 +
15718 +       lbs_deb_enter(LBS_DEB_IOCTL);
15719 +
15720 +       param.id = SUBCMD_DATA(wrq) ;
15721 +       ret = lbs_prepare_and_send_command(priv, CMD_BT_ACCESS,
15722 +                                   CMD_ACT_BT_ACCESS_SET_INVERT,
15723 +                                   CMD_OPTION_WAITFORRSP, 0,
15724 +                                   (char *)&param);
15725 +       if (ret != 0)
15726 +               return -EFAULT;
15727 +       lbs_deb_leave(LBS_DEB_IOCTL);
15728 +       return 0;
15729 +}
15730 +
15731 +/**
15732 + *  @brief          Gets inverted state of blacklist (non-zero if inverted)
15733 + *  @param priv     A pointer to struct lbs_private structure
15734 + *  @param req      A pointer to ifreq structure
15735 + *  @return         0 --success, otherwise fail
15736 + */
15737 +static int lbs_bt_get_invert_ioctl(struct lbs_private * priv, struct ifreq *req)
15738 +{
15739 +       struct iwreq *wrq = (struct iwreq *)req;
15740 +       int ret;
15741 +       union {
15742 +               __le32 id;
15743 +               char addr1addr2[2 * ETH_ALEN];
15744 +       } param;
15745 +
15746 +       lbs_deb_enter(LBS_DEB_IOCTL);
15747 +
15748 +       ret = lbs_prepare_and_send_command(priv, CMD_BT_ACCESS,
15749 +                                   CMD_ACT_BT_ACCESS_GET_INVERT,
15750 +                                   CMD_OPTION_WAITFORRSP, 0,
15751 +                                   (char *)&param);
15752 +
15753 +       if (ret == 0)
15754 +               wrq->u.param.value = le32_to_cpu(param.id);
15755 +       else
15756 +               return -EFAULT;
15757 +
15758 +       lbs_deb_leave(LBS_DEB_IOCTL);
15759 +       return 0;
15760 +}
15761 +
15762 +/**
15763 + *  @brief          Find the next parameter in an input string
15764 + *  @param ptr      A pointer to the input parameter string
15765 + *  @return         A pointer to the next parameter, or 0 if no parameters left.
15766 + */
15767 +static char * next_param(char * ptr)
15768 +{
15769 +       if (!ptr) return NULL;
15770 +       while (*ptr == ' ' || *ptr == '\t') ++ptr;
15771 +       return (*ptr == '\0') ? NULL : ptr;
15772 +}
15773 +
15774 +/**
15775 + *  @brief          Add an entry to the FWT table
15776 + *  @param priv     A pointer to struct lbs_private structure
15777 + *  @param req      A pointer to ifreq structure
15778 + *  @return         0 --success, otherwise fail
15779 + */
15780 +static int lbs_fwt_add_ioctl(struct lbs_private * priv, struct ifreq *req)
15781 +{
15782 +       struct iwreq *wrq = (struct iwreq *)req;
15783 +       char in_str[128];
15784 +       static struct cmd_ds_fwt_access fwt_access;
15785 +       char *ptr;
15786 +       int ret;
15787 +
15788 +       lbs_deb_enter(LBS_DEB_IOCTL);
15789 +
15790 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
15791 +               return -EFAULT;
15792 +
15793 +       if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
15794 +               lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n");
15795 +               return -EINVAL;
15796 +       }
15797 +
15798 +       if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
15799 +               lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n");
15800 +               return -EINVAL;
15801 +       }
15802 +
15803 +       if ((ptr = next_param(ptr)))
15804 +               fwt_access.metric =
15805 +                       cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
15806 +       else
15807 +               fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC);
15808 +
15809 +       if ((ptr = next_param(ptr)))
15810 +               fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
15811 +       else
15812 +               fwt_access.dir = FWT_DEFAULT_DIR;
15813 +
15814 +       if ((ptr = next_param(ptr)))
15815 +               fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10);
15816 +       else
15817 +               fwt_access.rate = FWT_DEFAULT_RATE;
15818 +
15819 +       if ((ptr = next_param(ptr)))
15820 +               fwt_access.ssn =
15821 +                       cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
15822 +       else
15823 +               fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN);
15824 +
15825 +       if ((ptr = next_param(ptr)))
15826 +               fwt_access.dsn =
15827 +                       cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
15828 +       else
15829 +               fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN);
15830 +
15831 +       if ((ptr = next_param(ptr)))
15832 +               fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
15833 +       else
15834 +               fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT;
15835 +
15836 +       if ((ptr = next_param(ptr)))
15837 +               fwt_access.ttl = simple_strtoul(ptr, &ptr, 10);
15838 +       else
15839 +               fwt_access.ttl = FWT_DEFAULT_TTL;
15840 +
15841 +       if ((ptr = next_param(ptr)))
15842 +               fwt_access.expiration =
15843 +                       cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
15844 +       else
15845 +               fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION);
15846 +
15847 +       if ((ptr = next_param(ptr)))
15848 +               fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
15849 +       else
15850 +               fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE;
15851 +
15852 +       if ((ptr = next_param(ptr)))
15853 +               fwt_access.snr =
15854 +                       cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
15855 +       else
15856 +               fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR);
15857 +
15858 +#ifdef DEBUG
15859 +       {
15860 +               char ethaddr1_str[18], ethaddr2_str[18];
15861 +               eth_addr2str(fwt_access.da, ethaddr1_str);
15862 +               eth_addr2str(fwt_access.ra, ethaddr2_str);
15863 +               lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
15864 +                      fwt_access.dir, ethaddr2_str);
15865 +               lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
15866 +                      fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
15867 +                      fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
15868 +                      fwt_access.sleepmode, fwt_access.snr);
15869 +       }
15870 +#endif
15871 +
15872 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
15873 +                                               CMD_ACT_FWT_ACCESS_ADD,
15874 +                                               CMD_OPTION_WAITFORRSP, 0,
15875 +                                               (void *)&fwt_access);
15876 +
15877 +       lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
15878 +       return ret;
15879 +}
15880 +
15881 +/**
15882 + *  @brief          Delete an entry from the FWT table
15883 + *  @param priv     A pointer to struct lbs_private structure
15884 + *  @param req      A pointer to ifreq structure
15885 + *  @return         0 --success, otherwise fail
15886 + */
15887 +static int lbs_fwt_del_ioctl(struct lbs_private * priv, struct ifreq *req)
15888 +{
15889 +       struct iwreq *wrq = (struct iwreq *)req;
15890 +       char in_str[64];
15891 +       static struct cmd_ds_fwt_access fwt_access;
15892 +       char *ptr;
15893 +       int ret;
15894 +
15895 +       lbs_deb_enter(LBS_DEB_IOCTL);
15896 +
15897 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
15898 +               return -EFAULT;
15899 +
15900 +       if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
15901 +               lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n");
15902 +               return -EINVAL;
15903 +       }
15904 +
15905 +       if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
15906 +               lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n");
15907 +               return -EINVAL;
15908 +       }
15909 +
15910 +       if ((ptr = next_param(ptr)))
15911 +               fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
15912 +       else
15913 +               fwt_access.dir = FWT_DEFAULT_DIR;
15914 +
15915 +#ifdef DEBUG
15916 +       {
15917 +               char ethaddr1_str[18], ethaddr2_str[18];
15918 +               lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str);
15919 +               eth_addr2str(fwt_access.da, ethaddr1_str);
15920 +               eth_addr2str(fwt_access.ra, ethaddr2_str);
15921 +               lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
15922 +                      ethaddr2_str, fwt_access.dir);
15923 +       }
15924 +#endif
15925 +
15926 +       ret = lbs_prepare_and_send_command(priv,
15927 +                                               CMD_FWT_ACCESS,
15928 +                                               CMD_ACT_FWT_ACCESS_DEL,
15929 +                                               CMD_OPTION_WAITFORRSP, 0,
15930 +                                               (void *)&fwt_access);
15931 +       lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
15932 +       return ret;
15933 +}
15934 +
15935 +
15936 +/**
15937 + *  @brief             Print route parameters
15938 + *  @param fwt_access  struct cmd_ds_fwt_access with route info
15939 + *  @param buf         destination buffer for route info
15940 + */
15941 +static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
15942 +{
15943 +       buf += sprintf(buf, " ");
15944 +       buf += eth_addr2str(fwt_access.da, buf);
15945 +       buf += sprintf(buf, " ");
15946 +       buf += eth_addr2str(fwt_access.ra, buf);
15947 +       buf += sprintf(buf, " %u", fwt_access.valid);
15948 +       buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
15949 +       buf += sprintf(buf, " %u", fwt_access.dir);
15950 +       buf += sprintf(buf, " %u", fwt_access.rate);
15951 +       buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
15952 +       buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
15953 +       buf += sprintf(buf, " %u", fwt_access.hopcount);
15954 +       buf += sprintf(buf, " %u", fwt_access.ttl);
15955 +       buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
15956 +       buf += sprintf(buf, " %u", fwt_access.sleepmode);
15957 +       buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr));
15958 +       buf += eth_addr2str(fwt_access.prec, buf);
15959 +}
15960 +
15961 +/**
15962 + *  @brief          Lookup an entry in the FWT table
15963 + *  @param priv     A pointer to struct lbs_private structure
15964 + *  @param req      A pointer to ifreq structure
15965 + *  @return         0 --success, otherwise fail
15966 + */
15967 +static int lbs_fwt_lookup_ioctl(struct lbs_private * priv, struct ifreq *req)
15968 +{
15969 +       struct iwreq *wrq = (struct iwreq *)req;
15970 +       char in_str[64];
15971 +       char *ptr;
15972 +       static struct cmd_ds_fwt_access fwt_access;
15973 +       static char out_str[128];
15974 +       int ret;
15975 +
15976 +       lbs_deb_enter(LBS_DEB_IOCTL);
15977 +
15978 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
15979 +               return -EFAULT;
15980 +
15981 +       if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
15982 +               lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n");
15983 +               return -EINVAL;
15984 +       }
15985 +
15986 +#ifdef DEBUG
15987 +       {
15988 +               char ethaddr1_str[18];
15989 +               lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str);
15990 +               eth_addr2str(fwt_access.da, ethaddr1_str);
15991 +               lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
15992 +       }
15993 +#endif
15994 +
15995 +       ret = lbs_prepare_and_send_command(priv,
15996 +                                               CMD_FWT_ACCESS,
15997 +                                               CMD_ACT_FWT_ACCESS_LOOKUP,
15998 +                                               CMD_OPTION_WAITFORRSP, 0,
15999 +                                               (void *)&fwt_access);
16000 +
16001 +       if (ret == 0)
16002 +               print_route(fwt_access, out_str);
16003 +       else
16004 +               sprintf(out_str, "(null)");
16005 +
16006 +       wrq->u.data.length = strlen(out_str);
16007 +       if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
16008 +                        wrq->u.data.length)) {
16009 +               lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n");
16010 +               return -EFAULT;
16011 +       }
16012 +
16013 +       lbs_deb_leave(LBS_DEB_IOCTL);
16014 +       return 0;
16015 +}
16016 +
16017 +/**
16018 + *  @brief          Reset all entries from the FWT table
16019 + *  @param priv     A pointer to struct lbs_private structure
16020 + *  @return         0 --success, otherwise fail
16021 + */
16022 +static int lbs_fwt_reset_ioctl(struct lbs_private * priv)
16023 +{
16024 +       lbs_deb_ioctl("FWT: resetting\n");
16025 +
16026 +       return (lbs_prepare_and_send_command(priv,
16027 +                                     CMD_FWT_ACCESS,
16028 +                                     CMD_ACT_FWT_ACCESS_RESET,
16029 +                                     CMD_OPTION_WAITFORRSP, 0, NULL));
16030 +}
16031 +
16032 +/**
16033 + *  @brief          List an entry from the FWT table
16034 + *  @param priv     A pointer to struct lbs_private structure
16035 + *  @param req      A pointer to ifreq structure
16036 + *  @return         0 --success, otherwise fail
16037 + */
16038 +static int lbs_fwt_list_ioctl(struct lbs_private * priv, struct ifreq *req)
16039 +{
16040 +       struct iwreq *wrq = (struct iwreq *)req;
16041 +       char in_str[8];
16042 +       static struct cmd_ds_fwt_access fwt_access;
16043 +       char *ptr = in_str;
16044 +       static char out_str[128];
16045 +       char *pbuf = out_str;
16046 +       int ret = 0;
16047 +
16048 +       lbs_deb_enter(LBS_DEB_IOCTL);
16049 +
16050 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) {
16051 +               ret = -EFAULT;
16052 +               goto out;
16053 +       }
16054 +
16055 +       fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
16056 +
16057 +#ifdef DEBUG
16058 +       {
16059 +               lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str);
16060 +               lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
16061 +       }
16062 +#endif
16063 +
16064 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
16065 +                                   CMD_ACT_FWT_ACCESS_LIST,
16066 +                                   CMD_OPTION_WAITFORRSP, 0, (void *)&fwt_access);
16067 +
16068 +       if (ret == 0)
16069 +               print_route(fwt_access, pbuf);
16070 +       else
16071 +               pbuf += sprintf(pbuf, " (null)");
16072 +
16073 +       wrq->u.data.length = strlen(out_str);
16074 +       if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
16075 +                        wrq->u.data.length)) {
16076 +               lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n");
16077 +               ret = -EFAULT;
16078 +               goto out;
16079 +       }
16080 +
16081 +       ret = 0;
16082 +
16083 +out:
16084 +       lbs_deb_leave(LBS_DEB_IOCTL);
16085 +       return ret;
16086 +}
16087 +
16088 +/**
16089 + *  @brief          List an entry from the FRT table
16090 + *  @param priv     A pointer to struct lbs_private structure
16091 + *  @param req      A pointer to ifreq structure
16092 + *  @return         0 --success, otherwise fail
16093 + */
16094 +static int lbs_fwt_list_route_ioctl(struct lbs_private * priv, struct ifreq *req)
16095 +{
16096 +       struct iwreq *wrq = (struct iwreq *)req;
16097 +       char in_str[64];
16098 +       static struct cmd_ds_fwt_access fwt_access;
16099 +       char *ptr = in_str;
16100 +       static char out_str[128];
16101 +       char *pbuf = out_str;
16102 +       int ret;
16103 +
16104 +       lbs_deb_enter(LBS_DEB_IOCTL);
16105 +
16106 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
16107 +               return -EFAULT;
16108 +
16109 +       fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
16110 +
16111 +#ifdef DEBUG
16112 +       {
16113 +               lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str);
16114 +               lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
16115 +       }
16116 +#endif
16117 +
16118 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
16119 +                                   CMD_ACT_FWT_ACCESS_LIST_ROUTE,
16120 +                                   CMD_OPTION_WAITFORRSP, 0, (void *)&fwt_access);
16121 +
16122 +       if (ret == 0) {
16123 +               print_route(fwt_access, pbuf);
16124 +       } else
16125 +               pbuf += sprintf(pbuf, " (null)");
16126 +
16127 +       wrq->u.data.length = strlen(out_str);
16128 +       if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
16129 +                        wrq->u.data.length)) {
16130 +               lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n");
16131 +               return -EFAULT;
16132 +       }
16133 +
16134 +       lbs_deb_leave(LBS_DEB_IOCTL);
16135 +       return 0;
16136 +}
16137 +
16138 +/**
16139 + *  @brief          List an entry from the FNT table
16140 + *  @param priv     A pointer to struct lbs_private structure
16141 + *  @param req      A pointer to ifreq structure
16142 + *  @return         0 --success, otherwise fail
16143 + */
16144 +static int lbs_fwt_list_neighbor_ioctl(struct lbs_private * priv, struct ifreq *req)
16145 +{
16146 +       struct iwreq *wrq = (struct iwreq *)req;
16147 +       char in_str[8];
16148 +       static struct cmd_ds_fwt_access fwt_access;
16149 +       char *ptr = in_str;
16150 +       static char out_str[128];
16151 +       char *pbuf = out_str;
16152 +       int ret;
16153 +
16154 +       lbs_deb_enter(LBS_DEB_IOCTL);
16155 +
16156 +       if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
16157 +               return -EFAULT;
16158 +
16159 +       memset(&fwt_access, 0, sizeof(fwt_access));
16160 +       fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
16161 +
16162 +#ifdef DEBUG
16163 +       {
16164 +               lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str);
16165 +               lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
16166 +       }
16167 +#endif
16168 +
16169 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
16170 +                                   CMD_ACT_FWT_ACCESS_LIST_NEIGHBOR,
16171 +                                   CMD_OPTION_WAITFORRSP, 0,
16172 +                                   (void *)&fwt_access);
16173 +
16174 +       if (ret == 0) {
16175 +               pbuf += sprintf(pbuf, " ra ");
16176 +               pbuf += eth_addr2str(fwt_access.ra, pbuf);
16177 +               pbuf += sprintf(pbuf, "  slp %u", fwt_access.sleepmode);
16178 +               pbuf += sprintf(pbuf, "  snr %u", le32_to_cpu(fwt_access.snr));
16179 +               pbuf += sprintf(pbuf, "  ref %u", le32_to_cpu(fwt_access.references));
16180 +       } else
16181 +               pbuf += sprintf(pbuf, " (null)");
16182 +
16183 +       wrq->u.data.length = strlen(out_str);
16184 +       if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
16185 +                        wrq->u.data.length)) {
16186 +               lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n");
16187 +               return -EFAULT;
16188 +       }
16189 +
16190 +       lbs_deb_leave(LBS_DEB_IOCTL);
16191 +       return 0;
16192 +}
16193 +
16194 +/**
16195 + *  @brief          Cleans up the route (FRT) and neighbor (FNT) tables
16196 + *                  (Garbage Collection)
16197 + *  @param priv     A pointer to struct lbs_private structure
16198 + *  @param req      A pointer to ifreq structure
16199 + *  @return         0 --success, otherwise fail
16200 + */
16201 +static int lbs_fwt_cleanup_ioctl(struct lbs_private * priv, struct ifreq *req)
16202 +{
16203 +       struct iwreq *wrq = (struct iwreq *)req;
16204 +       static struct cmd_ds_fwt_access fwt_access;
16205 +       int ret;
16206 +
16207 +       lbs_deb_enter(LBS_DEB_IOCTL);
16208 +
16209 +       lbs_deb_ioctl("FWT: cleaning up\n");
16210 +
16211 +       memset(&fwt_access, 0, sizeof(fwt_access));
16212 +
16213 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
16214 +                                   CMD_ACT_FWT_ACCESS_CLEANUP,
16215 +                                   CMD_OPTION_WAITFORRSP, 0,
16216 +                                   (void *)&fwt_access);
16217 +
16218 +       if (ret == 0)
16219 +               wrq->u.param.value = le32_to_cpu(fwt_access.references);
16220 +       else
16221 +               return -EFAULT;
16222 +
16223 +       lbs_deb_leave(LBS_DEB_IOCTL);
16224 +       return 0;
16225 +}
16226 +
16227 +/**
16228 + *  @brief          Gets firmware internal time (debug purposes)
16229 + *  @param priv     A pointer to struct lbs_private structure
16230 + *  @param req      A pointer to ifreq structure
16231 + *  @return         0 --success, otherwise fail
16232 + */
16233 +static int lbs_fwt_time_ioctl(struct lbs_private * priv, struct ifreq *req)
16234 +{
16235 +       struct iwreq *wrq = (struct iwreq *)req;
16236 +       static struct cmd_ds_fwt_access fwt_access;
16237 +       int ret;
16238 +
16239 +       lbs_deb_enter(LBS_DEB_IOCTL);
16240 +
16241 +       lbs_deb_ioctl("FWT: getting time\n");
16242 +
16243 +       memset(&fwt_access, 0, sizeof(fwt_access));
16244 +
16245 +       ret = lbs_prepare_and_send_command(priv, CMD_FWT_ACCESS,
16246 +                                   CMD_ACT_FWT_ACCESS_TIME,
16247 +                                   CMD_OPTION_WAITFORRSP, 0,
16248 +                                   (void *)&fwt_access);
16249 +
16250 +       if (ret == 0)
16251 +               wrq->u.param.value = le32_to_cpu(fwt_access.references);
16252 +       else
16253 +               return -EFAULT;
16254 +
16255 +       lbs_deb_leave(LBS_DEB_IOCTL);
16256 +       return 0;
16257 +}
16258 +
16259 +
16260 +/**
16261 + *  @brief              Manages all mesh related ioctls
16262 + *  @param priv         A pointer to struct lbs_private structure
16263 + *  @param req          A pointer to ifreq structure
16264 + *  @param cmd         The command type
16265 + *  @param host_subcmd  The device code for the subcommand
16266 + *                          0: sets a value in the firmware
16267 + *                          1: retrieves an int from the firmware
16268 + *  @return             0 --success, otherwise fail
16269 + */
16270 +static int lbs_mesh_ioctl(struct lbs_private * priv, struct iwreq * wrq, 
16271 +               int cmd, int subcmd)
16272 +{
16273 +       struct cmd_ds_mesh_access mesh_access;
16274 +       int parameter;
16275 +       char str[128];
16276 +       char *ptr = str;
16277 +       int ret, i;
16278 +
16279 +       lbs_deb_enter(LBS_DEB_IOCTL);
16280 +
16281 +       memset(&mesh_access, 0, sizeof(mesh_access));
16282 +
16283 +       if (cmd == LBS_SETONEINT_GETNONE) {
16284 +               parameter = SUBCMD_DATA(wrq);
16285 +
16286 +               /* Convert rate from Mbps -> firmware rate index */
16287 +               if (subcmd == CMD_ACT_MESH_SET_BCAST_RATE)
16288 +                       parameter = lbs_data_rate_to_fw_index(parameter);
16289 +               if (subcmd == CMD_ACT_MESH_SET_PRB_RSP_RETRY_LIMIT) {
16290 +                       if (parameter > 15)
16291 +                               return -EINVAL;
16292 +               }
16293 +               if (parameter < 0)
16294 +                       return -EINVAL;
16295 +               mesh_access.data[0] = cpu_to_le32(parameter);
16296 +       } else if (subcmd == CMD_ACT_MESH_SET_LINK_COSTS) {
16297 +               if (copy_from_user(str, wrq->u.data.pointer, sizeof(str)))
16298 +                       return -EFAULT;
16299 +
16300 +               for (i = 0; i < COSTS_LIST_SIZE; i++) {
16301 +                       mesh_access.data[i] = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
16302 +                       if (!(ptr = next_param(ptr)) && i!= (COSTS_LIST_SIZE - 1))
16303 +                               return -EINVAL;
16304 +               }
16305 +       }
16306 +
16307 +       ret = lbs_mesh_access(priv, subcmd, &mesh_access);
16308 +
16309 +       if (ret != 0)
16310 +               return ret;
16311 +
16312 +       if (cmd == LBS_SETNONE_GETONEINT) {
16313 +               u32 data = le32_to_cpu(mesh_access.data[0]);
16314 +
16315 +               if (subcmd == CMD_ACT_MESH_GET_BCAST_RATE)
16316 +                       wrq->u.param.value = lbs_fw_index_to_data_rate(data);
16317 +               else
16318 +                       wrq->u.param.value = data;
16319 +       } else if (subcmd == CMD_ACT_MESH_GET_LINK_COSTS) {
16320 +               for (i = 0; i < COSTS_LIST_SIZE; i++)
16321 +                       ptr += sprintf (ptr, " %u", le32_to_cpu(mesh_access.data[i]));
16322 +               wrq->u.data.length = strlen(str);
16323 +
16324 +               if (copy_to_user(wrq->u.data.pointer, (char *)str,
16325 +                                wrq->u.data.length)) {
16326 +                       lbs_deb_ioctl("MESH_IOCTL: Copy to user failed!\n");
16327 +                       ret = -EFAULT;
16328 +               }
16329 +       }
16330 +
16331 +       lbs_deb_leave(LBS_DEB_IOCTL);
16332 +       return ret;
16333 +}
16334 +
16335 +/**
16336 + *  @brief Control Beacon transmissions
16337 + *  @param priv                 A pointer to struct lbs_private structure
16338 + *  @param wrq                 A pointer to iwreq structure
16339 + *  @return                    0 --success, otherwise fail
16340 + */
16341 +static int lbs_bcn_ioctl(struct lbs_private * priv, struct iwreq *wrq)
16342 +{
16343 +       int ret;
16344 +       int data[2];
16345 +
16346 +       memset(data, 0, sizeof(data));
16347 +       if (!wrq->u.data.length) {
16348 +               lbs_deb_ioctl("Get Beacon control\n");
16349 +               ret = lbs_prepare_and_send_command(priv,
16350 +                                           CMD_802_11_BEACON_CTRL,
16351 +                                           CMD_ACT_GET,
16352 +                                           CMD_OPTION_WAITFORRSP, 0, NULL);
16353 +               data[0] = priv->beacon_enable;
16354 +               data[1] = priv->beacon_period;
16355 +               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
16356 +                       lbs_deb_ioctl("Copy to user failed\n");
16357 +                       return -EFAULT;
16358 +               }
16359 +#define GET_TWO_INT    2
16360 +               wrq->u.data.length = GET_TWO_INT;
16361 +       } else {
16362 +               lbs_deb_ioctl("Set beacon control\n");
16363 +               if (wrq->u.data.length > 2)
16364 +                       return -EINVAL;
16365 +               if (copy_from_user (data, wrq->u.data.pointer,
16366 +                    sizeof(int) * wrq->u.data.length)) {
16367 +                       lbs_deb_ioctl("Copy from user failed\n");
16368 +                       return -EFAULT;
16369 +               }
16370 +               priv->beacon_enable = data[0];
16371 +               if (wrq->u.data.length > 1) {
16372 +               if ((data[1] > MRVDRV_MAX_BEACON_INTERVAL)
16373 +                   || (data[1] < MRVDRV_MIN_BEACON_INTERVAL))
16374 +                       return -ENOTSUPP;
16375 +               priv->beacon_period= data[1];
16376 +               }
16377 +               ret = lbs_prepare_and_send_command(priv,
16378 +                                           CMD_802_11_BEACON_CTRL,
16379 +                                           CMD_ACT_SET,
16380 +                                           CMD_OPTION_WAITFORRSP, 0, NULL);
16381 +       }
16382 +       return ret;
16383 +}
16384 +
16385 +static int lbs_led_gpio_ioctl(struct lbs_private * priv, struct ifreq *req)
16386 +{
16387 +       struct iwreq *wrq = (struct iwreq *)req;
16388 +       int i, ret = 0;
16389 +       int data[16];
16390 +       struct cmd_ds_802_11_led_ctrl ctrl;
16391 +       struct mrvlietypes_ledgpio *gpio = (struct mrvlietypes_ledgpio *) ctrl.data;
16392 +       int len = wrq->u.data.length;
16393 +
16394 +       if ((len > MAX_LEDS * 2) || (len % 2 != 0))
16395 +               return -ENOTSUPP;
16396 +
16397 +       memset(&ctrl, 0, sizeof(ctrl));
16398 +       if (len == 0) {
16399 +               ctrl.action = cpu_to_le16(CMD_ACT_GET);
16400 +       } else {
16401 +               if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * len)) {
16402 +                       lbs_deb_ioctl("Copy from user failed\n");
16403 +                       ret = -EFAULT;
16404 +                       goto out;
16405 +               }
16406 +
16407 +               ctrl.action = cpu_to_le16(CMD_ACT_SET);
16408 +               ctrl.numled = cpu_to_le16(0);
16409 +               gpio->header.type = cpu_to_le16(TLV_TYPE_LED_GPIO);
16410 +               gpio->header.len = cpu_to_le16(len);
16411 +               for (i = 0; i < len; i += 2) {
16412 +                       gpio->ledpin[i / 2].led = data[i];
16413 +                       gpio->ledpin[i / 2].pin = data[i + 1];
16414 +               }
16415 +       }
16416 +
16417 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_LED_GPIO_CTRL,
16418 +                       0, CMD_OPTION_WAITFORRSP, 0, (void *)&ctrl);
16419 +       if (ret) {
16420 +               lbs_deb_ioctl("Error doing LED GPIO control: %d\n", ret);
16421 +               goto out;
16422 +       }
16423 +       len = le16_to_cpu(gpio->header.len);
16424 +       for (i = 0; i < len; i += 2) {
16425 +               data[i] = gpio->ledpin[i / 2].led;
16426 +               data[i + 1] = gpio->ledpin[i / 2].pin;
16427 +       }
16428 +
16429 +       if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * len)) {
16430 +               lbs_deb_ioctl("Copy to user failed\n");
16431 +               ret = -EFAULT;
16432 +               goto out;
16433 +       }
16434 +
16435 +       wrq->u.data.length = len;
16436 +
16437 +out:
16438 +       return ret;
16439 +}
16440 +
16441 +
16442 +static int lbs_led_bhv_ioctl(struct lbs_private * priv, struct ifreq *req)
16443 +{
16444 +       struct iwreq *wrq = (struct iwreq *)req;
16445 +       int i, ret = 0;
16446 +       int data[MAX_LEDS*4];
16447 +       int firmwarestate = 0;
16448 +       struct cmd_ds_802_11_led_ctrl ctrl;
16449 +       struct mrvlietypes_ledbhv *bhv = (struct mrvlietypes_ledbhv *) ctrl.data;
16450 +       int len = wrq->u.data.length;
16451 +
16452 +       if ((len > MAX_LEDS * 4) ||(len == 0)  )
16453 +               return -ENOTSUPP;
16454 +
16455 +       memset(&ctrl, 0, sizeof(ctrl));
16456 +       if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * len)) {
16457 +                       lbs_deb_ioctl("Copy from user failed\n");
16458 +                       ret = -EFAULT;
16459 +                       goto out;
16460 +       }
16461 +       if (len == 1) {
16462 +               ctrl.action = cpu_to_le16(CMD_ACT_GET);
16463 +               firmwarestate = data[0];
16464 +       } else {
16465 +               
16466 +               if (len % 4 != 0 )
16467 +                       return -ENOTSUPP;
16468 +
16469 +               bhv->header.type = cpu_to_le16(TLV_TYPE_LEDBEHAVIOR);
16470 +               bhv->header.len = cpu_to_le16(len);
16471 +               ctrl.action = cpu_to_le16(CMD_ACT_SET);
16472 +               ctrl.numled = cpu_to_le16(0);
16473 +               for (i = 0; i < len; i += 4) {
16474 +                       bhv->ledbhv[i / 4].firmwarestate = data[i];
16475 +                       bhv->ledbhv[i / 4].led = data[i + 1];
16476 +                       bhv->ledbhv[i / 4].ledstate = data[i + 2];
16477 +                       bhv->ledbhv[i / 4].ledarg = data[i + 3];
16478 +               }
16479 +       }
16480 +
16481 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_LED_GPIO_CTRL,
16482 +                       0, CMD_OPTION_WAITFORRSP, 0, (void *)&ctrl);
16483 +       if (ret) {
16484 +               lbs_deb_ioctl("Error doing LED GPIO control: %d\n", ret);
16485 +               goto out;
16486 +       }
16487 +
16488 +       /* Get LED behavior IE, we have received gpio control as well when len 
16489 +          is equal to 1. */
16490 +       if (len ==1 ) {
16491 +               bhv = (struct mrvlietypes_ledbhv *) 
16492 +                       ((unsigned char *)bhv->ledbhv + le16_to_cpu(bhv->header.len));
16493 +               i = 0;
16494 +               while ( i < (MAX_LEDS*4) &&
16495 +                       (bhv->header.type != cpu_to_le16(MRVL_TERMINATE_TLV_ID)) ) {
16496 +                       if (bhv->ledbhv[0].firmwarestate == firmwarestate) {
16497 +                               data[i++] = bhv->ledbhv[0].firmwarestate;
16498 +                               data[i++] = bhv->ledbhv[0].led;
16499 +                               data[i++] = bhv->ledbhv[0].ledstate;
16500 +                               data[i++] = bhv->ledbhv[0].ledarg;
16501 +                       }
16502 +                       bhv++;
16503 +               }
16504 +               len = i;
16505 +       } else {
16506 +               for (i = 0; i < le16_to_cpu(bhv->header.len); i += 4) {
16507 +                       data[i] = bhv->ledbhv[i / 4].firmwarestate;
16508 +                       data[i + 1] = bhv->ledbhv[i / 4].led;
16509 +                       data[i + 2] = bhv->ledbhv[i / 4].ledstate;
16510 +                       data[i + 3] = bhv->ledbhv[i / 4].ledarg;
16511 +               }
16512 +               len = le16_to_cpu(bhv->header.len);
16513 +       }
16514 +
16515 +       if (copy_to_user(wrq->u.data.pointer, data,
16516 +                        sizeof(int) * len)) {
16517 +               lbs_deb_ioctl("Copy to user failed\n");
16518 +               ret = -EFAULT;
16519 +               goto out;
16520 +       }
16521 +
16522 +       wrq->u.data.length = len;
16523 +
16524 +out:
16525 +       return ret;
16526 +}
16527 +
16528 +/**
16529 + *  @brief ioctl function - entry point
16530 + *
16531 + *  @param dev         A pointer to net_device structure
16532 + *  @param req         A pointer to ifreq structure
16533 + *  @param cmd                 command
16534 + *  @return            0--success, otherwise fail
16535 + */
16536 +int lbs_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
16537 +{
16538 +       int *pdata;
16539 +       int ret = 0;
16540 +       struct lbs_private *priv = dev->priv;
16541 +       struct iwreq *wrq = (struct iwreq *)req;
16542 +
16543 +       lbs_deb_enter(LBS_DEB_IOCTL);
16544 +
16545 +       lbs_deb_ioctl("lbs_do_ioctl: ioctl cmd = 0x%x\n", cmd);
16546 +       switch (cmd) {
16547 +       case LBS_SETNONE_GETNONE:
16548 +               switch (wrq->u.data.flags) {
16549 +               case LBS_SUBCMD_BT_RESET:
16550 +                       lbs_bt_reset_ioctl(priv);
16551 +                       break;
16552 +               case LBS_SUBCMD_FWT_RESET:
16553 +                       lbs_fwt_reset_ioctl(priv);
16554 +                       break;
16555 +               }
16556 +               break;
16557 +
16558 +       case LBS_SETONEINT_GETNONE:
16559 +               switch (wrq->u.mode) {
16560 +               case LBS_SUBCMD_SET_REGION:
16561 +                       ret = lbs_set_region(priv, (u16) SUBCMD_DATA(wrq));
16562 +                       break;
16563 +               case LBS_SUBCMD_MESH_SET_TTL:
16564 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16565 +                                       CMD_ACT_MESH_SET_TTL);
16566 +                       break;
16567 +               case LBS_SUBCMD_MESH_SET_BCAST_RATE:
16568 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16569 +                                       CMD_ACT_MESH_SET_BCAST_RATE);
16570 +                       break;
16571 +               case LBS_SUBCMD_MESH_SET_RREQ_DELAY:
16572 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16573 +                                       CMD_ACT_MESH_SET_RREQ_DELAY);
16574 +                       break;
16575 +               case LBS_SUBCMD_MESH_SET_ROUTE_EXP:
16576 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16577 +                                       CMD_ACT_MESH_SET_ROUTE_EXP);
16578 +                       break;
16579 +               case LBS_SUBCMD_BT_SET_INVERT:
16580 +                       ret = lbs_bt_set_invert_ioctl(priv, req);
16581 +                       break;
16582 +               case LBS_SUBCMD_MESH_SET_PRB_RSP_RETRY_LIMIT:
16583 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16584 +                                       CMD_ACT_MESH_SET_PRB_RSP_RETRY_LIMIT);
16585 +                       break;
16586 +               default:
16587 +                       ret = -EOPNOTSUPP;
16588 +                       break;
16589 +               }
16590 +               break;
16591 +
16592 +       case LBS_SET128CHAR_GET128CHAR:
16593 +               switch ((int)wrq->u.data.flags) {
16594 +               case LBS_SUBCMD_BT_ADD:
16595 +                       ret = lbs_bt_add_ioctl(priv, req);
16596 +                       break;
16597 +               case LBS_SUBCMD_BT_DEL:
16598 +                       ret = lbs_bt_del_ioctl(priv, req);
16599 +                       break;
16600 +               case LBS_SUBCMD_BT_LIST:
16601 +                       ret = lbs_bt_list_ioctl(priv, req);
16602 +                       break;
16603 +               case LBS_SUBCMD_FWT_ADD:
16604 +                       ret = lbs_fwt_add_ioctl(priv, req);
16605 +                       break;
16606 +               case LBS_SUBCMD_FWT_DEL:
16607 +                       ret = lbs_fwt_del_ioctl(priv, req);
16608 +                       break;
16609 +               case LBS_SUBCMD_FWT_LOOKUP:
16610 +                       ret = lbs_fwt_lookup_ioctl(priv, req);
16611 +                       break;
16612 +               case LBS_SUBCMD_FWT_LIST_NEIGHBOR:
16613 +                       ret = lbs_fwt_list_neighbor_ioctl(priv, req);
16614 +                       break;
16615 +               case LBS_SUBCMD_FWT_LIST:
16616 +                       ret = lbs_fwt_list_ioctl(priv, req);
16617 +                       break;
16618 +               case LBS_SUBCMD_FWT_LIST_ROUTE:
16619 +                       ret = lbs_fwt_list_route_ioctl(priv, req);
16620 +                       break;
16621 +               case LBS_SUBCMD_MESH_SET_LINK_COSTS:
16622 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16623 +                                       CMD_ACT_MESH_SET_LINK_COSTS);
16624 +                       break ;
16625 +               case LBS_SUBCMD_MESH_GET_LINK_COSTS:
16626 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16627 +                                       CMD_ACT_MESH_GET_LINK_COSTS);
16628 +                       break;
16629 +               }
16630 +               break;
16631 +
16632 +       case LBS_SETNONE_GETONEINT:
16633 +               switch (wrq->u.mode) {
16634 +               case LBS_SUBCMD_GET_REGION:
16635 +                       pdata = (int *)wrq->u.name;
16636 +                       *pdata = (int)priv->regioncode;
16637 +                       break;
16638 +               case LBS_SUBCMD_FWT_CLEANUP:
16639 +                       ret = lbs_fwt_cleanup_ioctl(priv, req);
16640 +                       break;
16641 +               case LBS_SUBCMD_FWT_TIME:
16642 +                       ret = lbs_fwt_time_ioctl(priv, req);
16643 +                       break;
16644 +               case LBS_SUBCMD_MESH_GET_TTL:
16645 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16646 +                                       CMD_ACT_MESH_GET_TTL);
16647 +                       break;
16648 +               case LBS_SUBCMD_MESH_GET_BCAST_RATE:
16649 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16650 +                                       CMD_ACT_MESH_GET_BCAST_RATE);
16651 +                       break;
16652 +               case LBS_SUBCMD_MESH_GET_RREQ_DELAY:
16653 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16654 +                                       CMD_ACT_MESH_GET_RREQ_DELAY);
16655 +                       break;
16656 +               case LBS_SUBCMD_MESH_GET_ROUTE_EXP:
16657 +                       ret = lbs_mesh_ioctl(priv, wrq, cmd,
16658 +                                       CMD_ACT_MESH_GET_ROUTE_EXP);
16659 +                       break;
16660 +               case LBS_SUBCMD_BT_GET_INVERT:
16661 +                       ret = lbs_bt_get_invert_ioctl(priv, req);
16662 +                       break;
16663 +               default:
16664 +                       ret = -EOPNOTSUPP;
16665 +               }
16666 +               break;
16667 +
16668 +       case LBS_SET_GET_SIXTEEN_INT:
16669 +               switch ((int)wrq->u.data.flags) {
16670 +               case LBS_LED_GPIO_CTRL:
16671 +                       ret = lbs_led_gpio_ioctl(priv, req);
16672 +                       break;
16673 +               case LBS_BCN_CTRL:
16674 +                       ret = lbs_bcn_ioctl(priv,wrq);
16675 +                       break;
16676 +               case LBS_LED_BEHAVIOR_CTRL:
16677 +                       ret = lbs_led_bhv_ioctl(priv, req);
16678 +                       break;
16679 +               }
16680 +               break;
16681 +
16682 +       default:
16683 +               ret = -EINVAL;
16684 +               break;
16685 +       }
16686 +
16687 +       lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
16688 +       return ret;
16689 +}
16690 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/ioctl.h linux-2.6.22-300/drivers/net/wireless/libertas/ioctl.h
16691 --- linux-2.6.22-250/drivers/net/wireless/libertas/ioctl.h      1969-12-31 19:00:00.000000000 -0500
16692 +++ linux-2.6.22-300/drivers/net/wireless/libertas/ioctl.h      2008-06-05 18:10:06.000000000 -0400
16693 @@ -0,0 +1,50 @@
16694 +#define COSTS_LIST_SIZE                        4
16695 +
16696 +/* iwpriv places the subcmd number in the first uint32_t;
16697 +   data buffer follows that */
16698 +#define SUBCMD_OFFSET                  sizeof(uint32_t)
16699 +#define SUBCMD_DATA(x)                 *((int *)(x->u.name + SUBCMD_OFFSET))
16700 +
16701 +/** Private ioctls and ioctls subcommands */
16702 +#define LBS_SETNONE_GETNONE                    (SIOCIWFIRSTPRIV + 8)
16703 +#define LBS_SUBCMD_BT_RESET                    13
16704 +#define LBS_SUBCMD_FWT_RESET                   14
16705 +
16706 +#define LBS_SETNONE_GETONEINT                  (SIOCIWFIRSTPRIV + 15)
16707 +#define LBS_SUBCMD_GET_REGION                  1
16708 +#define LBS_SUBCMD_FWT_CLEANUP                 15
16709 +#define LBS_SUBCMD_FWT_TIME                    16
16710 +#define LBS_SUBCMD_MESH_GET_TTL                        17
16711 +#define LBS_SUBCMD_BT_GET_INVERT               18
16712 +#define LBS_SUBCMD_MESH_GET_BCAST_RATE         19
16713 +#define LBS_SUBCMD_MESH_GET_RREQ_DELAY         20
16714 +#define LBS_SUBCMD_MESH_GET_ROUTE_EXP          21
16715 +
16716 +#define LBS_SETONEINT_GETNONE                  (SIOCIWFIRSTPRIV + 24)
16717 +#define LBS_SUBCMD_SET_REGION                  8
16718 +#define LBS_SUBCMD_MESH_SET_TTL                        18
16719 +#define LBS_SUBCMD_BT_SET_INVERT               19
16720 +#define LBS_SUBCMD_MESH_SET_BCAST_RATE         20
16721 +#define LBS_SUBCMD_MESH_SET_RREQ_DELAY         21
16722 +#define LBS_SUBCMD_MESH_SET_ROUTE_EXP          22
16723 +#define LBS_SUBCMD_MESH_SET_PRB_RSP_RETRY_LIMIT 23
16724 +
16725 +#define LBS_SET128CHAR_GET128CHAR              (SIOCIWFIRSTPRIV + 25)
16726 +#define LBS_SUBCMD_BT_ADD                      18
16727 +#define LBS_SUBCMD_BT_DEL                      19
16728 +#define LBS_SUBCMD_BT_LIST                     20
16729 +#define LBS_SUBCMD_FWT_ADD                     21
16730 +#define LBS_SUBCMD_FWT_DEL                     22
16731 +#define LBS_SUBCMD_FWT_LOOKUP                  23
16732 +#define LBS_SUBCMD_FWT_LIST_NEIGHBOR           24
16733 +#define LBS_SUBCMD_FWT_LIST                    25
16734 +#define LBS_SUBCMD_FWT_LIST_ROUTE              26
16735 +#define LBS_SUBCMD_MESH_SET_LINK_COSTS         27
16736 +#define LBS_SUBCMD_MESH_GET_LINK_COSTS         28
16737 +
16738 +#define LBS_SET_GET_SIXTEEN_INT                        (SIOCIWFIRSTPRIV + 29)
16739 +#define LBS_LED_GPIO_CTRL                      5
16740 +#define LBS_BCN_CTRL                           6
16741 +#define LBS_LED_BEHAVIOR_CTRL                  7
16742 +
16743 +int lbs_do_ioctl(struct net_device *dev, struct ifreq *req, int i);
16744 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/join.c linux-2.6.22-300/drivers/net/wireless/libertas/join.c
16745 --- linux-2.6.22-250/drivers/net/wireless/libertas/join.c       2007-07-08 19:32:17.000000000 -0400
16746 +++ linux-2.6.22-300/drivers/net/wireless/libertas/join.c       2008-06-05 18:10:06.000000000 -0400
16747 @@ -17,154 +17,171 @@
16748  #include "dev.h"
16749  #include "assoc.h"
16750  
16751 -#define AD_HOC_CAP_PRIVACY_ON 1
16752 +/* The firmware needs certain bits masked out of the beacon-derviced capability
16753 + * field when associating/joining to BSSs.
16754 + */
16755 +#define CAPINFO_MASK   (~(0xda00))
16756  
16757  /**
16758 - *  @brief This function finds out the common rates between rate1 and rate2.
16759 + *  @brief This function finds common rates between rate1 and card rates.
16760   *
16761   * It will fill common rates in rate1 as output if found.
16762   *
16763   * NOTE: Setting the MSB of the basic rates need to be taken
16764   *   care, either before or after calling this function
16765   *
16766 - *  @param adapter     A pointer to wlan_adapter structure
16767 + *  @param priv     A pointer to struct lbs_private structure
16768   *  @param rate1       the buffer which keeps input and output
16769 - *  @param rate1_size  the size of rate1 buffer
16770 - *  @param rate2       the buffer which keeps rate2
16771 - *  @param rate2_size  the size of rate2 buffer.
16772 + *  @param rate1_size  the size of rate1 buffer; new size of buffer on return
16773   *
16774   *  @return            0 or -1
16775   */
16776 -static int get_common_rates(wlan_adapter * adapter, u8 * rate1,
16777 -                           int rate1_size, u8 * rate2, int rate2_size)
16778 -{
16779 -       u8 *ptr = rate1;
16780 -       int ret = 0;
16781 +static int get_common_rates(struct lbs_private *priv,
16782 +       u8 *rates,
16783 +       u16 *rates_size)
16784 +{
16785 +       u8 *card_rates = lbs_bg_rates;
16786 +       size_t num_card_rates = sizeof(lbs_bg_rates);
16787 +       int ret = 0, i, j;
16788         u8 tmp[30];
16789 -       int i;
16790 +       size_t tmp_size = 0;
16791  
16792 -       memset(&tmp, 0, sizeof(tmp));
16793 -       memcpy(&tmp, rate1, min_t(size_t, rate1_size, sizeof(tmp)));
16794 -       memset(rate1, 0, rate1_size);
16795 -
16796 -       /* Mask the top bit of the original values */
16797 -       for (i = 0; tmp[i] && i < sizeof(tmp); i++)
16798 -               tmp[i] &= 0x7F;
16799 -
16800 -       for (i = 0; rate2[i] && i < rate2_size; i++) {
16801 -               /* Check for Card Rate in tmp, excluding the top bit */
16802 -               if (strchr(tmp, rate2[i] & 0x7F)) {
16803 -                       /* values match, so copy the Card Rate to rate1 */
16804 -                       *rate1++ = rate2[i];
16805 +       /* For each rate in card_rates that exists in rate1, copy to tmp */
16806 +       for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
16807 +               for (j = 0; rates[j] && (j < *rates_size); j++) {
16808 +                       if (rates[j] == card_rates[i])
16809 +                               tmp[tmp_size++] = card_rates[i];
16810                 }
16811         }
16812  
16813 -       lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp));
16814 -       lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size);
16815 -       lbs_dbg_hex("Common rates:", ptr, rate1_size);
16816 -       lbs_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate);
16817 -
16818 -       if (!adapter->is_datarate_auto) {
16819 -               while (*ptr) {
16820 -                       if ((*ptr & 0x7f) == adapter->datarate) {
16821 -                               ret = 0;
16822 +       lbs_deb_hex(LBS_DEB_JOIN, "AP rates    ", rates, *rates_size);
16823 +       lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", card_rates, num_card_rates);
16824 +       lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
16825 +       lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
16826 +
16827 +       if (!priv->auto_rate) {
16828 +               for (i = 0; i < tmp_size; i++) {
16829 +                       if (tmp[i] == priv->cur_rate)
16830                                 goto done;
16831 -                       }
16832 -                       ptr++;
16833                 }
16834 -               lbs_pr_alert( "Previously set fixed data rate %#x isn't "
16835 -                      "compatible with the network.\n", adapter->datarate);
16836 -
16837 +               lbs_pr_alert("Previously set fixed data rate %#x isn't "
16838 +                      "compatible with the network.\n", priv->cur_rate);
16839                 ret = -1;
16840                 goto done;
16841         }
16842 -
16843         ret = 0;
16844 +
16845  done:
16846 +       memset(rates, 0, *rates_size);
16847 +       *rates_size = min_t(int, tmp_size, *rates_size);
16848 +       memcpy(rates, tmp, *rates_size);
16849         return ret;
16850  }
16851  
16852 -int libertas_send_deauth(wlan_private * priv)
16853 +
16854 +/**
16855 + *  @brief Sets the MSB on basic rates as the firmware requires
16856 + *
16857 + * Scan through an array and set the MSB for basic data rates.
16858 + *
16859 + *  @param rates     buffer of data rates
16860 + *  @param len       size of buffer
16861 + */
16862 +static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
16863  {
16864 -       wlan_adapter *adapter = priv->adapter;
16865 -       int ret = 0;
16866 +       int i;
16867  
16868 -       if (adapter->mode == IW_MODE_INFRA &&
16869 -           adapter->connect_status == libertas_connected)
16870 -               ret = libertas_send_deauthentication(priv);
16871 -       else
16872 -               ret = -ENOTSUPP;
16873 +       for (i = 0; i < len; i++) {
16874 +               if (rates[i] == 0x02 || rates[i] == 0x04 ||
16875 +                   rates[i] == 0x0b || rates[i] == 0x16)
16876 +                       rates[i] |= 0x80;
16877 +       }
16878 +}
16879  
16880 -       return ret;
16881 +/**
16882 + *  @brief Unsets the MSB on basic rates
16883 + *
16884 + * Scan through an array and unset the MSB for basic data rates.
16885 + *
16886 + *  @param rates     buffer of data rates
16887 + *  @param len       size of buffer
16888 + */
16889 +void lbs_unset_basic_rate_flags(u8 *rates, size_t len)
16890 +{
16891 +       int i;
16892 +
16893 +       for (i = 0; i < len; i++)
16894 +               rates[i] &= 0x7f;
16895  }
16896  
16897 +
16898  /**
16899   *  @brief Associate to a specific BSS discovered in a scan
16900   *
16901 - *  @param priv      A pointer to wlan_private structure
16902 + *  @param priv      A pointer to struct lbs_private structure
16903   *  @param pbssdesc  Pointer to the BSS descriptor to associate with.
16904   *
16905   *  @return          0-success, otherwise fail
16906   */
16907 -int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
16908 +int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req)
16909  {
16910 -       wlan_adapter *adapter = priv->adapter;
16911         int ret;
16912  
16913 -       lbs_deb_enter(LBS_DEB_JOIN);
16914 +       lbs_deb_enter(LBS_DEB_ASSOC);
16915  
16916 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate,
16917 -                                   0, cmd_option_waitforrsp,
16918 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
16919 +                                   0, CMD_OPTION_WAITFORRSP,
16920                                     0, assoc_req->bss.bssid);
16921  
16922         if (ret)
16923                 goto done;
16924  
16925         /* set preamble to firmware */
16926 -       if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble)
16927 -               adapter->preamble = cmd_type_short_preamble;
16928 +       if (   (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
16929 +           && (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
16930 +               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
16931         else
16932 -               adapter->preamble = cmd_type_long_preamble;
16933 +               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
16934  
16935 -       libertas_set_radio_control(priv);
16936 +       lbs_set_radio_control(priv);
16937  
16938 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate,
16939 -                                   0, cmd_option_waitforrsp, 0, assoc_req);
16940 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
16941 +                                   0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
16942  
16943  done:
16944 -       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
16945 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
16946         return ret;
16947  }
16948  
16949  /**
16950   *  @brief Start an Adhoc Network
16951   *
16952 - *  @param priv         A pointer to wlan_private structure
16953 + *  @param priv         A pointer to struct lbs_private structure
16954   *  @param adhocssid    The ssid of the Adhoc Network
16955   *  @return             0--success, -1--fail
16956   */
16957 -int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
16958 +int lbs_start_adhoc_network(struct lbs_private *priv,
16959 +       struct assoc_request *assoc_req)
16960  {
16961 -       wlan_adapter *adapter = priv->adapter;
16962         int ret = 0;
16963  
16964 -       adapter->adhoccreate = 1;
16965 +       priv->adhoccreate = 1;
16966  
16967 -       if (!adapter->capinfo.shortpreamble) {
16968 -               lbs_deb_join("AdhocStart: Long preamble\n");
16969 -               adapter->preamble = cmd_type_long_preamble;
16970 -       } else {
16971 +       if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
16972                 lbs_deb_join("AdhocStart: Short preamble\n");
16973 -               adapter->preamble = cmd_type_short_preamble;
16974 +               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
16975 +       } else {
16976 +               lbs_deb_join("AdhocStart: Long preamble\n");
16977 +               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
16978         }
16979  
16980 -       libertas_set_radio_control(priv);
16981 +       lbs_set_radio_control(priv);
16982  
16983         lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
16984         lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
16985  
16986 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start,
16987 -                                   0, cmd_option_waitforrsp, 0, assoc_req);
16988 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
16989 +                                   0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
16990  
16991         return ret;
16992  }
16993 @@ -172,107 +189,120 @@ int libertas_start_adhoc_network(wlan_pr
16994  /**
16995   *  @brief Join an adhoc network found in a previous scan
16996   *
16997 - *  @param priv         A pointer to wlan_private structure
16998 + *  @param priv         A pointer to struct lbs_private structure
16999   *  @param pbssdesc     Pointer to a BSS descriptor found in a previous scan
17000   *                      to attempt to join
17001   *
17002   *  @return             0--success, -1--fail
17003   */
17004 -int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
17005 +int lbs_join_adhoc_network(struct lbs_private *priv,
17006 +       struct assoc_request *assoc_req)
17007  {
17008 -       wlan_adapter *adapter = priv->adapter;
17009         struct bss_descriptor * bss = &assoc_req->bss;
17010         int ret = 0;
17011  
17012         lbs_deb_join("%s: Current SSID '%s', ssid length %u\n",
17013                      __func__,
17014 -                    escape_essid(adapter->curbssparams.ssid,
17015 -                                 adapter->curbssparams.ssid_len),
17016 -                    adapter->curbssparams.ssid_len);
17017 +                    escape_essid(priv->curbssparams.ssid,
17018 +                                 priv->curbssparams.ssid_len),
17019 +                    priv->curbssparams.ssid_len);
17020         lbs_deb_join("%s: requested ssid '%s', ssid length %u\n",
17021                      __func__, escape_essid(bss->ssid, bss->ssid_len),
17022                      bss->ssid_len);
17023  
17024         /* check if the requested SSID is already joined */
17025 -       if (adapter->curbssparams.ssid_len
17026 -           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
17027 -                                 adapter->curbssparams.ssid_len,
17028 +       if (   priv->curbssparams.ssid_len
17029 +           && !lbs_ssid_cmp(priv->curbssparams.ssid,
17030 +                                 priv->curbssparams.ssid_len,
17031                                   bss->ssid, bss->ssid_len)
17032 -           && (adapter->mode == IW_MODE_ADHOC)) {
17033 -               lbs_deb_join(
17034 -                      "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
17035 -                      "not attempting to re-join");
17036 -               return -1;
17037 +           && (priv->mode == IW_MODE_ADHOC)
17038 +           && (priv->connect_status == LBS_CONNECTED)) {
17039 +               union iwreq_data wrqu;
17040 +
17041 +               lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as "
17042 +                            "current, not attempting to re-join");
17043 +
17044 +               /* Send the re-association event though, because the association
17045 +                * request really was successful, even if just a null-op.
17046 +                */
17047 +               memset(&wrqu, 0, sizeof(wrqu));
17048 +               memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid,
17049 +                      ETH_ALEN);
17050 +               wrqu.ap_addr.sa_family = ARPHRD_ETHER;
17051 +               wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
17052 +               goto out;
17053         }
17054  
17055 -       /*Use shortpreamble only when both creator and card supports
17056 +       /* Use shortpreamble only when both creator and card supports
17057            short preamble */
17058 -       if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
17059 +       if (   !(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
17060 +           || !(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
17061                 lbs_deb_join("AdhocJoin: Long preamble\n");
17062 -               adapter->preamble = cmd_type_long_preamble;
17063 +               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
17064         } else {
17065                 lbs_deb_join("AdhocJoin: Short preamble\n");
17066 -               adapter->preamble = cmd_type_short_preamble;
17067 +               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
17068         }
17069  
17070 -       libertas_set_radio_control(priv);
17071 +       lbs_set_radio_control(priv);
17072  
17073         lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
17074         lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
17075  
17076 -       adapter->adhoccreate = 0;
17077 +       priv->adhoccreate = 0;
17078  
17079 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join,
17080 -                                   0, cmd_option_waitforrsp,
17081 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN,
17082 +                                   0, CMD_OPTION_WAITFORRSP,
17083                                     OID_802_11_SSID, assoc_req);
17084  
17085 +out:
17086         return ret;
17087  }
17088  
17089 -int libertas_stop_adhoc_network(wlan_private * priv)
17090 +int lbs_stop_adhoc_network(struct lbs_private *priv)
17091  {
17092 -       return libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_stop,
17093 -                                    0, cmd_option_waitforrsp, 0, NULL);
17094 +       return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP,
17095 +                                    0, CMD_OPTION_WAITFORRSP, 0, NULL);
17096  }
17097  
17098  /**
17099   *  @brief Send Deauthentication Request
17100   *
17101 - *  @param priv      A pointer to wlan_private structure
17102 + *  @param priv      A pointer to struct lbs_private structure
17103   *  @return          0--success, -1--fail
17104   */
17105 -int libertas_send_deauthentication(wlan_private * priv)
17106 +int lbs_send_deauthentication(struct lbs_private *priv)
17107  {
17108 -       return libertas_prepare_and_send_command(priv, cmd_802_11_deauthenticate,
17109 -                                    0, cmd_option_waitforrsp, 0, NULL);
17110 +       return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
17111 +                                    0, CMD_OPTION_WAITFORRSP, 0, NULL);
17112  }
17113  
17114  /**
17115   *  @brief This function prepares command of authenticate.
17116   *
17117 - *  @param priv      A pointer to wlan_private structure
17118 + *  @param priv      A pointer to struct lbs_private structure
17119   *  @param cmd       A pointer to cmd_ds_command structure
17120   *  @param pdata_buf Void cast of pointer to a BSSID to authenticate with
17121   *
17122   *  @return         0 or -1
17123   */
17124 -int libertas_cmd_80211_authenticate(wlan_private * priv,
17125 +int lbs_cmd_80211_authenticate(struct lbs_private *priv,
17126                                  struct cmd_ds_command *cmd,
17127                                  void *pdata_buf)
17128  {
17129 -       wlan_adapter *adapter = priv->adapter;
17130         struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
17131         int ret = -1;
17132         u8 *bssid = pdata_buf;
17133 +       DECLARE_MAC_BUF(mac);
17134  
17135         lbs_deb_enter(LBS_DEB_JOIN);
17136  
17137 -       cmd->command = cpu_to_le16(cmd_802_11_authenticate);
17138 +       cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
17139         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
17140                                 + S_DS_GEN);
17141  
17142         /* translate auth mode to 802.11 defined wire value */
17143 -       switch (adapter->secinfo.auth_mode) {
17144 +       switch (priv->secinfo.auth_mode) {
17145         case IW_AUTH_ALG_OPEN_SYSTEM:
17146                 pauthenticate->authtype = 0x00;
17147                 break;
17148 @@ -284,14 +314,14 @@ int libertas_cmd_80211_authenticate(wlan
17149                 break;
17150         default:
17151                 lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
17152 -                            adapter->secinfo.auth_mode);
17153 +                            priv->secinfo.auth_mode);
17154                 goto out;
17155         }
17156  
17157         memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
17158  
17159 -       lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n",
17160 -                    MAC_ARG(bssid), pauthenticate->authtype);
17161 +       lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
17162 +                    print_mac(mac, bssid), pauthenticate->authtype);
17163         ret = 0;
17164  
17165  out:
17166 @@ -299,20 +329,19 @@ out:
17167         return ret;
17168  }
17169  
17170 -int libertas_cmd_80211_deauthenticate(wlan_private * priv,
17171 +int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
17172                                    struct cmd_ds_command *cmd)
17173  {
17174 -       wlan_adapter *adapter = priv->adapter;
17175         struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
17176  
17177         lbs_deb_enter(LBS_DEB_JOIN);
17178  
17179 -       cmd->command = cpu_to_le16(cmd_802_11_deauthenticate);
17180 +       cmd->command = cpu_to_le16(CMD_802_11_DEAUTHENTICATE);
17181         cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
17182                              S_DS_GEN);
17183  
17184         /* set AP MAC address */
17185 -       memmove(dauth->macaddr, adapter->curbssparams.bssid, ETH_ALEN);
17186 +       memmove(dauth->macaddr, priv->curbssparams.bssid, ETH_ALEN);
17187  
17188         /* Reason code 3 = Station is leaving */
17189  #define REASON_CODE_STA_LEAVING 3
17190 @@ -322,17 +351,14 @@ int libertas_cmd_80211_deauthenticate(wl
17191         return 0;
17192  }
17193  
17194 -int libertas_cmd_80211_associate(wlan_private * priv,
17195 +int lbs_cmd_80211_associate(struct lbs_private *priv,
17196                               struct cmd_ds_command *cmd, void *pdata_buf)
17197  {
17198 -       wlan_adapter *adapter = priv->adapter;
17199         struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
17200         int ret = 0;
17201         struct assoc_request * assoc_req = pdata_buf;
17202         struct bss_descriptor * bss = &assoc_req->bss;
17203 -       u8 *card_rates;
17204         u8 *pos;
17205 -       int card_rates_size;
17206         u16 tmpcap, tmplen;
17207         struct mrvlietypes_ssidparamset *ssid;
17208         struct mrvlietypes_phyparamset *phy;
17209 @@ -340,24 +366,24 @@ int libertas_cmd_80211_associate(wlan_pr
17210         struct mrvlietypes_ratesparamset *rates;
17211         struct mrvlietypes_rsnparamset *rsn;
17212  
17213 -       lbs_deb_enter(LBS_DEB_JOIN);
17214 +       lbs_deb_enter(LBS_DEB_ASSOC);
17215  
17216         pos = (u8 *) passo;
17217  
17218 -       if (!adapter) {
17219 +       if (!priv) {
17220                 ret = -1;
17221                 goto done;
17222         }
17223  
17224 -       cmd->command = cpu_to_le16(cmd_802_11_associate);
17225 +       cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
17226  
17227         memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
17228         pos += sizeof(passo->peerstaaddr);
17229  
17230         /* set the listen interval */
17231 -       passo->listeninterval = cpu_to_le16(adapter->listeninterval);
17232 +       passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
17233  
17234 -       pos += sizeof(passo->capinfo);
17235 +       pos += sizeof(passo->capability);
17236         pos += sizeof(passo->listeninterval);
17237         pos += sizeof(passo->bcnperiod);
17238         pos += sizeof(passo->dtimperiod);
17239 @@ -386,23 +412,24 @@ int libertas_cmd_80211_associate(wlan_pr
17240  
17241         rates = (struct mrvlietypes_ratesparamset *) pos;
17242         rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
17243 -
17244 -       memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES);
17245 -
17246 -       card_rates = libertas_supported_rates;
17247 -       card_rates_size = sizeof(libertas_supported_rates);
17248 -
17249 -       if (get_common_rates(adapter, rates->rates, WLAN_SUPPORTED_RATES,
17250 -                            card_rates, card_rates_size)) {
17251 +       memcpy(&rates->rates, &bss->rates, MAX_RATES);
17252 +       tmplen = MAX_RATES;
17253 +       if (get_common_rates(priv, rates->rates, &tmplen)) {
17254                 ret = -1;
17255                 goto done;
17256         }
17257 -
17258 -       tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
17259 -       adapter->curbssparams.numofrates = tmplen;
17260 -
17261         pos += sizeof(rates->header) + tmplen;
17262         rates->header.len = cpu_to_le16(tmplen);
17263 +       lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
17264 +
17265 +       /* Copy the infra. association rates into Current BSS state structure */
17266 +       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
17267 +       memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
17268 +
17269 +       /* Set MSB on basic rates as the firmware requires, but _after_
17270 +        * copying to current bss rates.
17271 +        */
17272 +       lbs_set_basic_rate_flags(rates->rates, tmplen);
17273  
17274         if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
17275                 rsn = (struct mrvlietypes_rsnparamset *) pos;
17276 @@ -411,70 +438,56 @@ int libertas_cmd_80211_associate(wlan_pr
17277                 tmplen = (u16) assoc_req->wpa_ie[1];
17278                 rsn->header.len = cpu_to_le16(tmplen);
17279                 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
17280 -               lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn,
17281 +               lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
17282                         sizeof(rsn->header) + tmplen);
17283                 pos += sizeof(rsn->header) + tmplen;
17284         }
17285  
17286         /* update curbssparams */
17287 -       adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
17288 +       priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
17289  
17290 -       /* Copy the infra. association rates into Current BSS state structure */
17291 -       memcpy(&adapter->curbssparams.datarates, &rates->rates,
17292 -              min_t(size_t, sizeof(adapter->curbssparams.datarates),
17293 -                    cpu_to_le16(rates->header.len)));
17294 -
17295 -       lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n",
17296 -                    cpu_to_le16(rates->header.len));
17297 -
17298 -       /* set IBSS field */
17299 -       if (bss->mode == IW_MODE_INFRA) {
17300 -#define CAPINFO_ESS_MODE 1
17301 -               passo->capinfo.ess = CAPINFO_ESS_MODE;
17302 -       }
17303 -
17304 -       if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
17305 +       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
17306                 ret = -1;
17307                 goto done;
17308         }
17309  
17310         cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
17311  
17312 -       /* set the capability info at last */
17313 -       memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo));
17314 -       tmpcap &= CAPINFO_MASK;
17315 -       lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
17316 -                    tmpcap, CAPINFO_MASK);
17317 -       memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo));
17318 +       /* set the capability info */
17319 +       tmpcap = (bss->capability & CAPINFO_MASK);
17320 +       if (bss->mode == IW_MODE_INFRA)
17321 +               tmpcap |= WLAN_CAPABILITY_ESS;
17322 +       passo->capability = cpu_to_le16(tmpcap);
17323 +       lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
17324  
17325  done:
17326 -       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
17327 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
17328         return ret;
17329  }
17330  
17331 -int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
17332 +int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
17333                                  struct cmd_ds_command *cmd, void *pdata_buf)
17334  {
17335 -       wlan_adapter *adapter = priv->adapter;
17336         struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
17337         int ret = 0;
17338         int cmdappendsize = 0;
17339 -       int i;
17340         struct assoc_request * assoc_req = pdata_buf;
17341 +       u16 tmpcap = 0;
17342 +       size_t ratesize = 0;
17343  
17344         lbs_deb_enter(LBS_DEB_JOIN);
17345  
17346 -       if (!adapter) {
17347 +       if (!priv) {
17348                 ret = -1;
17349                 goto done;
17350         }
17351  
17352 -       cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start);
17353 +       cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_START);
17354  
17355         /*
17356          * Fill in the parameters for 2 data structures:
17357          *   1. cmd_ds_802_11_ad_hoc_start command
17358 -        *   2. adapter->scantable[i]
17359 +        *   2. priv->scantable[i]
17360          *
17361          * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
17362          *   probe delay, and cap info.
17363 @@ -483,17 +496,19 @@ int libertas_cmd_80211_ad_hoc_start(wlan
17364          *   and operational rates.
17365          */
17366  
17367 -       memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE);
17368 -       memcpy(adhs->SSID, assoc_req->ssid, assoc_req->ssid_len);
17369 +       memset(adhs->ssid, 0, IW_ESSID_MAX_SIZE);
17370 +       memcpy(adhs->ssid, assoc_req->ssid, assoc_req->ssid_len);
17371  
17372         lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
17373                      escape_essid(assoc_req->ssid, assoc_req->ssid_len),
17374                      assoc_req->ssid_len);
17375  
17376         /* set the BSS type */
17377 -       adhs->bsstype = cmd_bss_type_ibss;
17378 -       adapter->mode = IW_MODE_ADHOC;
17379 -       adhs->beaconperiod = cpu_to_le16(adapter->beaconperiod);
17380 +       adhs->bsstype = CMD_BSS_TYPE_IBSS;
17381 +       priv->mode = IW_MODE_ADHOC;
17382 +       if (priv->beacon_period == 0)
17383 +               priv->beacon_period = MRVDRV_BEACON_INTERVAL;
17384 +       adhs->beaconperiod = cpu_to_le16(priv->beacon_period);
17385  
17386         /* set Physical param set */
17387  #define DS_PARA_IE_ID   3
17388 @@ -515,49 +530,40 @@ int libertas_cmd_80211_ad_hoc_start(wlan
17389  
17390         adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
17391         adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
17392 -       adhs->ssparamset.ibssparamset.atimwindow = cpu_to_le16(adapter->atimwindow);
17393 +       adhs->ssparamset.ibssparamset.atimwindow = 0;
17394  
17395         /* set capability info */
17396 -       adhs->cap.ess = 0;
17397 -       adhs->cap.ibss = 1;
17398 -
17399 -       /* probedelay */
17400 -       adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
17401 -
17402 -       /* set up privacy in adapter->scantable[i] */
17403 +       tmpcap = WLAN_CAPABILITY_IBSS;
17404         if (assoc_req->secinfo.wep_enabled) {
17405                 lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n");
17406 -               adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
17407 +               tmpcap |= WLAN_CAPABILITY_PRIVACY;
17408         } else {
17409                 lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n");
17410         }
17411 +       adhs->capability = cpu_to_le16(tmpcap);
17412  
17413 -       memset(adhs->datarate, 0, sizeof(adhs->datarate));
17414 -
17415 -       if (adapter->adhoc_grate_enabled) {
17416 -               memcpy(adhs->datarate, libertas_adhoc_rates_g,
17417 -                      min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_g)));
17418 -       } else {
17419 -               memcpy(adhs->datarate, libertas_adhoc_rates_b,
17420 -                      min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_b)));
17421 -       }
17422 -
17423 -       /* Find the last non zero */
17424 -       for (i = 0; i < sizeof(adhs->datarate) && adhs->datarate[i]; i++) ;
17425 +       /* probedelay */
17426 +       adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
17427  
17428 -       adapter->curbssparams.numofrates = i;
17429 +       memset(adhs->rates, 0, sizeof(adhs->rates));
17430 +       ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates));
17431 +       memcpy(adhs->rates, lbs_bg_rates, ratesize);
17432  
17433         /* Copy the ad-hoc creating rates into Current BSS state structure */
17434 -       memcpy(&adapter->curbssparams.datarates,
17435 -              &adhs->datarate, adapter->curbssparams.numofrates);
17436 +       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
17437 +       memcpy(&priv->curbssparams.rates, &adhs->rates, ratesize);
17438 +
17439 +       /* Set MSB on basic rates as the firmware requires, but _after_
17440 +        * copying to current bss rates.
17441 +        */
17442 +       lbs_set_basic_rate_flags(adhs->rates, ratesize);
17443  
17444         lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
17445 -              adhs->datarate[0], adhs->datarate[1],
17446 -              adhs->datarate[2], adhs->datarate[3]);
17447 +              adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
17448  
17449         lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
17450  
17451 -       if (libertas_create_dnld_countryinfo_11d(priv)) {
17452 +       if (lbs_create_dnld_countryinfo_11d(priv)) {
17453                 lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
17454                 ret = -1;
17455                 goto done;
17456 @@ -572,114 +578,96 @@ done:
17457         return ret;
17458  }
17459  
17460 -int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
17461 +int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv,
17462                                 struct cmd_ds_command *cmd)
17463  {
17464 -       cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_stop);
17465 +       cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP);
17466         cmd->size = cpu_to_le16(S_DS_GEN);
17467  
17468         return 0;
17469  }
17470  
17471 -int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
17472 +int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
17473                                 struct cmd_ds_command *cmd, void *pdata_buf)
17474  {
17475 -       wlan_adapter *adapter = priv->adapter;
17476 -       struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj;
17477 +       struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj;
17478         struct assoc_request * assoc_req = pdata_buf;
17479         struct bss_descriptor *bss = &assoc_req->bss;
17480         int cmdappendsize = 0;
17481         int ret = 0;
17482 -       u8 *card_rates;
17483 -       int card_rates_size;
17484 -       u16 tmpcap;
17485 -       int i;
17486 +       u16 ratesize = 0;
17487 +       DECLARE_MAC_BUF(mac);
17488  
17489         lbs_deb_enter(LBS_DEB_JOIN);
17490  
17491 -       cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join);
17492 -
17493 -       padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss;
17494 -
17495 -       padhocjoin->bssdescriptor.beaconperiod = cpu_to_le16(bss->beaconperiod);
17496 +       cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_JOIN);
17497  
17498 -       memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN);
17499 -       memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid, bss->ssid_len);
17500 +       join_cmd->bss.type = CMD_BSS_TYPE_IBSS;
17501 +       join_cmd->bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
17502  
17503 -       memcpy(&padhocjoin->bssdescriptor.phyparamset,
17504 -              &bss->phyparamset, sizeof(union ieeetypes_phyparamset));
17505 +       memcpy(&join_cmd->bss.bssid, &bss->bssid, ETH_ALEN);
17506 +       memcpy(&join_cmd->bss.ssid, &bss->ssid, bss->ssid_len);
17507  
17508 -       memcpy(&padhocjoin->bssdescriptor.ssparamset,
17509 -              &bss->ssparamset, sizeof(union IEEEtypes_ssparamset));
17510 +       memcpy(&join_cmd->bss.phyparamset, &bss->phyparamset,
17511 +              sizeof(union ieeetypes_phyparamset));
17512  
17513 -       memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo));
17514 -       tmpcap &= CAPINFO_MASK;
17515 +       memcpy(&join_cmd->bss.ssparamset, &bss->ssparamset,
17516 +              sizeof(union IEEEtypes_ssparamset));
17517  
17518 +       join_cmd->bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
17519         lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
17520 -              tmpcap, CAPINFO_MASK);
17521 -       memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap,
17522 -              sizeof(struct ieeetypes_capinfo));
17523 +              bss->capability, CAPINFO_MASK);
17524  
17525         /* information on BSSID descriptor passed to FW */
17526         lbs_deb_join(
17527 -              "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n",
17528 -              MAC_ARG(padhocjoin->bssdescriptor.BSSID),
17529 -              padhocjoin->bssdescriptor.SSID);
17530 +              "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
17531 +              print_mac(mac, join_cmd->bss.bssid),
17532 +              join_cmd->bss.ssid);
17533  
17534         /* failtimeout */
17535 -       padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
17536 +       join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
17537  
17538         /* probedelay */
17539 -       padhocjoin->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
17540 +       join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
17541 +
17542 +       priv->curbssparams.channel = bss->channel;
17543  
17544         /* Copy Data rates from the rates recorded in scan response */
17545 -       memset(padhocjoin->bssdescriptor.datarates, 0,
17546 -              sizeof(padhocjoin->bssdescriptor.datarates));
17547 -       memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates,
17548 -              min(sizeof(padhocjoin->bssdescriptor.datarates),
17549 -                  sizeof(bss->datarates)));
17550 -
17551 -       card_rates = libertas_supported_rates;
17552 -       card_rates_size = sizeof(libertas_supported_rates);
17553 -
17554 -       adapter->curbssparams.channel = bss->channel;
17555 -
17556 -       if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates,
17557 -                            sizeof(padhocjoin->bssdescriptor.datarates),
17558 -                            card_rates, card_rates_size)) {
17559 +       memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
17560 +       ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
17561 +       memcpy(join_cmd->bss.rates, bss->rates, ratesize);
17562 +       if (get_common_rates(priv, join_cmd->bss.rates, &ratesize)) {
17563                 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
17564                 ret = -1;
17565                 goto done;
17566         }
17567  
17568 -       /* Find the last non zero */
17569 -       for (i = 0; i < sizeof(padhocjoin->bssdescriptor.datarates)
17570 -            && padhocjoin->bssdescriptor.datarates[i]; i++) ;
17571 -
17572 -       adapter->curbssparams.numofrates = i;
17573 +       /* Copy the ad-hoc creating rates into Current BSS state structure */
17574 +       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
17575 +       memcpy(&priv->curbssparams.rates, join_cmd->bss.rates, ratesize);
17576  
17577 -       /*
17578 -        * Copy the adhoc joining rates to Current BSS State structure
17579 +       /* Set MSB on basic rates as the firmware requires, but _after_
17580 +        * copying to current bss rates.
17581          */
17582 -       memcpy(adapter->curbssparams.datarates,
17583 -              padhocjoin->bssdescriptor.datarates,
17584 -              adapter->curbssparams.numofrates);
17585 +       lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
17586  
17587 -       padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
17588 +       join_cmd->bss.ssparamset.ibssparamset.atimwindow =
17589             cpu_to_le16(bss->atimwindow);
17590  
17591         if (assoc_req->secinfo.wep_enabled) {
17592 -               padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
17593 +               u16 tmp = le16_to_cpu(join_cmd->bss.capability);
17594 +               tmp |= WLAN_CAPABILITY_PRIVACY;
17595 +               join_cmd->bss.capability = cpu_to_le16(tmp);
17596         }
17597  
17598 -       if (adapter->psmode == wlan802_11powermodemax_psp) {
17599 +       if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
17600                 /* wake up first */
17601                 __le32 Localpsmode;
17602  
17603 -               Localpsmode = cpu_to_le32(wlan802_11powermodecam);
17604 -               ret = libertas_prepare_and_send_command(priv,
17605 -                                           cmd_802_11_ps_mode,
17606 -                                           cmd_act_set,
17607 +               Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
17608 +               ret = lbs_prepare_and_send_command(priv,
17609 +                                           CMD_802_11_PS_MODE,
17610 +                                           CMD_ACT_SET,
17611                                             0, 0, &Localpsmode);
17612  
17613                 if (ret) {
17614 @@ -688,7 +676,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_
17615                 }
17616         }
17617  
17618 -       if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
17619 +       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
17620                 ret = -1;
17621                 goto done;
17622         }
17623 @@ -701,99 +689,131 @@ done:
17624         return ret;
17625  }
17626  
17627 -int libertas_ret_80211_associate(wlan_private * priv,
17628 +int lbs_ret_80211_associate(struct lbs_private *priv,
17629                               struct cmd_ds_command *resp)
17630  {
17631 -       wlan_adapter *adapter = priv->adapter;
17632         int ret = 0;
17633         union iwreq_data wrqu;
17634         struct ieeetypes_assocrsp *passocrsp;
17635         struct bss_descriptor * bss;
17636 +       u16 status_code;
17637  
17638 -       lbs_deb_enter(LBS_DEB_JOIN);
17639 +       lbs_deb_enter(LBS_DEB_ASSOC);
17640  
17641 -       if (!adapter->in_progress_assoc_req) {
17642 -               lbs_deb_join("ASSOC_RESP: no in-progress association request\n");
17643 +       if (!priv->in_progress_assoc_req) {
17644 +               lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
17645                 ret = -1;
17646                 goto done;
17647         }
17648 -       bss = &adapter->in_progress_assoc_req->bss;
17649 +       bss = &priv->in_progress_assoc_req->bss;
17650  
17651         passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
17652  
17653 -       if (le16_to_cpu(passocrsp->statuscode)) {
17654 -               libertas_mac_event_disconnected(priv);
17655 +       /*
17656 +        * Older FW versions map the IEEE 802.11 Status Code in the association
17657 +        * response to the following values returned in passocrsp->statuscode:
17658 +        *
17659 +        *    IEEE Status Code                Marvell Status Code
17660 +        *    0                       ->      0x0000 ASSOC_RESULT_SUCCESS
17661 +        *    13                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
17662 +        *    14                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
17663 +        *    15                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
17664 +        *    16                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
17665 +        *    others                  ->      0x0003 ASSOC_RESULT_REFUSED
17666 +        *
17667 +        * Other response codes:
17668 +        *    0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
17669 +        *    0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
17670 +        *                                    association response from the AP)
17671 +        */
17672  
17673 -               lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n",
17674 -                            le16_to_cpu(passocrsp->statuscode));
17675 +       status_code = le16_to_cpu(passocrsp->statuscode);
17676 +       switch (status_code) {
17677 +       case 0x00:
17678 +               break;
17679 +       case 0x01:
17680 +               lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
17681 +               break;
17682 +       case 0x02:
17683 +               lbs_deb_assoc("ASSOC_RESP: internal timer "
17684 +                       "expired while waiting for the AP\n");
17685 +               break;
17686 +       case 0x03:
17687 +               lbs_deb_assoc("ASSOC_RESP: association "
17688 +                       "refused by AP\n");
17689 +               break;
17690 +       case 0x04:
17691 +               lbs_deb_assoc("ASSOC_RESP: authentication "
17692 +                       "refused by AP\n");
17693 +               break;
17694 +       default:
17695 +               lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
17696 +                       " unknown\n", status_code);
17697 +               break;
17698 +       }
17699  
17700 +       if (status_code) {
17701 +               lbs_mac_event_disconnected(priv);
17702                 ret = -1;
17703                 goto done;
17704         }
17705  
17706 -       lbs_dbg_hex("ASSOC_RESP:", (void *)&resp->params,
17707 +       lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
17708                 le16_to_cpu(resp->size) - S_DS_GEN);
17709  
17710         /* Send a Media Connected event, according to the Spec */
17711 -       adapter->connect_status = libertas_connected;
17712 -
17713 -       lbs_deb_join("ASSOC_RESP: assocated to '%s'\n",
17714 -                    escape_essid(bss->ssid, bss->ssid_len));
17715 +       priv->connect_status = LBS_CONNECTED;
17716  
17717         /* Update current SSID and BSSID */
17718 -       memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
17719 -       adapter->curbssparams.ssid_len = bss->ssid_len;
17720 -       memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
17721 -
17722 -       lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
17723 -              adapter->currentpacketfilter);
17724 -
17725 -       adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
17726 -       adapter->NF[TYPE_RXPD][TYPE_AVG] = 0;
17727 -
17728 -       memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
17729 -       memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
17730 -       adapter->nextSNRNF = 0;
17731 -       adapter->numSNRNF = 0;
17732 +       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
17733 +       priv->curbssparams.ssid_len = bss->ssid_len;
17734 +       memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
17735 +
17736 +       lbs_deb_assoc("ASSOC_RESP: mac_control is 0x%x\n",
17737 +                     priv->mac_control);
17738 +
17739 +       priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
17740 +       priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
17741 +
17742 +       memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
17743 +       memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
17744 +       priv->nextSNRNF = 0;
17745 +       priv->numSNRNF = 0;
17746  
17747         netif_carrier_on(priv->dev);
17748 -       netif_wake_queue(priv->dev);
17749 -
17750 -       netif_carrier_on(priv->mesh_dev);
17751 -       netif_wake_queue(priv->mesh_dev);
17752 -
17753 -       lbs_deb_join("ASSOC_RESP: Associated \n");
17754 +       if (!priv->tx_pending_len)
17755 +               netif_wake_queue(priv->dev);
17756  
17757 -       memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
17758 +       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
17759         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
17760         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
17761  
17762  done:
17763 -       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
17764 +       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
17765         return ret;
17766  }
17767  
17768 -int libertas_ret_80211_disassociate(wlan_private * priv,
17769 +int lbs_ret_80211_disassociate(struct lbs_private *priv,
17770                                  struct cmd_ds_command *resp)
17771  {
17772         lbs_deb_enter(LBS_DEB_JOIN);
17773  
17774 -       libertas_mac_event_disconnected(priv);
17775 +       lbs_mac_event_disconnected(priv);
17776  
17777         lbs_deb_leave(LBS_DEB_JOIN);
17778         return 0;
17779  }
17780  
17781 -int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
17782 +int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
17783                                  struct cmd_ds_command *resp)
17784  {
17785 -       wlan_adapter *adapter = priv->adapter;
17786         int ret = 0;
17787         u16 command = le16_to_cpu(resp->command);
17788         u16 result = le16_to_cpu(resp->result);
17789         struct cmd_ds_802_11_ad_hoc_result *padhocresult;
17790         union iwreq_data wrqu;
17791         struct bss_descriptor *bss;
17792 +       DECLARE_MAC_BUF(mac);
17793  
17794         lbs_deb_enter(LBS_DEB_JOIN);
17795  
17796 @@ -803,20 +823,20 @@ int libertas_ret_80211_ad_hoc_start(wlan
17797         lbs_deb_join("ADHOC_RESP: command = %x\n", command);
17798         lbs_deb_join("ADHOC_RESP: result = %x\n", result);
17799  
17800 -       if (!adapter->in_progress_assoc_req) {
17801 +       if (!priv->in_progress_assoc_req) {
17802                 lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
17803                 ret = -1;
17804                 goto done;
17805         }
17806 -       bss = &adapter->in_progress_assoc_req->bss;
17807 +       bss = &priv->in_progress_assoc_req->bss;
17808  
17809         /*
17810          * Join result code 0 --> SUCCESS
17811          */
17812         if (result) {
17813                 lbs_deb_join("ADHOC_RESP: failed\n");
17814 -               if (adapter->connect_status == libertas_connected) {
17815 -                       libertas_mac_event_disconnected(priv);
17816 +               if (priv->connect_status == LBS_CONNECTED) {
17817 +                       lbs_mac_event_disconnected(priv);
17818                 }
17819                 ret = -1;
17820                 goto done;
17821 @@ -830,47 +850,45 @@ int libertas_ret_80211_ad_hoc_start(wlan
17822                      escape_essid(bss->ssid, bss->ssid_len));
17823  
17824         /* Send a Media Connected event, according to the Spec */
17825 -       adapter->connect_status = libertas_connected;
17826 +       priv->connect_status = LBS_CONNECTED;
17827  
17828 -       if (command == cmd_ret_802_11_ad_hoc_start) {
17829 +       if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
17830                 /* Update the created network descriptor with the new BSSID */
17831 -               memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN);
17832 +               memcpy(bss->bssid, padhocresult->bssid, ETH_ALEN);
17833         }
17834  
17835         /* Set the BSSID from the joined/started descriptor */
17836 -       memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
17837 +       memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
17838  
17839         /* Set the new SSID to current SSID */
17840 -       memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
17841 -       adapter->curbssparams.ssid_len = bss->ssid_len;
17842 +       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
17843 +       priv->curbssparams.ssid_len = bss->ssid_len;
17844  
17845         netif_carrier_on(priv->dev);
17846 -       netif_wake_queue(priv->dev);
17847 -
17848 -       netif_carrier_on(priv->mesh_dev);
17849 -       netif_wake_queue(priv->mesh_dev);
17850 +       if (!priv->tx_pending_len)
17851 +               netif_wake_queue(priv->dev);
17852  
17853         memset(&wrqu, 0, sizeof(wrqu));
17854 -       memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
17855 +       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
17856         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
17857         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
17858  
17859         lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
17860 -       lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
17861 -       lbs_deb_join("ADHOC_RESP: BSSID = " MAC_FMT "\n",
17862 -              MAC_ARG(padhocresult->BSSID));
17863 +       lbs_deb_join("ADHOC_RESP: channel = %d\n", priv->curbssparams.channel);
17864 +       lbs_deb_join("ADHOC_RESP: BSSID = %s\n",
17865 +                    print_mac(mac, padhocresult->bssid));
17866  
17867  done:
17868         lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
17869         return ret;
17870  }
17871  
17872 -int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
17873 +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv,
17874                                 struct cmd_ds_command *resp)
17875  {
17876         lbs_deb_enter(LBS_DEB_JOIN);
17877  
17878 -       libertas_mac_event_disconnected(priv);
17879 +       lbs_mac_event_disconnected(priv);
17880  
17881         lbs_deb_leave(LBS_DEB_JOIN);
17882         return 0;
17883 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/join.h linux-2.6.22-300/drivers/net/wireless/libertas/join.h
17884 --- linux-2.6.22-250/drivers/net/wireless/libertas/join.h       2007-07-08 19:32:17.000000000 -0400
17885 +++ linux-2.6.22-300/drivers/net/wireless/libertas/join.h       2008-06-05 18:10:06.000000000 -0400
17886 @@ -2,55 +2,52 @@
17887    * Interface for the wlan infrastructure and adhoc join routines
17888    *
17889    * Driver interface functions and type declarations for the join module
17890 -  *   implemented in wlan_join.c.  Process all start/join requests for
17891 +  *   implemented in join.c.  Process all start/join requests for
17892    *   both adhoc and infrastructure networks
17893    */
17894 -#ifndef _WLAN_JOIN_H
17895 -#define _WLAN_JOIN_H
17896 +#ifndef _LBS_JOIN_H
17897 +#define _LBS_JOIN_H
17898  
17899  #include "defs.h"
17900  #include "dev.h"
17901  
17902  struct cmd_ds_command;
17903 -extern int libertas_cmd_80211_authenticate(wlan_private * priv,
17904 +int lbs_cmd_80211_authenticate(struct lbs_private *priv,
17905                                         struct cmd_ds_command *cmd,
17906                                         void *pdata_buf);
17907 -extern int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
17908 +int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
17909                                        struct cmd_ds_command *cmd,
17910                                        void *pdata_buf);
17911 -extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
17912 +int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv,
17913                                        struct cmd_ds_command *cmd);
17914 -extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
17915 +int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
17916                                         struct cmd_ds_command *cmd,
17917                                         void *pdata_buf);
17918 -extern int libertas_cmd_80211_deauthenticate(wlan_private * priv,
17919 +int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
17920                                           struct cmd_ds_command *cmd);
17921 -extern int libertas_cmd_80211_associate(wlan_private * priv,
17922 +int lbs_cmd_80211_associate(struct lbs_private *priv,
17923                                      struct cmd_ds_command *cmd,
17924                                      void *pdata_buf);
17925  
17926 -extern int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
17927 +int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
17928                                         struct cmd_ds_command *resp);
17929 -extern int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
17930 +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv,
17931                                        struct cmd_ds_command *resp);
17932 -extern int libertas_ret_80211_disassociate(wlan_private * priv,
17933 +int lbs_ret_80211_disassociate(struct lbs_private *priv,
17934                                         struct cmd_ds_command *resp);
17935 -extern int libertas_ret_80211_associate(wlan_private * priv,
17936 +int lbs_ret_80211_associate(struct lbs_private *priv,
17937                                      struct cmd_ds_command *resp);
17938  
17939 -extern int libertas_reassociation_thread(void *data);
17940 -
17941 -extern int libertas_start_adhoc_network(wlan_private * priv,
17942 +int lbs_start_adhoc_network(struct lbs_private *priv,
17943                              struct assoc_request * assoc_req);
17944 -extern int libertas_join_adhoc_network(wlan_private * priv,
17945 +int lbs_join_adhoc_network(struct lbs_private *priv,
17946                                 struct assoc_request * assoc_req);
17947 -extern int libertas_stop_adhoc_network(wlan_private * priv);
17948 +int lbs_stop_adhoc_network(struct lbs_private *priv);
17949  
17950 -extern int libertas_send_deauthentication(wlan_private * priv);
17951 -extern int libertas_send_deauth(wlan_private * priv);
17952 +int lbs_send_deauthentication(struct lbs_private *priv);
17953  
17954 -extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
17955 +int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req);
17956  
17957 -int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req);
17958 +void lbs_unset_basic_rate_flags(u8 *rates, size_t len);
17959  
17960  #endif
17961 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/main.c linux-2.6.22-300/drivers/net/wireless/libertas/main.c
17962 --- linux-2.6.22-250/drivers/net/wireless/libertas/main.c       2007-07-08 19:32:17.000000000 -0400
17963 +++ linux-2.6.22-300/drivers/net/wireless/libertas/main.c       2008-06-05 18:10:06.000000000 -0400
17964 @@ -6,10 +6,12 @@
17965  
17966  #include <linux/moduleparam.h>
17967  #include <linux/delay.h>
17968 -#include <linux/freezer.h>
17969  #include <linux/etherdevice.h>
17970  #include <linux/netdevice.h>
17971  #include <linux/if_arp.h>
17972 +#include <linux/kthread.h>
17973 +#include <asm/olpc.h>
17974 +#include <linux/stddef.h>
17975  
17976  #include <net/iw_handler.h>
17977  #include <net/ieee80211.h>
17978 @@ -20,9 +22,12 @@
17979  #include "wext.h"
17980  #include "debugfs.h"
17981  #include "assoc.h"
17982 +#include "join.h"
17983 +#include "cmd.h"
17984 +#include "ioctl.h"
17985  
17986 -#define DRIVER_RELEASE_VERSION "322.p0"
17987 -const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
17988 +#define DRIVER_RELEASE_VERSION "323.p0"
17989 +const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
17990  #ifdef  DEBUG
17991      "-dbg"
17992  #endif
17993 @@ -30,80 +35,80 @@ const char libertas_driver_version[] = "
17994  
17995  
17996  /* Module parameters */
17997 -unsigned int libertas_debug = 0;
17998 -module_param(libertas_debug, int, 0644);
17999 -EXPORT_SYMBOL_GPL(libertas_debug);
18000 +unsigned int lbs_debug;
18001 +EXPORT_SYMBOL_GPL(lbs_debug);
18002 +module_param_named(libertas_debug, lbs_debug, int, 0644);
18003  
18004  
18005 -#define WLAN_TX_PWR_DEFAULT            20      /*100mW */
18006 -#define WLAN_TX_PWR_US_DEFAULT         20      /*100mW */
18007 -#define WLAN_TX_PWR_JP_DEFAULT         16      /*50mW */
18008 -#define WLAN_TX_PWR_FR_DEFAULT         20      /*100mW */
18009 -#define WLAN_TX_PWR_EMEA_DEFAULT       20      /*100mW */
18010 +#define LBS_TX_PWR_DEFAULT             20      /*100mW */
18011 +#define LBS_TX_PWR_US_DEFAULT          20      /*100mW */
18012 +#define LBS_TX_PWR_JP_DEFAULT          16      /*50mW */
18013 +#define LBS_TX_PWR_FR_DEFAULT          20      /*100mW */
18014 +#define LBS_TX_PWR_EMEA_DEFAULT        20      /*100mW */
18015  
18016  /* Format { channel, frequency (MHz), maxtxpower } */
18017  /* band: 'B/G', region: USA FCC/Canada IC */
18018  static struct chan_freq_power channel_freq_power_US_BG[] = {
18019 -       {1, 2412, WLAN_TX_PWR_US_DEFAULT},
18020 -       {2, 2417, WLAN_TX_PWR_US_DEFAULT},
18021 -       {3, 2422, WLAN_TX_PWR_US_DEFAULT},
18022 -       {4, 2427, WLAN_TX_PWR_US_DEFAULT},
18023 -       {5, 2432, WLAN_TX_PWR_US_DEFAULT},
18024 -       {6, 2437, WLAN_TX_PWR_US_DEFAULT},
18025 -       {7, 2442, WLAN_TX_PWR_US_DEFAULT},
18026 -       {8, 2447, WLAN_TX_PWR_US_DEFAULT},
18027 -       {9, 2452, WLAN_TX_PWR_US_DEFAULT},
18028 -       {10, 2457, WLAN_TX_PWR_US_DEFAULT},
18029 -       {11, 2462, WLAN_TX_PWR_US_DEFAULT}
18030 +       {1, 2412, LBS_TX_PWR_US_DEFAULT},
18031 +       {2, 2417, LBS_TX_PWR_US_DEFAULT},
18032 +       {3, 2422, LBS_TX_PWR_US_DEFAULT},
18033 +       {4, 2427, LBS_TX_PWR_US_DEFAULT},
18034 +       {5, 2432, LBS_TX_PWR_US_DEFAULT},
18035 +       {6, 2437, LBS_TX_PWR_US_DEFAULT},
18036 +       {7, 2442, LBS_TX_PWR_US_DEFAULT},
18037 +       {8, 2447, LBS_TX_PWR_US_DEFAULT},
18038 +       {9, 2452, LBS_TX_PWR_US_DEFAULT},
18039 +       {10, 2457, LBS_TX_PWR_US_DEFAULT},
18040 +       {11, 2462, LBS_TX_PWR_US_DEFAULT}
18041  };
18042  
18043  /* band: 'B/G', region: Europe ETSI */
18044  static struct chan_freq_power channel_freq_power_EU_BG[] = {
18045 -       {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
18046 -       {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
18047 -       {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
18048 -       {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
18049 -       {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
18050 -       {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
18051 -       {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
18052 -       {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
18053 -       {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
18054 -       {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
18055 -       {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
18056 -       {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
18057 -       {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
18058 +       {1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
18059 +       {2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
18060 +       {3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
18061 +       {4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
18062 +       {5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
18063 +       {6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
18064 +       {7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
18065 +       {8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
18066 +       {9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
18067 +       {10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
18068 +       {11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
18069 +       {12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
18070 +       {13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
18071  };
18072  
18073  /* band: 'B/G', region: Spain */
18074  static struct chan_freq_power channel_freq_power_SPN_BG[] = {
18075 -       {10, 2457, WLAN_TX_PWR_DEFAULT},
18076 -       {11, 2462, WLAN_TX_PWR_DEFAULT}
18077 +       {10, 2457, LBS_TX_PWR_DEFAULT},
18078 +       {11, 2462, LBS_TX_PWR_DEFAULT}
18079  };
18080  
18081  /* band: 'B/G', region: France */
18082  static struct chan_freq_power channel_freq_power_FR_BG[] = {
18083 -       {10, 2457, WLAN_TX_PWR_FR_DEFAULT},
18084 -       {11, 2462, WLAN_TX_PWR_FR_DEFAULT},
18085 -       {12, 2467, WLAN_TX_PWR_FR_DEFAULT},
18086 -       {13, 2472, WLAN_TX_PWR_FR_DEFAULT}
18087 +       {10, 2457, LBS_TX_PWR_FR_DEFAULT},
18088 +       {11, 2462, LBS_TX_PWR_FR_DEFAULT},
18089 +       {12, 2467, LBS_TX_PWR_FR_DEFAULT},
18090 +       {13, 2472, LBS_TX_PWR_FR_DEFAULT}
18091  };
18092  
18093  /* band: 'B/G', region: Japan */
18094  static struct chan_freq_power channel_freq_power_JPN_BG[] = {
18095 -       {1, 2412, WLAN_TX_PWR_JP_DEFAULT},
18096 -       {2, 2417, WLAN_TX_PWR_JP_DEFAULT},
18097 -       {3, 2422, WLAN_TX_PWR_JP_DEFAULT},
18098 -       {4, 2427, WLAN_TX_PWR_JP_DEFAULT},
18099 -       {5, 2432, WLAN_TX_PWR_JP_DEFAULT},
18100 -       {6, 2437, WLAN_TX_PWR_JP_DEFAULT},
18101 -       {7, 2442, WLAN_TX_PWR_JP_DEFAULT},
18102 -       {8, 2447, WLAN_TX_PWR_JP_DEFAULT},
18103 -       {9, 2452, WLAN_TX_PWR_JP_DEFAULT},
18104 -       {10, 2457, WLAN_TX_PWR_JP_DEFAULT},
18105 -       {11, 2462, WLAN_TX_PWR_JP_DEFAULT},
18106 -       {12, 2467, WLAN_TX_PWR_JP_DEFAULT},
18107 -       {13, 2472, WLAN_TX_PWR_JP_DEFAULT},
18108 -       {14, 2484, WLAN_TX_PWR_JP_DEFAULT}
18109 +       {1, 2412, LBS_TX_PWR_JP_DEFAULT},
18110 +       {2, 2417, LBS_TX_PWR_JP_DEFAULT},
18111 +       {3, 2422, LBS_TX_PWR_JP_DEFAULT},
18112 +       {4, 2427, LBS_TX_PWR_JP_DEFAULT},
18113 +       {5, 2432, LBS_TX_PWR_JP_DEFAULT},
18114 +       {6, 2437, LBS_TX_PWR_JP_DEFAULT},
18115 +       {7, 2442, LBS_TX_PWR_JP_DEFAULT},
18116 +       {8, 2447, LBS_TX_PWR_JP_DEFAULT},
18117 +       {9, 2452, LBS_TX_PWR_JP_DEFAULT},
18118 +       {10, 2457, LBS_TX_PWR_JP_DEFAULT},
18119 +       {11, 2462, LBS_TX_PWR_JP_DEFAULT},
18120 +       {12, 2467, LBS_TX_PWR_JP_DEFAULT},
18121 +       {13, 2472, LBS_TX_PWR_JP_DEFAULT},
18122 +       {14, 2484, LBS_TX_PWR_JP_DEFAULT}
18123  };
18124  
18125  /**
18126 @@ -121,57 +126,88 @@ struct region_cfp_table {
18127  static struct region_cfp_table region_cfp_table[] = {
18128         {0x10,                  /*US FCC */
18129          channel_freq_power_US_BG,
18130 -        sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
18131 +        ARRAY_SIZE(channel_freq_power_US_BG),
18132          }
18133         ,
18134         {0x20,                  /*CANADA IC */
18135          channel_freq_power_US_BG,
18136 -        sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
18137 +        ARRAY_SIZE(channel_freq_power_US_BG),
18138          }
18139         ,
18140         {0x30, /*EU*/ channel_freq_power_EU_BG,
18141 -        sizeof(channel_freq_power_EU_BG) / sizeof(struct chan_freq_power),
18142 +        ARRAY_SIZE(channel_freq_power_EU_BG),
18143          }
18144         ,
18145         {0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
18146 -        sizeof(channel_freq_power_SPN_BG) / sizeof(struct chan_freq_power),
18147 +        ARRAY_SIZE(channel_freq_power_SPN_BG),
18148          }
18149         ,
18150         {0x32, /*FRANCE*/ channel_freq_power_FR_BG,
18151 -        sizeof(channel_freq_power_FR_BG) / sizeof(struct chan_freq_power),
18152 +        ARRAY_SIZE(channel_freq_power_FR_BG),
18153          }
18154         ,
18155         {0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
18156 -        sizeof(channel_freq_power_JPN_BG) / sizeof(struct chan_freq_power),
18157 +        ARRAY_SIZE(channel_freq_power_JPN_BG),
18158          }
18159         ,
18160  /*Add new region here */
18161  };
18162  
18163  /**
18164 - * the rates supported
18165 + * the table to keep region code
18166   */
18167 -u8 libertas_supported_rates[G_SUPPORTED_RATES] =
18168 -    { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
18169 -0 };
18170 +u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
18171 +    { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
18172  
18173  /**
18174 - * the rates supported for ad-hoc G mode
18175 + * 802.11b/g supported bitrates (in 500Kb/s units)
18176   */
18177 -u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] =
18178 -    { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
18179 -0 };
18180 +u8 lbs_bg_rates[MAX_RATES] =
18181 +    { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
18182 +0x00, 0x00 };
18183  
18184  /**
18185 - * the rates supported for ad-hoc B mode
18186 + * FW rate table.  FW refers to rates by their index in this table, not by the
18187 + * rate value itself.  Values of 0x00 are
18188 + * reserved positions.
18189   */
18190 -u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 };
18191 +static u8 fw_data_rates[MAX_RATES] =
18192 +    { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
18193 +      0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
18194 +};
18195  
18196  /**
18197 - * the table to keep region code
18198 + *  @brief use index to get the data rate
18199 + *
18200 + *  @param idx                The index of data rate
18201 + *  @return                    data rate or 0
18202   */
18203 -u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
18204 -    { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
18205 +u32 lbs_fw_index_to_data_rate(u8 idx)
18206 +{
18207 +       if (idx >= sizeof(fw_data_rates))
18208 +               idx = 0;
18209 +       return fw_data_rates[idx];
18210 +}
18211 +
18212 +/**
18213 + *  @brief use rate to get the index
18214 + *
18215 + *  @param rate                 data rate
18216 + *  @return                    index or 0
18217 + */
18218 +u8 lbs_data_rate_to_fw_index(u32 rate)
18219 +{
18220 +       u8 i;
18221 +
18222 +       if (!rate)
18223 +               return 0;
18224 +
18225 +       for (i = 0; i < sizeof(fw_data_rates); i++) {
18226 +               if (rate == fw_data_rates[i])
18227 +                       return i;
18228 +       }
18229 +       return 0;
18230 +}
18231  
18232  /**
18233   * Attributes exported through sysfs
18234 @@ -180,16 +216,18 @@ u16 libertas_region_code_to_index[MRVDRV
18235  /**
18236   * @brief Get function for sysfs attribute anycast_mask
18237   */
18238 -static ssize_t libertas_anycast_get(struct device * dev,
18239 +static ssize_t lbs_anycast_get(struct device *dev,
18240                 struct device_attribute *attr, char * buf)
18241  {
18242 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18243         struct cmd_ds_mesh_access mesh_access;
18244 +       int ret;
18245  
18246         memset(&mesh_access, 0, sizeof(mesh_access));
18247 -       libertas_prepare_and_send_command(to_net_dev(dev)->priv,
18248 -                       cmd_mesh_access,
18249 -                       cmd_act_mesh_get_anycast,
18250 -                       cmd_option_waitforrsp, 0, (void *)&mesh_access);
18251 +
18252 +       ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
18253 +       if (ret)
18254 +               return ret;
18255  
18256         return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
18257  }
18258 @@ -197,274 +235,299 @@ static ssize_t libertas_anycast_get(stru
18259  /**
18260   * @brief Set function for sysfs attribute anycast_mask
18261   */
18262 -static ssize_t libertas_anycast_set(struct device * dev,
18263 +static ssize_t lbs_anycast_set(struct device *dev,
18264                 struct device_attribute *attr, const char * buf, size_t count)
18265  {
18266 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18267         struct cmd_ds_mesh_access mesh_access;
18268         uint32_t datum;
18269 +       int ret;
18270  
18271         memset(&mesh_access, 0, sizeof(mesh_access));
18272         sscanf(buf, "%x", &datum);
18273         mesh_access.data[0] = cpu_to_le32(datum);
18274  
18275 -       libertas_prepare_and_send_command((to_net_dev(dev))->priv,
18276 -                       cmd_mesh_access,
18277 -                       cmd_act_mesh_set_anycast,
18278 -                       cmd_option_waitforrsp, 0, (void *)&mesh_access);
18279 +       ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
18280 +       if (ret)
18281 +               return ret;
18282 +
18283         return strlen(buf);
18284  }
18285  
18286 -/**
18287 - * anycast_mask attribute to be exported per mshX interface
18288 - * through sysfs (/sys/class/net/mshX/anycast_mask)
18289 - */
18290 -static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set);
18291 +static int lbs_add_rtap(struct lbs_private *priv);
18292 +static void lbs_remove_rtap(struct lbs_private *priv);
18293 +static int lbs_add_mesh(struct lbs_private *priv);
18294 +static void lbs_remove_mesh(struct lbs_private *priv);
18295 +
18296  
18297  /**
18298 - *  @brief Check if the device can be open and wait if necessary.
18299 - *
18300 - *  @param dev     A pointer to net_device structure
18301 - *  @return       0
18302 - *
18303 - * For USB adapter, on some systems the device open handler will be
18304 - * called before FW ready. Use the following flag check and wait
18305 - * function to work around the issue.
18306 - *
18307 + * Get function for sysfs attribute rtap
18308   */
18309 -static int pre_open_check(struct net_device *dev)
18310 +static ssize_t lbs_rtap_get(struct device *dev,
18311 +               struct device_attribute *attr, char * buf)
18312  {
18313 -       wlan_private *priv = (wlan_private *) dev->priv;
18314 -       wlan_adapter *adapter = priv->adapter;
18315 -       int i = 0;
18316 -
18317 -       while (!adapter->fw_ready && i < 20) {
18318 -               i++;
18319 -               msleep_interruptible(100);
18320 -       }
18321 -       if (!adapter->fw_ready) {
18322 -               lbs_pr_err("firmware not ready\n");
18323 -               return -1;
18324 -       }
18325 -
18326 -       return 0;
18327 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18328 +       return snprintf(buf, 5, "0x%X\n", priv->monitormode);
18329  }
18330  
18331  /**
18332 - *  @brief This function opens the device
18333 - *
18334 - *  @param dev     A pointer to net_device structure
18335 - *  @return       0
18336 + *  Set function for sysfs attribute rtap
18337   */
18338 -static int wlan_dev_open(struct net_device *dev)
18339 +static ssize_t lbs_rtap_set(struct device *dev,
18340 +               struct device_attribute *attr, const char * buf, size_t count)
18341  {
18342 -       wlan_private *priv = (wlan_private *) dev->priv;
18343 -       wlan_adapter *adapter = priv->adapter;
18344 +       int monitor_mode;
18345 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18346  
18347 -       lbs_deb_enter(LBS_DEB_NET);
18348 +       sscanf(buf, "%x", &monitor_mode);
18349 +       if (monitor_mode != LBS_MONITOR_OFF) {
18350 +               if(priv->monitormode == monitor_mode)
18351 +                       return strlen(buf);
18352 +               if (priv->monitormode == LBS_MONITOR_OFF) {
18353 +                       if (priv->infra_open || priv->mesh_open)
18354 +                               return -EBUSY;
18355 +                       if (priv->mode == IW_MODE_INFRA)
18356 +                               lbs_send_deauthentication(priv);
18357 +                       else if (priv->mode == IW_MODE_ADHOC)
18358 +                               lbs_stop_adhoc_network(priv);
18359 +                       lbs_add_rtap(priv);
18360 +               }
18361 +               priv->monitormode = monitor_mode;
18362 +       }
18363  
18364 -       priv->open = 1;
18365 +       else {
18366 +               if (priv->monitormode == LBS_MONITOR_OFF)
18367 +                       return strlen(buf);
18368 +               priv->monitormode = LBS_MONITOR_OFF;
18369 +               lbs_remove_rtap(priv);
18370 +
18371 +               if (priv->currenttxskb) {
18372 +                       dev_kfree_skb_any(priv->currenttxskb);
18373 +                       priv->currenttxskb = NULL;
18374 +               }
18375  
18376 -       if (adapter->connect_status == libertas_connected) {
18377 -               netif_carrier_on(priv->dev);
18378 -               netif_carrier_on(priv->mesh_dev);
18379 -       } else {
18380 -               netif_carrier_off(priv->dev);
18381 -               netif_carrier_off(priv->mesh_dev);
18382 +               /* Wake queues, command thread, etc. */
18383 +               lbs_host_to_card_done(priv);
18384         }
18385  
18386 -       lbs_deb_leave(LBS_DEB_NET);
18387 -       return 0;
18388 +       lbs_prepare_and_send_command(priv,
18389 +                       CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
18390 +                       CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
18391 +       return strlen(buf);
18392  }
18393 +
18394  /**
18395 - *  @brief This function opens the mshX interface
18396 - *
18397 - *  @param dev     A pointer to net_device structure
18398 - *  @return       0
18399 + * lbs_rtap attribute to be exported per ethX interface
18400 + * through sysfs (/sys/class/net/ethX/lbs_rtap)
18401   */
18402 -static int mesh_open(struct net_device *dev)
18403 -{
18404 -       wlan_private *priv = (wlan_private *) dev->priv ;
18405 -
18406 -       if (pre_open_check(dev) == -1)
18407 -               return -1;
18408 -       priv->mesh_open = 1 ;
18409 -       netif_wake_queue(priv->mesh_dev);
18410 -       if (priv->infra_open == 0)
18411 -               return wlan_dev_open(priv->dev) ;
18412 -       return 0;
18413 -}
18414 +static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
18415  
18416  /**
18417 - *  @brief This function opens the ethX interface
18418 - *
18419 - *  @param dev     A pointer to net_device structure
18420 - *  @return       0
18421 + * Get function for sysfs attribute mesh
18422   */
18423 -static int wlan_open(struct net_device *dev)
18424 +static ssize_t lbs_mesh_get(struct device *dev,
18425 +               struct device_attribute *attr, char * buf)
18426  {
18427 -       wlan_private *priv = (wlan_private *) dev->priv ;
18428 -
18429 -       if(pre_open_check(dev) == -1)
18430 -               return -1;
18431 -       priv->infra_open = 1 ;
18432 -       netif_wake_queue(priv->dev);
18433 -       if (priv->open == 0)
18434 -               return wlan_dev_open(priv->dev) ;
18435 -       return 0;
18436 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18437 +       return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
18438  }
18439  
18440 -static int wlan_dev_close(struct net_device *dev)
18441 +/**
18442 + *  Set function for sysfs attribute mesh
18443 + */
18444 +static ssize_t lbs_mesh_set(struct device *dev,
18445 +               struct device_attribute *attr, const char * buf, size_t count)
18446  {
18447 -       wlan_private *priv = dev->priv;
18448 -
18449 -       lbs_deb_enter(LBS_DEB_NET);
18450 +       struct lbs_private *priv = to_net_dev(dev)->priv;
18451 +       int enable;
18452 +       int ret, action = CMD_ACT_MESH_CONFIG_STOP;
18453 +
18454 +       sscanf(buf, "%x", &enable);
18455 +       enable = !!enable;
18456 +       if (enable == !!priv->mesh_dev)
18457 +               return count;
18458 +       if (enable)
18459 +               action = CMD_ACT_MESH_CONFIG_START;
18460 +       ret = lbs_mesh_config(priv, action, priv->curbssparams.channel);
18461 +       if (ret)
18462 +               return ret;
18463  
18464 -       netif_carrier_off(priv->dev);
18465 -       priv->open = 0;
18466 +       if (enable)
18467 +               lbs_add_mesh(priv);
18468 +       else
18469 +               lbs_remove_mesh(priv);
18470  
18471 -       lbs_deb_leave(LBS_DEB_NET);
18472 -       return 0;
18473 +       return count;
18474  }
18475  
18476  /**
18477 - *  @brief This function closes the mshX interface
18478 - *
18479 - *  @param dev     A pointer to net_device structure
18480 - *  @return       0
18481 + * lbs_mesh attribute to be exported per ethX interface
18482 + * through sysfs (/sys/class/net/ethX/lbs_mesh)
18483   */
18484 -static int mesh_close(struct net_device *dev)
18485 -{
18486 -       wlan_private *priv = (wlan_private *) (dev->priv);
18487 +static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
18488  
18489 -       priv->mesh_open = 0;
18490 -       netif_stop_queue(priv->mesh_dev);
18491 -       if (priv->infra_open == 0)
18492 -               return wlan_dev_close(dev);
18493 -       else
18494 -               return 0;
18495 -}
18496 +/**
18497 + * anycast_mask attribute to be exported per mshX interface
18498 + * through sysfs (/sys/class/net/mshX/anycast_mask)
18499 + */
18500 +static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
18501 +
18502 +static struct attribute *lbs_mesh_sysfs_entries[] = {
18503 +       &dev_attr_anycast_mask.attr,
18504 +       NULL,
18505 +};
18506 +
18507 +static struct attribute_group lbs_mesh_attr_group = {
18508 +       .attrs = lbs_mesh_sysfs_entries,
18509 +};
18510  
18511  /**
18512 - *  @brief This function closes the ethX interface
18513 + *  @brief This function opens the ethX or mshX interface
18514   *
18515   *  @param dev     A pointer to net_device structure
18516 - *  @return       0
18517 + *  @return       0 or -EBUSY if monitor mode active
18518   */
18519 -static int wlan_close(struct net_device *dev)
18520 +static int lbs_dev_open(struct net_device *dev)
18521  {
18522 -       wlan_private *priv = (wlan_private *) dev->priv;
18523 -
18524 -       netif_stop_queue(dev);
18525 -       priv->infra_open = 0;
18526 -       if (priv->mesh_open == 0)
18527 -               return wlan_dev_close(dev);
18528 -       else
18529 -               return 0;
18530 -}
18531 +       struct lbs_private *priv = (struct lbs_private *) dev->priv ;
18532 +       int ret = 0;
18533  
18534 +       spin_lock_irq(&priv->driver_lock);
18535  
18536 -static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
18537 -{
18538 -       int ret = 0;
18539 -       wlan_private *priv = dev->priv;
18540 +       if (priv->monitormode != LBS_MONITOR_OFF) {
18541 +               ret = -EBUSY;
18542 +               goto out;
18543 +       }
18544  
18545 -       lbs_deb_enter(LBS_DEB_NET);
18546 +       if (dev == priv->mesh_dev) {
18547 +               priv->mesh_open = 1;
18548 +               priv->mesh_connect_status = LBS_CONNECTED;
18549 +               netif_carrier_on(dev);
18550 +       } else {
18551 +               priv->infra_open = 1;
18552  
18553 -       if (priv->dnld_sent || priv->adapter->TxLockFlag) {
18554 -               priv->stats.tx_dropped++;
18555 -               goto done;
18556 +               if (priv->connect_status == LBS_CONNECTED)
18557 +                       netif_carrier_on(dev);
18558 +               else
18559 +                       netif_carrier_off(dev);
18560         }
18561  
18562 -       netif_stop_queue(priv->dev);
18563 -       netif_stop_queue(priv->mesh_dev);
18564 +       if (!priv->tx_pending_len)
18565 +               netif_wake_queue(dev);
18566 + out:
18567  
18568 -       if (libertas_process_tx(priv, skb) == 0)
18569 -               dev->trans_start = jiffies;
18570 -done:
18571 -       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
18572 +       spin_unlock_irq(&priv->driver_lock);
18573         return ret;
18574  }
18575  
18576 +static void lbs_set_multicast_list(struct net_device *dev);
18577  /**
18578 - * @brief Mark mesh packets and handover them to wlan_hard_start_xmit
18579 + *  @brief This function closes the mshX interface
18580   *
18581 + *  @param dev     A pointer to net_device structure
18582 + *  @return       0
18583   */
18584 -static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
18585 +static int lbs_mesh_stop(struct net_device *dev)
18586  {
18587 -       wlan_private *priv = dev->priv;
18588 -       int ret;
18589 +       struct lbs_private *priv = (struct lbs_private *) (dev->priv);
18590  
18591 -       lbs_deb_enter(LBS_DEB_MESH);
18592 +       spin_lock_irq(&priv->driver_lock);
18593 +
18594 +       priv->mesh_open = 0;
18595 +       priv->mesh_connect_status = LBS_DISCONNECTED;
18596  
18597 -       SET_MESH_FRAME(skb);
18598 +       netif_stop_queue(dev);
18599 +       netif_carrier_off(dev);
18600  
18601 -       ret = wlan_hard_start_xmit(skb, priv->dev);
18602 -       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
18603 -       return ret;
18604 +       schedule_work(&priv->mcast_work);
18605 +
18606 +       spin_unlock_irq(&priv->driver_lock);
18607 +       return 0;
18608  }
18609  
18610  /**
18611 - * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
18612 + *  @brief This function closes the ethX interface
18613   *
18614 + *  @param dev     A pointer to net_device structure
18615 + *  @return       0
18616   */
18617 -static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
18618 +static int lbs_eth_stop(struct net_device *dev)
18619  {
18620 -       int ret;
18621 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
18622  
18623 -       lbs_deb_enter(LBS_DEB_NET);
18624 +       spin_lock_irq(&priv->driver_lock);
18625  
18626 -       UNSET_MESH_FRAME(skb);
18627 +       priv->infra_open = 0;
18628  
18629 -       ret = wlan_hard_start_xmit(skb, dev);
18630 -       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
18631 -       return ret;
18632 +       netif_stop_queue(dev);
18633 +
18634 +       schedule_work(&priv->mcast_work);
18635 +
18636 +       spin_unlock_irq(&priv->driver_lock);
18637 +       return 0;
18638  }
18639  
18640 -static void wlan_tx_timeout(struct net_device *dev)
18641 +static void lbs_tx_timeout(struct net_device *dev)
18642  {
18643 -       wlan_private *priv = (wlan_private *) dev->priv;
18644 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
18645  
18646         lbs_deb_enter(LBS_DEB_TX);
18647  
18648         lbs_pr_err("tx watch dog timeout\n");
18649  
18650 -       priv->dnld_sent = DNLD_RES_RECEIVED;
18651         dev->trans_start = jiffies;
18652  
18653 -       if (priv->adapter->currenttxskb) {
18654 -               if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
18655 -                       /* If we are here, we have not received feedback from
18656 -                          the previous packet.  Assume TX_FAIL and move on. */
18657 -                       priv->adapter->eventcause = 0x01000000;
18658 -                       libertas_send_tx_feedback(priv);
18659 -               } else
18660 -                       wake_up_interruptible(&priv->mainthread.waitq);
18661 -       } else if (priv->adapter->connect_status == libertas_connected) {
18662 -               netif_wake_queue(priv->dev);
18663 -               netif_wake_queue(priv->mesh_dev);
18664 -       }
18665 +       if (priv->currenttxskb) {
18666 +               priv->eventcause = 0x01000000;
18667 +               lbs_send_tx_feedback(priv);
18668 +       }
18669 +       /* XX: Shouldn't we also call into the hw-specific driver
18670 +          to kick it somehow? */
18671 +       lbs_host_to_card_done(priv);
18672 +
18673 +       /* More often than not, this actually happens because the
18674 +          firmware has crapped itself -- rather than just a very
18675 +          busy medium. So send a harmless command, and if/when
18676 +          _that_ times out, we'll kick it in the head. */
18677 +       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
18678 +                                    0, 0, NULL);
18679  
18680         lbs_deb_leave(LBS_DEB_TX);
18681  }
18682  
18683 +void lbs_host_to_card_done(struct lbs_private *priv)
18684 +{
18685 +       unsigned long flags;
18686 +
18687 +       spin_lock_irqsave(&priv->driver_lock, flags);
18688 +
18689 +       priv->dnld_sent = DNLD_RES_RECEIVED;
18690 +
18691 +       /* Wake main thread if commands are pending */
18692 +       if (!priv->cur_cmd || priv->tx_pending_len > 0)
18693 +               wake_up_interruptible(&priv->waitq);
18694 +
18695 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
18696 +}
18697 +EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
18698 +
18699  /**
18700   *  @brief This function returns the network statistics
18701   *
18702 - *  @param dev     A pointer to wlan_private structure
18703 + *  @param dev     A pointer to struct lbs_private structure
18704   *  @return       A pointer to net_device_stats structure
18705   */
18706 -static struct net_device_stats *wlan_get_stats(struct net_device *dev)
18707 +static struct net_device_stats *lbs_get_stats(struct net_device *dev)
18708  {
18709 -       wlan_private *priv = (wlan_private *) dev->priv;
18710 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
18711  
18712         return &priv->stats;
18713  }
18714  
18715 -static int wlan_set_mac_address(struct net_device *dev, void *addr)
18716 +static int lbs_set_mac_address(struct net_device *dev, void *addr)
18717  {
18718         int ret = 0;
18719 -       wlan_private *priv = (wlan_private *) dev->priv;
18720 -       wlan_adapter *adapter = priv->adapter;
18721 +       struct lbs_private *priv = (struct lbs_private *) dev->priv;
18722         struct sockaddr *phwaddr = addr;
18723  
18724         lbs_deb_enter(LBS_DEB_NET);
18725 @@ -472,17 +535,17 @@ static int wlan_set_mac_address(struct n
18726         /* In case it was called from the mesh device */
18727         dev = priv->dev ;
18728  
18729 -       memset(adapter->current_addr, 0, ETH_ALEN);
18730 +       memset(priv->current_addr, 0, ETH_ALEN);
18731  
18732         /* dev->dev_addr is 8 bytes */
18733 -       lbs_dbg_hex("dev->dev_addr:", dev->dev_addr, ETH_ALEN);
18734 +       lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN);
18735  
18736 -       lbs_dbg_hex("addr:", phwaddr->sa_data, ETH_ALEN);
18737 -       memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN);
18738 +       lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);
18739 +       memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
18740  
18741 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_mac_address,
18742 -                                   cmd_act_set,
18743 -                                   cmd_option_waitforrsp, 0, NULL);
18744 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,
18745 +                                   CMD_ACT_SET,
18746 +                                   CMD_OPTION_WAITFORRSP, 0, NULL);
18747  
18748         if (ret) {
18749                 lbs_deb_net("set MAC address failed\n");
18750 @@ -490,304 +553,567 @@ static int wlan_set_mac_address(struct n
18751                 goto done;
18752         }
18753  
18754 -       lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN);
18755 -       memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
18756 +       lbs_deb_hex(LBS_DEB_NET, "priv->macaddr", priv->current_addr, ETH_ALEN);
18757 +       memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN);
18758         if (priv->mesh_dev)
18759 -               memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
18760 +               memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
18761  
18762  done:
18763         lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
18764         return ret;
18765  }
18766  
18767 -static int wlan_copy_multicast_address(wlan_adapter * adapter,
18768 -                                    struct net_device *dev)
18769 +
18770 +static inline int mac_in_list(unsigned char *list, int list_len,
18771 +                             unsigned char *mac)
18772  {
18773 -       int i = 0;
18774 -       struct dev_mc_list *mcptr = dev->mc_list;
18775 +       while (list_len) {
18776 +               if (!memcmp(list, mac, ETH_ALEN))
18777 +                       return 1;
18778 +               list += ETH_ALEN;
18779 +               list_len--;
18780 +       }
18781 +       return 0;
18782 +}
18783 +
18784  
18785 -       for (i = 0; i < dev->mc_count; i++) {
18786 -               memcpy(&adapter->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
18787 -               mcptr = mcptr->next;
18788 +static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
18789 +                              struct net_device *dev, int nr_addrs)
18790 +{
18791 +       int i = nr_addrs;
18792 +       struct dev_mc_list *mc_list;
18793 +       DECLARE_MAC_BUF(mac);
18794 +
18795 +       if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
18796 +               return nr_addrs;
18797 +
18798 +       netif_tx_lock_bh(dev);
18799 +       for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
18800 +               if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
18801 +                       lbs_deb_net("mcast address %s:%s skipped\n", dev->name,
18802 +                                   print_mac(mac, mc_list->dmi_addr));
18803 +                       continue;
18804 +               }
18805 +
18806 +               if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
18807 +                       break;
18808 +               memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
18809 +               lbs_deb_net("mcast address %s:%s added to filter\n", dev->name,
18810 +                           print_mac(mac, mc_list->dmi_addr));
18811 +               i++;
18812         }
18813 +       netif_tx_unlock_bh(dev);
18814 +       if (mc_list)
18815 +               return -EOVERFLOW;
18816  
18817         return i;
18818 -
18819  }
18820  
18821 -static void wlan_set_multicast_list(struct net_device *dev)
18822 +static void lbs_set_mcast_worker(struct work_struct *work)
18823  {
18824 -       wlan_private *priv = dev->priv;
18825 -       wlan_adapter *adapter = priv->adapter;
18826 -       int oldpacketfilter;
18827 +       struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
18828 +       struct cmd_ds_mac_multicast_adr mcast_cmd;
18829 +       int dev_flags;
18830 +       int nr_addrs;
18831 +       int old_mac_control = priv->mac_control;
18832  
18833         lbs_deb_enter(LBS_DEB_NET);
18834  
18835 -       oldpacketfilter = adapter->currentpacketfilter;
18836 -
18837 -       if (dev->flags & IFF_PROMISC) {
18838 -               lbs_deb_net("enable promiscuous mode\n");
18839 -               adapter->currentpacketfilter |=
18840 -                   cmd_act_mac_promiscuous_enable;
18841 -               adapter->currentpacketfilter &=
18842 -                   ~(cmd_act_mac_all_multicast_enable |
18843 -                     cmd_act_mac_multicast_enable);
18844 -       } else {
18845 -               /* Multicast */
18846 -               adapter->currentpacketfilter &=
18847 -                   ~cmd_act_mac_promiscuous_enable;
18848 -
18849 -               if (dev->flags & IFF_ALLMULTI || dev->mc_count >
18850 -                   MRVDRV_MAX_MULTICAST_LIST_SIZE) {
18851 -                       lbs_deb_net( "enabling all multicast\n");
18852 -                       adapter->currentpacketfilter |=
18853 -                           cmd_act_mac_all_multicast_enable;
18854 -                       adapter->currentpacketfilter &=
18855 -                           ~cmd_act_mac_multicast_enable;
18856 -               } else {
18857 -                       adapter->currentpacketfilter &=
18858 -                           ~cmd_act_mac_all_multicast_enable;
18859 -
18860 -                       if (!dev->mc_count) {
18861 -                               lbs_deb_net("no multicast addresses, "
18862 -                                      "disabling multicast\n");
18863 -                               adapter->currentpacketfilter &=
18864 -                                   ~cmd_act_mac_multicast_enable;
18865 -                       } else {
18866 -                               int i;
18867 -
18868 -                               adapter->currentpacketfilter |=
18869 -                                   cmd_act_mac_multicast_enable;
18870 +       dev_flags = priv->dev->flags;
18871 +       if (priv->mesh_dev)
18872 +               dev_flags |= priv->mesh_dev->flags;
18873  
18874 -                               adapter->nr_of_multicastmacaddr =
18875 -                                   wlan_copy_multicast_address(adapter, dev);
18876 +       if (dev_flags & IFF_PROMISC) {
18877 +               priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
18878 +               priv->mac_control &= ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
18879 +                                      CMD_ACT_MAC_MULTICAST_ENABLE);
18880 +               goto out_set_mac_control;
18881 +       } else if (dev_flags & IFF_ALLMULTI) {
18882 +       do_allmulti:
18883 +               priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
18884 +               priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
18885 +                                      CMD_ACT_MAC_MULTICAST_ENABLE);
18886 +               goto out_set_mac_control;
18887 +       }
18888 +
18889 +       /* Once for priv->dev, again for priv->mesh_dev if it exists */
18890 +       nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->dev, 0);
18891 +       if (nr_addrs >= 0 && priv->mesh_dev)
18892 +               nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->mesh_dev, nr_addrs);
18893 +       if (nr_addrs < 0)
18894 +               goto do_allmulti;
18895 +
18896 +       if (nr_addrs) {
18897 +               int size = offsetof(struct cmd_ds_mac_multicast_adr,
18898 +                                   maclist[6*nr_addrs]);
18899 +
18900 +               mcast_cmd.action = cpu_to_le16(CMD_ACT_SET);
18901 +               mcast_cmd.hdr.size = cpu_to_le16(size);
18902 +               mcast_cmd.nr_of_adrs = cpu_to_le16(nr_addrs);
18903 +
18904 +               lbs_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &mcast_cmd.hdr, size);
18905 +
18906 +               priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
18907 +       } else
18908 +               priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
18909 +
18910 +       priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
18911 +                              CMD_ACT_MAC_ALL_MULTICAST_ENABLE);
18912 + out_set_mac_control:
18913 +       if (priv->mac_control != old_mac_control)
18914 +               lbs_set_mac_control(priv);
18915  
18916 -                               lbs_deb_net("multicast addresses: %d\n",
18917 -                                      dev->mc_count);
18918 -
18919 -                               for (i = 0; i < dev->mc_count; i++) {
18920 -                                       lbs_deb_net("Multicast address %d:"
18921 -                                              MAC_FMT "\n", i,
18922 -                                              adapter->multicastlist[i][0],
18923 -                                              adapter->multicastlist[i][1],
18924 -                                              adapter->multicastlist[i][2],
18925 -                                              adapter->multicastlist[i][3],
18926 -                                              adapter->multicastlist[i][4],
18927 -                                              adapter->multicastlist[i][5]);
18928 -                               }
18929 -                               /* send multicast addresses to firmware */
18930 -                               libertas_prepare_and_send_command(priv,
18931 -                                                     cmd_mac_multicast_adr,
18932 -                                                     cmd_act_set, 0, 0,
18933 -                                                     NULL);
18934 -                       }
18935 -               }
18936 -       }
18937 +       lbs_deb_leave(LBS_DEB_NET);
18938 +}
18939  
18940 -       if (adapter->currentpacketfilter != oldpacketfilter) {
18941 -               libertas_set_mac_packet_filter(priv);
18942 -       }
18943 +static void lbs_set_multicast_list(struct net_device *dev)
18944 +{
18945 +       struct lbs_private *priv = dev->priv;
18946  
18947 -       lbs_deb_leave(LBS_DEB_NET);
18948 +       schedule_work(&priv->mcast_work);
18949  }
18950  
18951  /**
18952 - *  @brief This function handles the major jobs in the WLAN driver.
18953 + *  @brief This function handles the major jobs in the LBS driver.
18954   *  It handles all events generated by firmware, RX data received
18955   *  from firmware and TX data sent from kernel.
18956   *
18957 - *  @param data    A pointer to wlan_thread structure
18958 + *  @param data    A pointer to lbs_thread structure
18959   *  @return       0
18960   */
18961 -static int wlan_service_main_thread(void *data)
18962 +static int lbs_thread(void *data)
18963  {
18964 -       struct wlan_thread *thread = data;
18965 -       wlan_private *priv = thread->priv;
18966 -       wlan_adapter *adapter = priv->adapter;
18967 +       struct net_device *dev = data;
18968 +       struct lbs_private *priv = dev->priv;
18969         wait_queue_t wait;
18970         u8 ireg = 0;
18971  
18972         lbs_deb_enter(LBS_DEB_THREAD);
18973  
18974 -       wlan_activate_thread(thread);
18975 -
18976         init_waitqueue_entry(&wait, current);
18977  
18978 +       current->flags |= PF_NOFREEZE;
18979 +
18980         for (;;) {
18981 -               lbs_deb_thread( "main-thread 111: intcounter=%d "
18982 -                      "currenttxskb=%p dnld_sent=%d\n",
18983 -                      adapter->intcounter,
18984 -                      adapter->currenttxskb, priv->dnld_sent);
18985 +               int shouldsleep;
18986  
18987 -               add_wait_queue(&thread->waitq, &wait);
18988 +               lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
18989 +                               priv->intcounter, priv->currenttxskb, priv->dnld_sent);
18990 +
18991 +               add_wait_queue(&priv->waitq, &wait);
18992                 set_current_state(TASK_INTERRUPTIBLE);
18993 -               spin_lock_irq(&adapter->driver_lock);
18994 -               if ((adapter->psstate == PS_STATE_SLEEP) ||
18995 -                   (!adapter->intcounter
18996 -                    && (priv->dnld_sent || adapter->cur_cmd ||
18997 -                        list_empty(&adapter->cmdpendingq)))) {
18998 -                       lbs_deb_thread(
18999 -                              "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
19000 -                              adapter->connect_status, adapter->intcounter,
19001 -                              adapter->psmode, adapter->psstate);
19002 -                       spin_unlock_irq(&adapter->driver_lock);
19003 +               spin_lock_irq(&priv->driver_lock);
19004 +
19005 +               if (kthread_should_stop())
19006 +                       shouldsleep = 0;        /* Bye */
19007 +               else if (priv->surpriseremoved)
19008 +                       shouldsleep = 1;        /* We need to wait until we're _told_ to die */
19009 +               else if (priv->psstate == PS_STATE_SLEEP)
19010 +                       shouldsleep = 1;        /* Sleep mode. Nothing we can do till it wakes */
19011 +               else if (priv->intcounter)
19012 +                       shouldsleep = 0;        /* Interrupt pending. Deal with it now */
19013 +               else if (priv->cmd_timed_out)
19014 +                       shouldsleep = 0;        /* Command timed out. Recover */
19015 +               else if (!priv->fw_ready)
19016 +                       shouldsleep = 1;        /* Firmware not ready. We're waiting for it */
19017 +               else if (priv->dnld_sent)
19018 +                       shouldsleep = 1;        /* Something is en route to the device already */
19019 +               else if (priv->tx_pending_len > 0)
19020 +                       shouldsleep = 0;        /* We've a packet to send */
19021 +               else if (priv->cur_cmd)
19022 +                       shouldsleep = 1;        /* Can't send a command; one already running */
19023 +               else if (!list_empty(&priv->cmdpendingq))
19024 +                       shouldsleep = 0;        /* We have a command to send */
19025 +               else
19026 +                       shouldsleep = 1;        /* No command */
19027 +
19028 +               if (shouldsleep) {
19029 +                       lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
19030 +                                      priv->connect_status, priv->intcounter,
19031 +                                      priv->psmode, priv->psstate);
19032 +                       spin_unlock_irq(&priv->driver_lock);
19033                         schedule();
19034                 } else
19035 -                       spin_unlock_irq(&adapter->driver_lock);
19036 +                       spin_unlock_irq(&priv->driver_lock);
19037  
19038 -
19039 -               lbs_deb_thread(
19040 -                      "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
19041 -                      "dnld_sent=%d\n", adapter->intcounter,
19042 -                      adapter->currenttxskb, priv->dnld_sent);
19043 +               lbs_deb_thread("main-thread 222 (waking up): intcounter=%d currenttxskb=%p dnld_sent=%d\n",
19044 +                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
19045  
19046                 set_current_state(TASK_RUNNING);
19047 -               remove_wait_queue(&thread->waitq, &wait);
19048 -               try_to_freeze();
19049 +               remove_wait_queue(&priv->waitq, &wait);
19050 +
19051 +               lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
19052 +                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
19053  
19054 -               lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
19055 -                      "dnld_sent=%d\n",
19056 -                      adapter->intcounter,
19057 -                      adapter->currenttxskb, priv->dnld_sent);
19058 -
19059 -               if (kthread_should_stop()
19060 -                   || adapter->surpriseremoved) {
19061 -                       lbs_deb_thread(
19062 -                              "main-thread: break from main thread: surpriseremoved=0x%x\n",
19063 -                              adapter->surpriseremoved);
19064 +               if (kthread_should_stop()) {
19065 +                       lbs_deb_thread("main-thread: break from main thread\n");
19066                         break;
19067                 }
19068  
19069 +               if (priv->surpriseremoved) {
19070 +                       lbs_deb_thread("adapter removed; waiting to die...\n");
19071 +                       continue;
19072 +               }
19073  
19074 -               spin_lock_irq(&adapter->driver_lock);
19075 -               if (adapter->intcounter) {
19076 +               spin_lock_irq(&priv->driver_lock);
19077 +
19078 +               if (priv->intcounter) {
19079                         u8 int_status;
19080 -                       adapter->intcounter = 0;
19081 +
19082 +                       priv->intcounter = 0;
19083                         int_status = priv->hw_get_int_status(priv, &ireg);
19084  
19085                         if (int_status) {
19086 -                               lbs_deb_thread(
19087 -                                      "main-thread: reading HOST_INT_STATUS_REG failed\n");
19088 -                               spin_unlock_irq(&adapter->driver_lock);
19089 +                               lbs_deb_thread("main-thread: reading HOST_INT_STATUS_REG failed\n");
19090 +                               spin_unlock_irq(&priv->driver_lock);
19091                                 continue;
19092                         }
19093 -                       adapter->hisregcpy |= ireg;
19094 +                       priv->hisregcpy |= ireg;
19095                 }
19096  
19097 -               lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
19098 -                      "dnld_sent=%d\n",
19099 -                      adapter->intcounter,
19100 -                      adapter->currenttxskb, priv->dnld_sent);
19101 +               lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
19102 +                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
19103  
19104                 /* command response? */
19105 -               if (adapter->hisregcpy & his_cmdupldrdy) {
19106 +               if (priv->hisregcpy & MRVDRV_CMD_UPLD_RDY) {
19107                         lbs_deb_thread("main-thread: cmd response ready\n");
19108  
19109 -                       adapter->hisregcpy &= ~his_cmdupldrdy;
19110 -                       spin_unlock_irq(&adapter->driver_lock);
19111 -                       libertas_process_rx_command(priv);
19112 -                       spin_lock_irq(&adapter->driver_lock);
19113 +                       priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
19114 +                       spin_unlock_irq(&priv->driver_lock);
19115 +                       lbs_process_rx_command(priv);
19116 +                       spin_lock_irq(&priv->driver_lock);
19117                 }
19118  
19119 +               if (priv->cmd_timed_out && priv->cur_cmd) {
19120 +                       struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
19121 +
19122 +                       if (++priv->nr_retries > 10) {
19123 +                               lbs_pr_info("Excessive timeouts submitting command %x\n",
19124 +                                           le16_to_cpu(cmdnode->cmdbuf->command));
19125 +                               lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
19126 +                               priv->nr_retries = 0;
19127 +#ifdef CONFIG_OLPC
19128 +                               if (machine_is_olpc()) {
19129 +                                       spin_unlock_irq(&priv->driver_lock);
19130 +                                       printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
19131 +                                       olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
19132 +                                       spin_lock_irq(&priv->driver_lock);
19133 +                               }
19134 +#endif
19135 +                       } else {
19136 +                               priv->cur_cmd = NULL;
19137 +                               lbs_pr_info("requeueing command %x due to timeout (#%d)\n",
19138 +                                           le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries);
19139 +
19140 +                               /* Stick it back at the _top_ of the pending queue
19141 +                                  for immediate resubmission */
19142 +                               list_add(&cmdnode->list, &priv->cmdpendingq);
19143 +                       }
19144 +               }
19145 +               priv->cmd_timed_out = 0;
19146 +
19147                 /* Any Card Event */
19148 -               if (adapter->hisregcpy & his_cardevent) {
19149 +               if (priv->hisregcpy & MRVDRV_CARDEVENT) {
19150                         lbs_deb_thread("main-thread: Card Event Activity\n");
19151  
19152 -                       adapter->hisregcpy &= ~his_cardevent;
19153 +                       priv->hisregcpy &= ~MRVDRV_CARDEVENT;
19154  
19155                         if (priv->hw_read_event_cause(priv)) {
19156 -                               lbs_pr_alert(
19157 -                                      "main-thread: hw_read_event_cause failed\n");
19158 -                               spin_unlock_irq(&adapter->driver_lock);
19159 +                               lbs_pr_alert("main-thread: hw_read_event_cause failed\n");
19160 +                               spin_unlock_irq(&priv->driver_lock);
19161                                 continue;
19162                         }
19163 -                       spin_unlock_irq(&adapter->driver_lock);
19164 -                       libertas_process_event(priv);
19165 +                       spin_unlock_irq(&priv->driver_lock);
19166 +                       lbs_process_event(priv);
19167                 } else
19168 -                       spin_unlock_irq(&adapter->driver_lock);
19169 +                       spin_unlock_irq(&priv->driver_lock);
19170 +
19171 +               if (!priv->fw_ready)
19172 +                       continue;
19173  
19174                 /* Check if we need to confirm Sleep Request received previously */
19175 -               if (adapter->psstate == PS_STATE_PRE_SLEEP) {
19176 -                       if (!priv->dnld_sent && !adapter->cur_cmd) {
19177 -                               if (adapter->connect_status ==
19178 -                                   libertas_connected) {
19179 -                                       lbs_deb_thread(
19180 -                                              "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
19181 -                                              "dnld_sent=%d cur_cmd=%p, confirm now\n",
19182 -                                              adapter->intcounter,
19183 -                                              adapter->currenttxskb,
19184 -                                              priv->dnld_sent,
19185 -                                              adapter->cur_cmd);
19186 -
19187 -                                       libertas_ps_confirm_sleep(priv,
19188 -                                                      (u16) adapter->psmode);
19189 -                               } else {
19190 -                                       /* workaround for firmware sending
19191 -                                        * deauth/linkloss event immediately
19192 -                                        * after sleep request, remove this
19193 -                                        * after firmware fixes it
19194 -                                        */
19195 -                                       adapter->psstate = PS_STATE_AWAKE;
19196 -                                       lbs_pr_alert(
19197 -                                              "main-thread: ignore PS_SleepConfirm in non-connected state\n");
19198 -                               }
19199 +               if (priv->psstate == PS_STATE_PRE_SLEEP &&
19200 +                   !priv->dnld_sent && !priv->cur_cmd) {
19201 +                       if (priv->connect_status == LBS_CONNECTED) {
19202 +                               lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n",
19203 +                                              priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd);
19204 +
19205 +                               lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
19206 +                       } else {
19207 +                               /* workaround for firmware sending
19208 +                                * deauth/linkloss event immediately
19209 +                                * after sleep request; remove this
19210 +                                * after firmware fixes it
19211 +                                */
19212 +                               priv->psstate = PS_STATE_AWAKE;
19213 +                               lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n");
19214                         }
19215                 }
19216  
19217                 /* The PS state is changed during processing of Sleep Request
19218                  * event above
19219                  */
19220 -               if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
19221 -                   (priv->adapter->psstate == PS_STATE_PRE_SLEEP))
19222 +               if ((priv->psstate == PS_STATE_SLEEP) ||
19223 +                   (priv->psstate == PS_STATE_PRE_SLEEP))
19224                         continue;
19225  
19226                 /* Execute the next command */
19227 -               if (!priv->dnld_sent && !priv->adapter->cur_cmd)
19228 -                       libertas_execute_next_command(priv);
19229 +               if (!priv->dnld_sent && !priv->cur_cmd)
19230 +                       lbs_execute_next_command(priv);
19231  
19232                 /* Wake-up command waiters which can't sleep in
19233 -                * libertas_prepare_and_send_command
19234 +                * lbs_prepare_and_send_command
19235                  */
19236 -               if (!adapter->nr_cmd_pending)
19237 -                       wake_up_all(&adapter->cmd_pending);
19238 +               if (!list_empty(&priv->cmdpendingq))
19239 +                       wake_up_all(&priv->cmd_pending);
19240  
19241 -               libertas_tx_runqueue(priv);
19242 +               spin_lock_irq(&priv->driver_lock);
19243 +               if (!priv->dnld_sent && priv->tx_pending_len > 0) {
19244 +                       int ret = priv->hw_host_to_card(priv, MVMS_DAT,
19245 +                                                       priv->tx_pending_buf,
19246 +                                                       priv->tx_pending_len);
19247 +                       if (ret) {
19248 +                               lbs_deb_tx("host_to_card failed %d\n", ret);
19249 +                               priv->dnld_sent = DNLD_RES_RECEIVED;
19250 +                       }
19251 +                       priv->tx_pending_len = 0;
19252 +                       if (!priv->currenttxskb) {
19253 +                               /* We can wake the queues immediately if we aren't
19254 +                                  waiting for TX feedback */
19255 +                               if (priv->connect_status == LBS_CONNECTED)
19256 +                                       netif_wake_queue(priv->dev);
19257 +                               if (priv->mesh_dev &&
19258 +                                   priv->mesh_connect_status == LBS_CONNECTED)
19259 +                                       netif_wake_queue(priv->mesh_dev);
19260 +                       }
19261 +               }
19262 +               spin_unlock_irq(&priv->driver_lock);
19263         }
19264  
19265 -       del_timer(&adapter->command_timer);
19266 -       adapter->nr_cmd_pending = 0;
19267 -       wake_up_all(&adapter->cmd_pending);
19268 -       wlan_deactivate_thread(thread);
19269 +       del_timer(&priv->command_timer);
19270 +       wake_up_all(&priv->cmd_pending);
19271  
19272         lbs_deb_leave(LBS_DEB_THREAD);
19273         return 0;
19274  }
19275  
19276 +static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
19277 +                               struct cmd_header *cmd)
19278 +{
19279 +       lbs_deb_fw("HOST_SLEEP_ACTIVATE succeeded\n");
19280 +
19281 +       netif_device_detach(priv->dev);
19282 +       if (priv->mesh_dev)
19283 +               netif_device_detach(priv->mesh_dev);
19284 +
19285 +       priv->fw_ready = 0;
19286 +       return 0;
19287 +}
19288 +
19289 +
19290 +int lbs_suspend(struct lbs_private *priv)
19291 +{
19292 +       struct cmd_header cmd;
19293 +       int ret;
19294 +
19295 +       if (priv->wol_criteria == 0xffffffff) {
19296 +               lbs_pr_info("Suspend attempt without configuring wake params!\n");
19297 +               return -EINVAL;
19298 +       }
19299 +
19300 +       memset(&cmd, 0, sizeof(cmd));
19301 +
19302 +       ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
19303 +                       sizeof(cmd), lbs_suspend_callback, 0);
19304 +       if (ret)
19305 +               lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
19306 +
19307 +       return ret;
19308 +}
19309 +EXPORT_SYMBOL_GPL(lbs_suspend);
19310 +
19311 +int lbs_resume(struct lbs_private *priv)
19312 +{
19313 +       priv->fw_ready = 1;
19314 +
19315 +       /* Firmware doesn't seem to give us RX packets any more
19316 +          until we send it some command. Might as well update */
19317 +       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
19318 +                                    0, 0, NULL);
19319 +
19320 +       netif_device_attach(priv->dev);
19321 +       if (priv->mesh_dev)
19322 +               netif_device_attach(priv->mesh_dev);
19323 +
19324 +       return 0;
19325 +}
19326 +EXPORT_SYMBOL_GPL(lbs_resume);
19327 +
19328 +/**
19329 + *  @brief This function downloads firmware image, gets
19330 + *  HW spec from firmware and set basic parameters to
19331 + *  firmware.
19332 + *
19333 + *  @param priv    A pointer to struct lbs_private structure
19334 + *  @return       0 or -1
19335 + */
19336 +static int lbs_setup_firmware(struct lbs_private *priv)
19337 +{
19338 +       int ret = -1;
19339 +
19340 +       lbs_deb_enter(LBS_DEB_FW);
19341 +
19342 +       /*
19343 +        * Read MAC address from HW
19344 +        */
19345 +       memset(priv->current_addr, 0xff, ETH_ALEN);
19346 +       ret = lbs_update_hw_spec(priv);
19347 +       if (ret) {
19348 +               ret = -1;
19349 +               goto done;
19350 +       }
19351 +
19352 +       lbs_set_mac_control(priv);
19353 +
19354 +       ret = lbs_get_data_rate(priv);
19355 +       if (ret < 0) {
19356 +               ret = -1;
19357 +               goto done;
19358 +       }
19359 +
19360 +       ret = 0;
19361 +done:
19362 +       lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
19363 +       return ret;
19364 +}
19365 +
19366 +/**
19367 + *  This function handles the timeout of command sending.
19368 + *  It will re-send the same command again.
19369 + */
19370 +static void command_timer_fn(unsigned long data)
19371 +{
19372 +       struct lbs_private *priv = (struct lbs_private *)data;
19373 +       unsigned long flags;
19374 +
19375 +       spin_lock_irqsave(&priv->driver_lock, flags);
19376 +
19377 +       if (!priv->cur_cmd) {
19378 +               lbs_pr_info("Command timer expired; no pending command\n");
19379 +               goto out;
19380 +       }
19381 +
19382 +       lbs_pr_info("Command %x timed out\n", le16_to_cpu(priv->cur_cmd->cmdbuf->command));
19383 +
19384 +       priv->cmd_timed_out = 1;
19385 +       wake_up_interruptible(&priv->waitq);
19386 + out:
19387 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
19388 +}
19389 +
19390 +static int lbs_init_adapter(struct lbs_private *priv)
19391 +{
19392 +       size_t bufsize;
19393 +       int i, ret = 0;
19394 +
19395 +       /* Allocate buffer to store the BSSID list */
19396 +       bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
19397 +       priv->networks = kzalloc(bufsize, GFP_KERNEL);
19398 +       if (!priv->networks) {
19399 +               lbs_pr_err("Out of memory allocating beacons\n");
19400 +               ret = -1;
19401 +               goto out;
19402 +       }
19403 +
19404 +       /* Initialize scan result lists */
19405 +       INIT_LIST_HEAD(&priv->network_free_list);
19406 +       INIT_LIST_HEAD(&priv->network_list);
19407 +       for (i = 0; i < MAX_NETWORK_COUNT; i++) {
19408 +               list_add_tail(&priv->networks[i].list,
19409 +                             &priv->network_free_list);
19410 +       }
19411 +
19412 +       priv->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++priv->seqnum);
19413 +       priv->lbs_ps_confirm_sleep.command =
19414 +           cpu_to_le16(CMD_802_11_PS_MODE);
19415 +       priv->lbs_ps_confirm_sleep.size =
19416 +           cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
19417 +       priv->lbs_ps_confirm_sleep.action =
19418 +           cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
19419 +
19420 +       memset(priv->current_addr, 0xff, ETH_ALEN);
19421 +
19422 +       priv->connect_status = LBS_DISCONNECTED;
19423 +       priv->mesh_connect_status = LBS_DISCONNECTED;
19424 +       priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
19425 +       priv->mode = IW_MODE_INFRA;
19426 +       priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
19427 +       priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
19428 +       priv->radioon = RADIO_ON;
19429 +       priv->auto_rate = 1;
19430 +       priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
19431 +       priv->psmode = LBS802_11POWERMODECAM;
19432 +       priv->psstate = PS_STATE_FULL_POWER;
19433 +
19434 +       mutex_init(&priv->lock);
19435 +
19436 +       setup_timer(&priv->command_timer, command_timer_fn,
19437 +                   (unsigned long)priv);
19438 +
19439 +       INIT_LIST_HEAD(&priv->cmdfreeq);
19440 +       INIT_LIST_HEAD(&priv->cmdpendingq);
19441 +
19442 +       spin_lock_init(&priv->driver_lock);
19443 +       init_waitqueue_head(&priv->cmd_pending);
19444 +
19445 +       /* Allocate the command buffers */
19446 +       if (lbs_allocate_cmd_buffer(priv)) {
19447 +               lbs_pr_err("Out of memory allocating command buffers\n");
19448 +               ret = -1;
19449 +       }
19450 +
19451 +out:
19452 +       return ret;
19453 +}
19454 +
19455 +static void lbs_free_adapter(struct lbs_private *priv)
19456 +{
19457 +       lbs_deb_fw("free command buffer\n");
19458 +       lbs_free_cmd_buffer(priv);
19459 +
19460 +       lbs_deb_fw("free command_timer\n");
19461 +       del_timer(&priv->command_timer);
19462 +
19463 +       lbs_deb_fw("free scan results table\n");
19464 +       kfree(priv->networks);
19465 +       priv->networks = NULL;
19466 +}
19467 +
19468  /**
19469   * @brief This function adds the card. it will probe the
19470 - * card, allocate the wlan_priv and initialize the device.
19471 + * card, allocate the lbs_priv and initialize the device.
19472   *
19473   *  @param card    A pointer to card
19474 - *  @return       A pointer to wlan_private structure
19475 + *  @return       A pointer to struct lbs_private structure
19476   */
19477 -wlan_private *libertas_add_card(void *card, struct device *dmdev)
19478 +struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
19479  {
19480         struct net_device *dev = NULL;
19481 -       wlan_private *priv = NULL;
19482 +       struct lbs_private *priv = NULL;
19483  
19484         lbs_deb_enter(LBS_DEB_NET);
19485  
19486         /* Allocate an Ethernet device and register it */
19487 -       if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
19488 +       dev = alloc_etherdev(sizeof(struct lbs_private));
19489 +       if (!dev) {
19490                 lbs_pr_err("init ethX device failed\n");
19491 -               return NULL;
19492 +               goto done;
19493         }
19494         priv = dev->priv;
19495  
19496 -       /* allocate buffer for wlan_adapter */
19497 -       if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
19498 -               lbs_pr_err("allocate buffer for wlan_adapter failed\n");
19499 -               goto err_kzalloc;
19500 +       if (lbs_init_adapter(priv)) {
19501 +               lbs_pr_err("failed to initialize adapter structure.\n");
19502 +               goto err_init_adapter;
19503         }
19504  
19505         priv->dev = dev;
19506 @@ -795,110 +1121,207 @@ wlan_private *libertas_add_card(void *ca
19507         priv->mesh_open = 0;
19508         priv->infra_open = 0;
19509  
19510 -       SET_MODULE_OWNER(dev);
19511 -
19512         /* Setup the OS Interface to our functions */
19513 -       dev->open = wlan_open;
19514 -       dev->hard_start_xmit = wlan_pre_start_xmit;
19515 -       dev->stop = wlan_close;
19516 -       dev->set_mac_address = wlan_set_mac_address;
19517 -       dev->tx_timeout = wlan_tx_timeout;
19518 -       dev->get_stats = wlan_get_stats;
19519 +       dev->open = lbs_dev_open;
19520 +       dev->hard_start_xmit = lbs_hard_start_xmit;
19521 +       dev->stop = lbs_eth_stop;
19522 +       dev->set_mac_address = lbs_set_mac_address;
19523 +       dev->tx_timeout = lbs_tx_timeout;
19524 +       dev->do_ioctl = lbs_do_ioctl;
19525 +       dev->get_stats = lbs_get_stats;
19526         dev->watchdog_timeo = 5 * HZ;
19527 -       dev->ethtool_ops = &libertas_ethtool_ops;
19528 +       dev->ethtool_ops = &lbs_ethtool_ops;
19529  #ifdef WIRELESS_EXT
19530 -       dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
19531 +       dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
19532  #endif
19533 -#define NETIF_F_DYNALLOC 16
19534 -       dev->features |= NETIF_F_DYNALLOC;
19535         dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
19536 -       dev->set_multicast_list = wlan_set_multicast_list;
19537 +       dev->set_multicast_list = lbs_set_multicast_list;
19538  
19539         SET_NETDEV_DEV(dev, dmdev);
19540  
19541 -       INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
19542 -       INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
19543 +       priv->rtap_net_dev = NULL;
19544 +
19545 +       lbs_deb_thread("Starting main thread...\n");
19546 +       init_waitqueue_head(&priv->waitq);
19547 +       priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
19548 +       if (IS_ERR(priv->main_thread)) {
19549 +               lbs_deb_thread("Error creating main thread.\n");
19550 +               goto err_init_adapter;
19551 +       }
19552 +
19553 +       priv->work_thread = create_singlethread_workqueue("lbs_worker");
19554 +       INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
19555 +       INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
19556 +       INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
19557 +       INIT_WORK(&priv->sync_channel, lbs_sync_channel);
19558 +
19559 +       sprintf(priv->mesh_ssid, "mesh");
19560 +       priv->mesh_ssid_len = 4;
19561 +
19562 +       priv->wol_criteria = 0xffffffff;
19563 +       priv->wol_gpio = 0xff;
19564  
19565 -       spin_lock_init(&priv->adapter->driver_lock);
19566 -       init_waitqueue_head(&priv->adapter->cmd_pending);
19567 -       priv->adapter->nr_cmd_pending = 0;
19568         goto done;
19569  
19570 -err_kzalloc:
19571 +err_init_adapter:
19572 +       lbs_free_adapter(priv);
19573         free_netdev(dev);
19574         priv = NULL;
19575 +
19576  done:
19577         lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
19578         return priv;
19579  }
19580 -EXPORT_SYMBOL_GPL(libertas_add_card);
19581 +EXPORT_SYMBOL_GPL(lbs_add_card);
19582 +
19583  
19584 -int libertas_activate_card(wlan_private *priv, char *fw_name)
19585 +int lbs_remove_card(struct lbs_private *priv)
19586  {
19587         struct net_device *dev = priv->dev;
19588 -       int ret = -1;
19589 +       union iwreq_data wrqu;
19590  
19591         lbs_deb_enter(LBS_DEB_MAIN);
19592  
19593 -       lbs_deb_thread("Starting kthread...\n");
19594 -       priv->mainthread.priv = priv;
19595 -       wlan_create_thread(wlan_service_main_thread,
19596 -                          &priv->mainthread, "wlan_main_service");
19597 -
19598 -       priv->assoc_thread =
19599 -               create_singlethread_workqueue("libertas_assoc");
19600 -       INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
19601 -       INIT_WORK(&priv->sync_channel, libertas_sync_channel);
19602 +       lbs_remove_mesh(priv);
19603 +       lbs_remove_rtap(priv);
19604  
19605 -       /*
19606 -        * Register the device. Fillup the private data structure with
19607 -        * relevant information from the card and request for the required
19608 -        * IRQ.
19609 -        */
19610 -       if (priv->hw_register_dev(priv) < 0) {
19611 -               lbs_pr_err("failed to register WLAN device\n");
19612 -               goto err_registerdev;
19613 -       }
19614 +       dev = priv->dev;
19615 +
19616 +       cancel_delayed_work(&priv->scan_work);
19617 +       cancel_delayed_work(&priv->assoc_work);
19618 +       cancel_work_sync(&priv->mcast_work);
19619 +       destroy_workqueue(priv->work_thread);
19620  
19621 -       /* init FW and HW */
19622 -       if (fw_name && libertas_init_fw(priv, fw_name)) {
19623 -               lbs_pr_err("firmware init failed\n");
19624 -               goto err_registerdev;
19625 +       if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
19626 +               priv->psmode = LBS802_11POWERMODECAM;
19627 +               lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
19628         }
19629  
19630 +       memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
19631 +       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
19632 +       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
19633 +
19634 +       /* Stop the thread servicing the interrupts */
19635 +       priv->surpriseremoved = 1;
19636 +       kthread_stop(priv->main_thread);
19637 +
19638 +       lbs_free_adapter(priv);
19639 +
19640 +       priv->dev = NULL;
19641 +       free_netdev(dev);
19642 +
19643 +       lbs_deb_leave(LBS_DEB_MAIN);
19644 +       return 0;
19645 +}
19646 +EXPORT_SYMBOL_GPL(lbs_remove_card);
19647 +
19648 +
19649 +int lbs_start_card(struct lbs_private *priv)
19650 +{
19651 +       struct net_device *dev = priv->dev;
19652 +       int ret = -1;
19653 +
19654 +       lbs_deb_enter(LBS_DEB_MAIN);
19655 +
19656 +       /* poke the firmware */
19657 +       ret = lbs_setup_firmware(priv);
19658 +       if (ret)
19659 +               goto done;
19660 +
19661 +       /* init 802.11d */
19662 +       lbs_init_11d(priv);
19663 +
19664         if (register_netdev(dev)) {
19665                 lbs_pr_err("cannot register ethX device\n");
19666 -               goto err_init_fw;
19667 +               goto done;
19668         }
19669 +       if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
19670 +               lbs_pr_err("cannot register lbs_rtap attribute\n");
19671  
19672 -       lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
19673 +       /* Enable mesh, if supported, and work out which TLV it uses.
19674 +          0x100 + 291 is an unofficial value used in 5.110.20.pXX
19675 +          0x100 + 37 is the official value used in 5.110.21.pXX
19676 +          but we check them in that order because 20.pXX doesn't
19677 +          give an error -- it just silently fails. */
19678 +
19679 +       /* 5.110.20.pXX firmware will fail the command if the channel
19680 +          doesn't match the existing channel. But only if the TLV
19681 +          is correct. If the channel is wrong, _BOTH_ versions will
19682 +          give an error to 0x100+291, and allow 0x100+37 to succeed.
19683 +          It's just that 5.110.20.pXX will not have done anything
19684 +          useful */
19685 +
19686 +       lbs_update_channel(priv);
19687 +       priv->mesh_tlv = 0x100 + 291;
19688 +       if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
19689 +                           priv->curbssparams.channel)) {
19690 +               priv->mesh_tlv = 0x100 + 37;
19691 +               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
19692 +                                   priv->curbssparams.channel))
19693 +                       priv->mesh_tlv = 0;
19694 +       }
19695 +       if (priv->mesh_tlv) {
19696 +               lbs_add_mesh(priv);
19697  
19698 -       libertas_debugfs_init_one(priv, dev);
19699 +               if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
19700 +                       lbs_pr_err("cannot register lbs_mesh attribute\n");
19701 +       }
19702 +
19703 +       lbs_debugfs_init_one(priv, dev);
19704 +
19705 +       lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
19706  
19707         ret = 0;
19708 -       goto done;
19709  
19710 -err_init_fw:
19711 -       priv->hw_unregister_dev(priv);
19712 -err_registerdev:
19713 -       destroy_workqueue(priv->assoc_thread);
19714 -       /* Stop the thread servicing the interrupts */
19715 -       wake_up_interruptible(&priv->mainthread.waitq);
19716 -       wlan_terminate_thread(&priv->mainthread);
19717  done:
19718 -       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
19719 +       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
19720 +       return ret;
19721 +}
19722 +EXPORT_SYMBOL_GPL(lbs_start_card);
19723 +
19724 +
19725 +int lbs_stop_card(struct lbs_private *priv)
19726 +{
19727 +       struct net_device *dev = priv->dev;
19728 +       int ret = -1;
19729 +       struct cmd_ctrl_node *cmdnode;
19730 +       unsigned long flags;
19731 +
19732 +       lbs_deb_enter(LBS_DEB_MAIN);
19733 +
19734 +       netif_stop_queue(priv->dev);
19735 +       netif_carrier_off(priv->dev);
19736 +
19737 +       lbs_debugfs_remove_one(priv);
19738 +       device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
19739 +       if (priv->mesh_tlv) {
19740 +               device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
19741 +       }
19742 +
19743 +       /* Flush pending command nodes */
19744 +       spin_lock_irqsave(&priv->driver_lock, flags);
19745 +       list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
19746 +               cmdnode->result = -ENOENT;
19747 +               cmdnode->cmdwaitqwoken = 1;
19748 +               wake_up_interruptible(&cmdnode->cmdwait_q);
19749 +       }
19750 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
19751 +
19752 +       unregister_netdev(dev);
19753 +
19754 +       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
19755         return ret;
19756  }
19757 -EXPORT_SYMBOL_GPL(libertas_activate_card);
19758 +EXPORT_SYMBOL_GPL(lbs_stop_card);
19759  
19760  
19761  /**
19762   * @brief This function adds mshX interface
19763   *
19764 - *  @param priv    A pointer to the wlan_private structure
19765 + *  @param priv    A pointer to the struct lbs_private structure
19766   *  @return       0 if successful, -X otherwise
19767   */
19768 -int libertas_add_mesh(wlan_private *priv, struct device *dev)
19769 +static int lbs_add_mesh(struct lbs_private *priv)
19770  {
19771         struct net_device *mesh_dev = NULL;
19772         int ret = 0;
19773 @@ -914,24 +1337,23 @@ int libertas_add_mesh(wlan_private *priv
19774         mesh_dev->priv = priv;
19775         priv->mesh_dev = mesh_dev;
19776  
19777 -       SET_MODULE_OWNER(mesh_dev);
19778 -
19779 -       mesh_dev->open = mesh_open;
19780 -       mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
19781 -       mesh_dev->stop = mesh_close;
19782 -       mesh_dev->get_stats = wlan_get_stats;
19783 -       mesh_dev->set_mac_address = wlan_set_mac_address;
19784 -       mesh_dev->ethtool_ops = &libertas_ethtool_ops;
19785 +       mesh_dev->open = lbs_dev_open;
19786 +       mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
19787 +       mesh_dev->stop = lbs_mesh_stop;
19788 +       mesh_dev->do_ioctl = lbs_do_ioctl;
19789 +       mesh_dev->get_stats = lbs_get_stats;
19790 +       mesh_dev->set_mac_address = lbs_set_mac_address;
19791 +       mesh_dev->ethtool_ops = &lbs_ethtool_ops;
19792         memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
19793                         sizeof(priv->dev->dev_addr));
19794  
19795 -       SET_NETDEV_DEV(priv->mesh_dev, dev);
19796 +       SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
19797  
19798  #ifdef WIRELESS_EXT
19799         mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
19800  #endif
19801 -#define NETIF_F_DYNALLOC 16
19802 -
19803 +       mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
19804 +       mesh_dev->set_multicast_list = lbs_set_multicast_list;
19805         /* Register virtual mesh interface */
19806         ret = register_netdev(mesh_dev);
19807         if (ret) {
19808 @@ -939,15 +1361,16 @@ int libertas_add_mesh(wlan_private *priv
19809                 goto err_free;
19810         }
19811  
19812 -       ret = device_create_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
19813 +       ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
19814         if (ret)
19815                 goto err_unregister;
19816  
19817 +       lbs_persist_config_init(mesh_dev);
19818 +
19819         /* Everything successful */
19820         ret = 0;
19821         goto done;
19822  
19823 -
19824  err_unregister:
19825         unregister_netdev(mesh_dev);
19826  
19827 @@ -958,107 +1381,36 @@ done:
19828         lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
19829         return ret;
19830  }
19831 -EXPORT_SYMBOL_GPL(libertas_add_mesh);
19832 -
19833 -static void wake_pending_cmdnodes(wlan_private *priv)
19834 -{
19835 -       struct cmd_ctrl_node *cmdnode;
19836 -       unsigned long flags;
19837 -
19838 -       lbs_deb_enter(LBS_DEB_CMD);
19839 -
19840 -       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
19841 -       list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
19842 -               cmdnode->cmdwaitqwoken = 1;
19843 -               wake_up_interruptible(&cmdnode->cmdwait_q);
19844 -       }
19845 -       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
19846 -}
19847 +EXPORT_SYMBOL_GPL(lbs_add_mesh);
19848  
19849  
19850 -int libertas_remove_card(wlan_private *priv)
19851 -{
19852 -       wlan_adapter *adapter;
19853 -       struct net_device *dev;
19854 -       union iwreq_data wrqu;
19855 -
19856 -       lbs_deb_enter(LBS_DEB_NET);
19857 -
19858 -       if (!priv)
19859 -               goto out;
19860 -
19861 -       adapter = priv->adapter;
19862 -
19863 -       if (!adapter)
19864 -               goto out;
19865 -
19866 -       dev = priv->dev;
19867 -
19868 -       netif_stop_queue(priv->dev);
19869 -       netif_carrier_off(priv->dev);
19870 -
19871 -       wake_pending_cmdnodes(priv);
19872 -
19873 -       unregister_netdev(dev);
19874 -
19875 -       cancel_delayed_work(&priv->assoc_work);
19876 -       destroy_workqueue(priv->assoc_thread);
19877 -
19878 -       if (adapter->psmode == wlan802_11powermodemax_psp) {
19879 -               adapter->psmode = wlan802_11powermodecam;
19880 -               libertas_ps_wakeup(priv, cmd_option_waitforrsp);
19881 -       }
19882 -
19883 -       memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
19884 -       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
19885 -       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
19886 -
19887 -       adapter->surpriseremoved = 1;
19888 -
19889 -       /* Stop the thread servicing the interrupts */
19890 -       wlan_terminate_thread(&priv->mainthread);
19891 -
19892 -       libertas_debugfs_remove_one(priv);
19893 -
19894 -       lbs_deb_net("free adapter\n");
19895 -       libertas_free_adapter(priv);
19896 -
19897 -       lbs_deb_net("unregister finish\n");
19898 -
19899 -       priv->dev = NULL;
19900 -       free_netdev(dev);
19901 -
19902 -out:
19903 -       lbs_deb_leave(LBS_DEB_NET);
19904 -       return 0;
19905 -}
19906 -EXPORT_SYMBOL_GPL(libertas_remove_card);
19907 -
19908 -
19909 -void libertas_remove_mesh(wlan_private *priv)
19910 +static void lbs_remove_mesh(struct lbs_private *priv)
19911  {
19912         struct net_device *mesh_dev;
19913  
19914 -       lbs_deb_enter(LBS_DEB_NET);
19915 +       lbs_deb_enter(LBS_DEB_MAIN);
19916  
19917         if (!priv)
19918                 goto out;
19919  
19920         mesh_dev = priv->mesh_dev;
19921 +       if (!mesh_dev)
19922 +               goto out;
19923  
19924         netif_stop_queue(mesh_dev);
19925 -       netif_carrier_off(priv->mesh_dev);
19926 +       netif_carrier_off(mesh_dev);
19927  
19928 -       device_remove_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
19929 +       sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
19930 +       lbs_persist_config_remove(mesh_dev);
19931         unregister_netdev(mesh_dev);
19932  
19933 -       priv->mesh_dev = NULL ;
19934 +       priv->mesh_dev = NULL;
19935         free_netdev(mesh_dev);
19936  
19937  out:
19938 -       lbs_deb_leave(LBS_DEB_NET);
19939 +       lbs_deb_leave(LBS_DEB_MAIN);
19940  }
19941 -EXPORT_SYMBOL_GPL(libertas_remove_mesh);
19942 +EXPORT_SYMBOL_GPL(lbs_remove_mesh);
19943  
19944  /**
19945   *  @brief This function finds the CFP in
19946 @@ -1069,13 +1421,13 @@ EXPORT_SYMBOL_GPL(libertas_remove_mesh);
19947   *  @param cfp_no  A pointer to CFP number
19948   *  @return       A pointer to CFP
19949   */
19950 -struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
19951 +struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
19952  {
19953         int i, end;
19954  
19955         lbs_deb_enter(LBS_DEB_MAIN);
19956  
19957 -       end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
19958 +       end = ARRAY_SIZE(region_cfp_table);
19959  
19960         for (i = 0; i < end ; i++) {
19961                 lbs_deb_main("region_cfp_table[i].region=%d\n",
19962 @@ -1091,9 +1443,8 @@ struct chan_freq_power *libertas_get_reg
19963         return NULL;
19964  }
19965  
19966 -int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
19967 +int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
19968  {
19969 -       wlan_adapter *adapter = priv->adapter;
19970         int ret = 0;
19971         int i = 0;
19972  
19973 @@ -1102,22 +1453,22 @@ int libertas_set_regiontable(wlan_privat
19974  
19975         lbs_deb_enter(LBS_DEB_MAIN);
19976  
19977 -       memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
19978 +       memset(priv->region_channel, 0, sizeof(priv->region_channel));
19979  
19980         {
19981 -               cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
19982 +               cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
19983                 if (cfp != NULL) {
19984 -                       adapter->region_channel[i].nrcfp = cfp_no;
19985 -                       adapter->region_channel[i].CFP = cfp;
19986 +                       priv->region_channel[i].nrcfp = cfp_no;
19987 +                       priv->region_channel[i].CFP = cfp;
19988                 } else {
19989                         lbs_deb_main("wrong region code %#x in band B/G\n",
19990                                region);
19991                         ret = -1;
19992                         goto out;
19993                 }
19994 -               adapter->region_channel[i].valid = 1;
19995 -               adapter->region_channel[i].region = region;
19996 -               adapter->region_channel[i].band = band;
19997 +               priv->region_channel[i].valid = 1;
19998 +               priv->region_channel[i].region = region;
19999 +               priv->region_channel[i].band = band;
20000                 i++;
20001         }
20002  out:
20003 @@ -1133,48 +1484,137 @@ out:
20004   *  @param dev     A pointer to net_device structure
20005   *  @return       n/a
20006   */
20007 -void libertas_interrupt(struct net_device *dev)
20008 +void lbs_interrupt(struct lbs_private *priv)
20009  {
20010 -       wlan_private *priv = dev->priv;
20011 -
20012         lbs_deb_enter(LBS_DEB_THREAD);
20013  
20014 -       lbs_deb_thread("libertas_interrupt: intcounter=%d\n",
20015 -              priv->adapter->intcounter);
20016 -
20017 -       priv->adapter->intcounter++;
20018 +       lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);
20019  
20020 -       if (priv->adapter->psstate == PS_STATE_SLEEP) {
20021 -               priv->adapter->psstate = PS_STATE_AWAKE;
20022 -               netif_wake_queue(dev);
20023 -               netif_wake_queue(priv->mesh_dev);
20024 +       if (!spin_is_locked(&priv->driver_lock)) {
20025 +               printk(KERN_CRIT "%s called without driver_lock held\n", __func__);
20026 +               WARN_ON(1);
20027         }
20028  
20029 -       wake_up_interruptible(&priv->mainthread.waitq);
20030 +       priv->intcounter++;
20031 +
20032 +       if (priv->psstate == PS_STATE_SLEEP)
20033 +               priv->psstate = PS_STATE_AWAKE;
20034 +
20035 +       wake_up_interruptible(&priv->waitq);
20036  
20037         lbs_deb_leave(LBS_DEB_THREAD);
20038  }
20039 -EXPORT_SYMBOL_GPL(libertas_interrupt);
20040 +EXPORT_SYMBOL_GPL(lbs_interrupt);
20041 +
20042 +int lbs_reset_device(struct lbs_private *priv)
20043 +{
20044 +       int ret;
20045 +
20046 +       lbs_deb_enter(LBS_DEB_MAIN);
20047 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
20048 +                                   CMD_ACT_HALT, 0, 0, NULL);
20049 +#ifdef CONFIG_OLPC
20050 +       if (machine_is_olpc()) {
20051 +               printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
20052 +               olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
20053 +       }
20054 +#endif
20055 +       msleep_interruptible(10);
20056 +
20057 +       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
20058 +       return ret;
20059 +}
20060 +EXPORT_SYMBOL_GPL(lbs_reset_device);
20061  
20062 -static int libertas_init_module(void)
20063 +static int __init lbs_init_module(void)
20064  {
20065         lbs_deb_enter(LBS_DEB_MAIN);
20066 -       libertas_debugfs_init();
20067 +       lbs_debugfs_init();
20068         lbs_deb_leave(LBS_DEB_MAIN);
20069         return 0;
20070  }
20071  
20072 -static void libertas_exit_module(void)
20073 +static void __exit lbs_exit_module(void)
20074  {
20075         lbs_deb_enter(LBS_DEB_MAIN);
20076  
20077 -       libertas_debugfs_remove();
20078 +       lbs_debugfs_remove();
20079  
20080         lbs_deb_leave(LBS_DEB_MAIN);
20081  }
20082  
20083 -module_init(libertas_init_module);
20084 -module_exit(libertas_exit_module);
20085 +/*
20086 + * rtap interface support fuctions
20087 + */
20088 +
20089 +static int lbs_rtap_open(struct net_device *dev)
20090 +{
20091 +       /* Yes, _stop_ the queue. Because we don't support injection */
20092 +        netif_carrier_off(dev);
20093 +        netif_stop_queue(dev);
20094 +        return 0;
20095 +}
20096 +
20097 +static int lbs_rtap_stop(struct net_device *dev)
20098 +{
20099 +        return 0;
20100 +}
20101 +
20102 +static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
20103 +{
20104 +        netif_stop_queue(dev);
20105 +        return NETDEV_TX_BUSY;
20106 +}
20107 +
20108 +static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
20109 +{
20110 +       struct lbs_private *priv = dev->priv;
20111 +       return &priv->stats;
20112 +}
20113 +
20114 +
20115 +static void lbs_remove_rtap(struct lbs_private *priv)
20116 +{
20117 +       if (priv->rtap_net_dev == NULL)
20118 +               return;
20119 +       unregister_netdev(priv->rtap_net_dev);
20120 +       free_netdev(priv->rtap_net_dev);
20121 +       priv->rtap_net_dev = NULL;
20122 +}
20123 +
20124 +static int lbs_add_rtap(struct lbs_private *priv)
20125 +{
20126 +       int rc = 0;
20127 +       struct net_device *rtap_dev;
20128 +
20129 +       if (priv->rtap_net_dev)
20130 +               return -EPERM;
20131 +
20132 +       rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
20133 +       if (rtap_dev == NULL)
20134 +               return -ENOMEM;
20135 +
20136 +       memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
20137 +       rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
20138 +       rtap_dev->open = lbs_rtap_open;
20139 +       rtap_dev->stop = lbs_rtap_stop;
20140 +       rtap_dev->get_stats = lbs_rtap_get_stats;
20141 +       rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
20142 +       rtap_dev->priv = priv;
20143 +
20144 +       rc = register_netdev(rtap_dev);
20145 +       if (rc) {
20146 +               free_netdev(rtap_dev);
20147 +               return rc;
20148 +       }
20149 +       priv->rtap_net_dev = rtap_dev;
20150 +
20151 +       return 0;
20152 +}
20153 +
20154 +
20155 +module_init(lbs_init_module);
20156 +module_exit(lbs_exit_module);
20157  
20158  MODULE_DESCRIPTION("Libertas WLAN Driver Library");
20159  MODULE_AUTHOR("Marvell International Ltd.");
20160 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/Makefile linux-2.6.22-300/drivers/net/wireless/libertas/Makefile
20161 --- linux-2.6.22-250/drivers/net/wireless/libertas/Makefile     2007-07-08 19:32:17.000000000 -0400
20162 +++ linux-2.6.22-300/drivers/net/wireless/libertas/Makefile     2008-06-05 18:10:06.000000000 -0400
20163 @@ -1,12 +1,11 @@
20164 -libertas-objs := main.o fw.o wext.o \
20165 -               rx.o tx.o cmd.o           \
20166 -               cmdresp.o scan.o          \
20167 -               join.o 11d.o              \
20168 -               debugfs.o         \
20169 -               ethtool.o assoc.o
20170 +libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o join.o \
20171 +                11d.o debugfs.o persistcfg.o ethtool.o assoc.o ioctl.o
20172  
20173 -usb8xxx-objs += if_bootcmd.o
20174  usb8xxx-objs += if_usb.o
20175 +libertas_cs-objs += if_cs.o
20176 +libertas_sdio-objs += if_sdio.o
20177  
20178  obj-$(CONFIG_LIBERTAS)     += libertas.o
20179  obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
20180 +obj-$(CONFIG_LIBERTAS_CS)  += libertas_cs.o
20181 +obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
20182 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/mesh_opts.c linux-2.6.22-300/drivers/net/wireless/libertas/mesh_opts.c
20183 --- linux-2.6.22-250/drivers/net/wireless/libertas/mesh_opts.c  1969-12-31 19:00:00.000000000 -0500
20184 +++ linux-2.6.22-300/drivers/net/wireless/libertas/mesh_opts.c  2008-06-05 18:10:06.000000000 -0400
20185 @@ -0,0 +1,174 @@
20186 +/*
20187 + * mesh_opts
20188 + *
20189 + * Author: Javier Cardona <javier@cozybit.com>
20190 + * Copyright: Marvell Semiconductors Inc., 2007
20191 + *
20192 + * Apply mesh-layer specific configuration to network flows.  Currently this
20193 + * only supports the mesh TTL parameter.
20194 + *
20195 + * Users call setsockopt on sockets to configure mesh parameters.  This module
20196 + * maintains a list of sockets (mesh_sks) that have different mesh parameters
20197 + * than the per-interface defaults.  The driver will modify the mesh
20198 + * configuration for each outgoing frame that belongs to one of the sockets in
20199 + * the mesh_sks list.
20200 + */
20201 +
20202 +#include <linux/module.h>
20203 +#include <linux/list.h>
20204 +#include <linux/net.h>
20205 +#include <linux/in.h>
20206 +#include <linux/netfilter.h>
20207 +#include <linux/netfilter_ipv4.h>
20208 +#include <linux/netfilter_ipv6.h>
20209 +#include <linux/spinlock.h>
20210 +#include <net/sock.h>
20211 +
20212 +#include <asm/uaccess.h>
20213 +
20214 +#include "mesh_opts.h"
20215 +
20216 +#define MESH_SO_BASE_CTL       MESH_SO_SET_TTL
20217 +
20218 +static struct list_head mesh_sks = LIST_HEAD_INIT(mesh_sks);
20219 +static DEFINE_RWLOCK(mesh_sks_lock);
20220 +
20221 +struct mesh_sock {
20222 +       struct list_head list;
20223 +
20224 +       struct sock *sk;
20225 +       unsigned char ttl;
20226 +       void (*orig_sk_destruct) (struct sock *sk);
20227 +};
20228 +
20229 +static struct mesh_sock * lookup_socket(struct sock *sk)
20230 +{
20231 +       struct mesh_sock *mesh_sk;
20232 +       struct mesh_sock *found_sk = NULL;
20233 +
20234 +       read_lock(&mesh_sks_lock);
20235 +       list_for_each_entry(mesh_sk, &mesh_sks, list) 
20236 +               if (mesh_sk->sk == sk) {
20237 +                       found_sk = mesh_sk;
20238 +                       break;
20239 +               }
20240 +       read_unlock(&mesh_sks_lock);
20241 +       return found_sk;
20242 +}
20243 +
20244 +static void mesh_sk_destruct(struct sock *sk)
20245 +{
20246 +       struct mesh_sock *mesh_sk;
20247 +       void (*orig_sk_destruct) (struct sock *sk);
20248 +
20249 +       mesh_sk = lookup_socket(sk);
20250 +
20251 +       if (mesh_sk) {
20252 +               orig_sk_destruct = mesh_sk->orig_sk_destruct;
20253 +               write_lock(&mesh_sks_lock);
20254 +               list_del(&mesh_sk->list);
20255 +               write_unlock(&mesh_sks_lock);
20256 +               kfree(mesh_sk);
20257 +               (*orig_sk_destruct)(sk);
20258 +       }
20259 +}
20260 +
20261 +static int do_mesh_set_mesh_ttl(struct sock *sk, void __user *user, unsigned int len)
20262 +{
20263 +       struct mesh_sock *mesh_sk;
20264 +       unsigned char ttl;
20265 +
20266 +
20267 +       if (len) {
20268 +               if (get_user(ttl, (unsigned char *) user))
20269 +                       return -EFAULT;
20270 +       } else
20271 +               return -EINVAL;
20272 +
20273 +       mesh_sk = (struct mesh_sock*) kmalloc(sizeof(struct mesh_sock), GFP_KERNEL);
20274 +       mesh_sk->ttl = ttl;
20275 +       mesh_sk->sk = sk;
20276 +       mesh_sk->orig_sk_destruct = sk->sk_destruct;
20277 +       sk->sk_destruct = mesh_sk_destruct;
20278 +       write_lock(&mesh_sks_lock);
20279 +       list_add(&mesh_sk->list, &mesh_sks);
20280 +       write_unlock(&mesh_sks_lock);
20281 +
20282 +       return 0;
20283 +}
20284 +
20285 +static int do_mesh_get_mesh_ttl(struct sock *sk, void __user *user, int *len)
20286 +{
20287 +       struct mesh_sock *mesh_sk;
20288 +       int rc = 0;
20289 +
20290 +       if ((mesh_sk = lookup_socket(sk)) == NULL)
20291 +               return -ENODATA;        
20292 +
20293 +       if (put_user(mesh_sk->ttl, (unsigned char*) user))
20294 +               return -EFAULT;
20295 +
20296 +       /* netfilter wrapper does the copy to user of len */
20297 +       *len = sizeof(unsigned char);
20298 +
20299 +       return rc;
20300 +}
20301 +
20302 +static int do_mesh_set_ctl(struct sock *sk, int optval, void __user *user,
20303 +               unsigned int len) 
20304 +{
20305 +       return do_mesh_set_mesh_ttl(sk, user, len);
20306 +}
20307 +
20308 +static int do_mesh_get_ctl(struct sock *sk, int optval, void __user *user, 
20309 +               int *len) 
20310 +{
20311 +       return do_mesh_get_mesh_ttl(sk, user, len);
20312 +}
20313 +
20314 +static unsigned char get_sock_mesh_ttl(struct sock *sk)
20315 +{
20316 +       struct mesh_sock *mesh_sk;
20317 +
20318 +       mesh_sk = lookup_socket(sk);
20319 +
20320 +       /* zero ttl results in using the network interface default */
20321 +       return mesh_sk ? mesh_sk->ttl : 0;      
20322 +}
20323 +
20324 +static struct mesh_options mesh_opts =
20325 +{
20326 +       .get_sock_ttl = get_sock_mesh_ttl,
20327 +};
20328 +
20329 +static struct nf_sockopt_ops mesh_sockopt_ops =
20330 +{
20331 +       .pf             = PF_INET,
20332 +       .set_optmin     = MESH_SO_BASE_CTL,
20333 +       .set_optmax     = MESH_SO_BASE_CTL + 1,
20334 +       .set            = do_mesh_set_ctl,
20335 +       .get_optmin     = MESH_SO_BASE_CTL,
20336 +       .get_optmax     = MESH_SO_BASE_CTL + 1,
20337 +       .get            = do_mesh_get_ctl,
20338 +};
20339 +
20340 +static int __init mesh_opts_init(void)
20341 +{
20342 +       int ret;
20343 +
20344 +       if ((ret = nf_register_sockopt(&mesh_sockopt_ops)) < 0) {
20345 +               return ret;
20346 +       }
20347 +       libertas_register_mesh_opts(&mesh_opts);
20348 +       return ret;
20349 +}
20350 +
20351 +static void __exit mesh_opts_fini(void)
20352 +{
20353 +       nf_unregister_sockopt(&mesh_sockopt_ops);
20354 +       libertas_unregister_mesh_opts(&mesh_opts);
20355 +}
20356 +
20357 +module_init(mesh_opts_init);
20358 +module_exit(mesh_opts_fini);
20359 +MODULE_LICENSE("GPL");
20360 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/mesh_opts.h linux-2.6.22-300/drivers/net/wireless/libertas/mesh_opts.h
20361 --- linux-2.6.22-250/drivers/net/wireless/libertas/mesh_opts.h  1969-12-31 19:00:00.000000000 -0500
20362 +++ linux-2.6.22-300/drivers/net/wireless/libertas/mesh_opts.h  2008-06-05 18:10:06.000000000 -0400
20363 @@ -0,0 +1,5 @@
20364 +
20365 +struct mesh_options {
20366 +       unsigned char (*get_sock_ttl)(struct sock*);
20367 +};
20368 +
20369 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/persistcfg.c linux-2.6.22-300/drivers/net/wireless/libertas/persistcfg.c
20370 --- linux-2.6.22-250/drivers/net/wireless/libertas/persistcfg.c 1969-12-31 19:00:00.000000000 -0500
20371 +++ linux-2.6.22-300/drivers/net/wireless/libertas/persistcfg.c 2008-06-05 18:10:06.000000000 -0400
20372 @@ -0,0 +1,453 @@
20373 +#include <linux/moduleparam.h>
20374 +#include <linux/delay.h>
20375 +#include <linux/etherdevice.h>
20376 +#include <linux/netdevice.h>
20377 +#include <linux/if_arp.h>
20378 +#include <linux/kthread.h>
20379 +#include <linux/kfifo.h>
20380 +
20381 +#include "host.h"
20382 +#include "decl.h"
20383 +#include "dev.h"
20384 +#include "wext.h"
20385 +#include "debugfs.h"
20386 +#include "scan.h"
20387 +#include "assoc.h"
20388 +#include "cmd.h"
20389 +
20390 +static int mesh_get_default_parameters(struct device *dev,
20391 +                                      struct mrvl_mesh_defaults *defs)
20392 +{
20393 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20394 +       struct cmd_ds_mesh_config cmd;
20395 +       int ret;
20396 +
20397 +       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
20398 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
20399 +                                  CMD_TYPE_MESH_GET_DEFAULTS);
20400 +
20401 +       if (ret)
20402 +               return -EOPNOTSUPP;
20403 +
20404 +       memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
20405 +
20406 +       return 0;
20407 +}
20408 +
20409 +/**
20410 + * @brief Get function for sysfs attribute bootflag
20411 + */
20412 +static ssize_t bootflag_get(struct device *dev,
20413 +                           struct device_attribute *attr, char *buf)
20414 +{
20415 +       struct mrvl_mesh_defaults defs;
20416 +       int ret;
20417 +
20418 +       ret = mesh_get_default_parameters(dev, &defs);
20419 +
20420 +       if (ret)
20421 +               return ret;
20422 +
20423 +       return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag));
20424 +}
20425 +
20426 +/**
20427 + * @brief Set function for sysfs attribute bootflag
20428 + */
20429 +static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
20430 +                           const char *buf, size_t count)
20431 +{
20432 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20433 +       struct cmd_ds_mesh_config cmd;
20434 +       uint32_t datum;
20435 +       int ret;
20436 +
20437 +       memset(&cmd, 0, sizeof(cmd));
20438 +       ret = sscanf(buf, "%x", &datum);
20439 +       if (ret != 1)
20440 +               return -EINVAL;
20441 +
20442 +       *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
20443 +       cmd.length = cpu_to_le16(sizeof(uint32_t));
20444 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20445 +                                  CMD_TYPE_MESH_SET_BOOTFLAG);
20446 +       if (ret)
20447 +               return ret;
20448 +
20449 +       return strlen(buf);
20450 +}
20451 +
20452 +/**
20453 + * @brief Get function for sysfs attribute boottime
20454 + */
20455 +static ssize_t boottime_get(struct device *dev,
20456 +                           struct device_attribute *attr, char *buf)
20457 +{
20458 +       struct mrvl_mesh_defaults defs;
20459 +       int ret;
20460 +
20461 +       ret = mesh_get_default_parameters(dev, &defs);
20462 +
20463 +       if (ret)
20464 +               return ret;
20465 +
20466 +       return snprintf(buf, 12, "0x%x\n", defs.boottime);
20467 +}
20468 +
20469 +/**
20470 + * @brief Set function for sysfs attribute boottime
20471 + */
20472 +static ssize_t boottime_set(struct device *dev,
20473 +               struct device_attribute *attr, const char *buf, size_t count)
20474 +{
20475 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20476 +       struct cmd_ds_mesh_config cmd;
20477 +       uint32_t datum;
20478 +       int ret;
20479 +
20480 +       memset(&cmd, 0, sizeof(cmd));
20481 +       ret = sscanf(buf, "%x", &datum);
20482 +       if (ret != 1)
20483 +               return -EINVAL;
20484 +
20485 +       /* A too small boot time will result in the device booting into
20486 +        * standalone (no-host) mode before the host can take control of it,
20487 +        * so the change will be hard to revert.  This may be a desired
20488 +        * feature (e.g to configure a very fast boot time for devices that
20489 +        * will not be attached to a host), but dangerous.  So I'm enforcing a
20490 +        * lower limit of 20 seconds:  remove and recompile the driver if this
20491 +        * does not work for you.
20492 +        */
20493 +       datum = (datum < 20) ? 20 : datum;
20494 +       cmd.data[0] = datum;
20495 +       cmd.length = cpu_to_le16(sizeof(uint8_t));
20496 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20497 +                                  CMD_TYPE_MESH_SET_BOOTTIME);
20498 +       if (ret)
20499 +               return ret;
20500 +
20501 +       return strlen(buf);
20502 +}
20503 +
20504 +/**
20505 + * @brief Get function for sysfs attribute channel
20506 + */
20507 +static ssize_t channel_get(struct device *dev,
20508 +                           struct device_attribute *attr, char *buf)
20509 +{
20510 +       struct mrvl_mesh_defaults defs;
20511 +       int ret;
20512 +
20513 +       ret = mesh_get_default_parameters(dev, &defs);
20514 +
20515 +       if (ret)
20516 +               return ret;
20517 +
20518 +       return snprintf(buf, 12, "0x%x\n", le16_to_cpu(defs.channel));
20519 +}
20520 +
20521 +/**
20522 + * @brief Set function for sysfs attribute channel
20523 + */
20524 +static ssize_t channel_set(struct device *dev,
20525 +               struct device_attribute *attr, const char *buf, size_t count)
20526 +{
20527 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20528 +       struct cmd_ds_mesh_config cmd;
20529 +       uint16_t datum;
20530 +       int ret;
20531 +
20532 +       memset(&cmd, 0, sizeof(cmd));
20533 +       ret = sscanf(buf, "%hx", &datum);
20534 +       if (ret != 1 || datum < 1 || datum > 11)
20535 +               return -EINVAL;
20536 +
20537 +       *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
20538 +       cmd.length = cpu_to_le16(sizeof(uint16_t));
20539 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20540 +                                  CMD_TYPE_MESH_SET_DEF_CHANNEL);
20541 +       if (ret)
20542 +               return ret;
20543 +
20544 +       return strlen(buf);
20545 +}
20546 +
20547 +/**
20548 + * @brief Get function for sysfs attribute mesh_id
20549 + */
20550 +static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
20551 +                          char *buf)
20552 +{
20553 +       struct mrvl_mesh_defaults defs;
20554 +       int maxlen;
20555 +       int ret;
20556 +
20557 +       ret = mesh_get_default_parameters(dev, &defs);
20558 +
20559 +       if (ret)
20560 +               return ret;
20561 +
20562 +       if (defs.meshie.val.mesh_id_len > IW_ESSID_MAX_SIZE) {
20563 +               printk(KERN_ERR "Inconsistent mesh ID length");
20564 +               defs.meshie.val.mesh_id_len = IW_ESSID_MAX_SIZE;
20565 +       }
20566 +
20567 +       /* SSID not null terminated: reserve room for \0 + \n */
20568 +       maxlen = defs.meshie.val.mesh_id_len + 2;
20569 +       maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
20570 +
20571 +       defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
20572 +
20573 +       return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
20574 +}
20575 +
20576 +/**
20577 + * @brief Set function for sysfs attribute mesh_id
20578 + */
20579 +static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
20580 +                          const char *buf, size_t count)
20581 +{
20582 +       struct cmd_ds_mesh_config cmd;
20583 +       struct mrvl_mesh_defaults defs;
20584 +       struct mrvl_meshie *ie;
20585 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20586 +       int len;
20587 +       int ret;
20588 +
20589 +       if (count < 2 || count > IW_ESSID_MAX_SIZE + 1)
20590 +               return -EINVAL;
20591 +
20592 +       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
20593 +       ie = (struct mrvl_meshie *) &cmd.data[0];
20594 +
20595 +       /* fetch all other Information Element parameters */
20596 +       ret = mesh_get_default_parameters(dev, &defs);
20597 +
20598 +       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
20599 +
20600 +       /* transfer IE elements */
20601 +       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
20602 +
20603 +       len = count - 1;
20604 +       memcpy(ie->val.mesh_id, buf, len);
20605 +       /* SSID len */
20606 +       ie->val.mesh_id_len = len;
20607 +       /* IE len */
20608 +       ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
20609 +
20610 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20611 +                                  CMD_TYPE_MESH_SET_MESH_IE);
20612 +       if (ret)
20613 +               return ret;
20614 +
20615 +       return strlen(buf);
20616 +}
20617 +
20618 +/**
20619 + * @brief Get function for sysfs attribute protocol_id
20620 + */
20621 +static ssize_t protocol_id_get(struct device *dev,
20622 +                              struct device_attribute *attr, char *buf)
20623 +{
20624 +       struct mrvl_mesh_defaults defs;
20625 +       int ret;
20626 +
20627 +       ret = mesh_get_default_parameters(dev, &defs);
20628 +
20629 +       if (ret)
20630 +               return ret;
20631 +
20632 +       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
20633 +}
20634 +
20635 +/**
20636 + * @brief Set function for sysfs attribute protocol_id
20637 + */
20638 +static ssize_t protocol_id_set(struct device *dev,
20639 +               struct device_attribute *attr, const char *buf, size_t count)
20640 +{
20641 +       struct cmd_ds_mesh_config cmd;
20642 +       struct mrvl_mesh_defaults defs;
20643 +       struct mrvl_meshie *ie;
20644 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20645 +       uint32_t datum;
20646 +       int ret;
20647 +
20648 +       memset(&cmd, 0, sizeof(cmd));
20649 +       ret = sscanf(buf, "%x", &datum);
20650 +       if (ret != 1)
20651 +               return -EINVAL;
20652 +
20653 +       /* fetch all other Information Element parameters */
20654 +       ret = mesh_get_default_parameters(dev, &defs);
20655 +
20656 +       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
20657 +
20658 +       /* transfer IE elements */
20659 +       ie = (struct mrvl_meshie *) &cmd.data[0];
20660 +       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
20661 +       /* update protocol id */
20662 +       ie->val.active_protocol_id = datum;
20663 +
20664 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20665 +                                  CMD_TYPE_MESH_SET_MESH_IE);
20666 +       if (ret)
20667 +               return ret;
20668 +
20669 +       return strlen(buf);
20670 +}
20671 +
20672 +/**
20673 + * @brief Get function for sysfs attribute metric_id
20674 + */
20675 +static ssize_t metric_id_get(struct device *dev,
20676 +               struct device_attribute *attr, char *buf)
20677 +{
20678 +       struct mrvl_mesh_defaults defs;
20679 +       int ret;
20680 +
20681 +       ret = mesh_get_default_parameters(dev, &defs);
20682 +
20683 +       if (ret)
20684 +               return ret;
20685 +
20686 +       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
20687 +}
20688 +
20689 +/**
20690 + * @brief Set function for sysfs attribute metric_id
20691 + */
20692 +static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
20693 +                            const char *buf, size_t count)
20694 +{
20695 +       struct cmd_ds_mesh_config cmd;
20696 +       struct mrvl_mesh_defaults defs;
20697 +       struct mrvl_meshie *ie;
20698 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20699 +       uint32_t datum;
20700 +       int ret;
20701 +
20702 +       memset(&cmd, 0, sizeof(cmd));
20703 +       ret = sscanf(buf, "%x", &datum);
20704 +       if (ret != 1)
20705 +               return -EINVAL;
20706 +
20707 +       /* fetch all other Information Element parameters */
20708 +       ret = mesh_get_default_parameters(dev, &defs);
20709 +
20710 +       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
20711 +
20712 +       /* transfer IE elements */
20713 +       ie = (struct mrvl_meshie *) &cmd.data[0];
20714 +       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
20715 +       /* update metric id */
20716 +       ie->val.active_metric_id = datum;
20717 +
20718 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20719 +                                  CMD_TYPE_MESH_SET_MESH_IE);
20720 +       if (ret)
20721 +               return ret;
20722 +
20723 +       return strlen(buf);
20724 +}
20725 +
20726 +/**
20727 + * @brief Get function for sysfs attribute capability
20728 + */
20729 +static ssize_t capability_get(struct device *dev,
20730 +               struct device_attribute *attr, char *buf)
20731 +{
20732 +       struct mrvl_mesh_defaults defs;
20733 +       int ret;
20734 +
20735 +       ret = mesh_get_default_parameters(dev, &defs);
20736 +
20737 +       if (ret)
20738 +               return ret;
20739 +
20740 +       return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
20741 +}
20742 +
20743 +/**
20744 + * @brief Set function for sysfs attribute capability
20745 + */
20746 +static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
20747 +                             const char *buf, size_t count)
20748 +{
20749 +       struct cmd_ds_mesh_config cmd;
20750 +       struct mrvl_mesh_defaults defs;
20751 +       struct mrvl_meshie *ie;
20752 +       struct lbs_private *priv = to_net_dev(dev)->priv;
20753 +       uint32_t datum;
20754 +       int ret;
20755 +
20756 +       memset(&cmd, 0, sizeof(cmd));
20757 +       ret = sscanf(buf, "%x", &datum);
20758 +       if (ret != 1)
20759 +               return -EINVAL;
20760 +
20761 +       /* fetch all other Information Element parameters */
20762 +       ret = mesh_get_default_parameters(dev, &defs);
20763 +
20764 +       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
20765 +
20766 +       /* transfer IE elements */
20767 +       ie = (struct mrvl_meshie *) &cmd.data[0];
20768 +       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
20769 +       /* update value */
20770 +       ie->val.mesh_capability = datum;
20771 +
20772 +       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
20773 +                                  CMD_TYPE_MESH_SET_MESH_IE);
20774 +       if (ret)
20775 +               return ret;
20776 +
20777 +       return strlen(buf);
20778 +}
20779 +
20780 +
20781 +static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
20782 +static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
20783 +static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
20784 +static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
20785 +static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
20786 +static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
20787 +static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
20788 +
20789 +static struct attribute *boot_opts_attrs[] = {
20790 +       &dev_attr_bootflag.attr,
20791 +       &dev_attr_boottime.attr,
20792 +       &dev_attr_channel.attr,
20793 +       NULL
20794 +};
20795 +
20796 +static struct attribute_group boot_opts_group = {
20797 +       .name = "boot_options",
20798 +       .attrs = boot_opts_attrs,
20799 +};
20800 +
20801 +static struct attribute *mesh_ie_attrs[] = {
20802 +       &dev_attr_mesh_id.attr,
20803 +       &dev_attr_protocol_id.attr,
20804 +       &dev_attr_metric_id.attr,
20805 +       &dev_attr_capability.attr,
20806 +       NULL
20807 +};
20808 +
20809 +static struct attribute_group mesh_ie_group = {
20810 +       .name = "mesh_ie",
20811 +       .attrs = mesh_ie_attrs,
20812 +};
20813 +
20814 +void lbs_persist_config_init(struct net_device *dev)
20815 +{
20816 +       int ret;
20817 +       ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
20818 +       ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
20819 +}
20820 +
20821 +void lbs_persist_config_remove(struct net_device *dev)
20822 +{
20823 +       sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
20824 +       sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
20825 +}
20826 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/README linux-2.6.22-300/drivers/net/wireless/libertas/README
20827 --- linux-2.6.22-250/drivers/net/wireless/libertas/README       2007-07-08 19:32:17.000000000 -0400
20828 +++ linux-2.6.22-300/drivers/net/wireless/libertas/README       2008-06-05 18:10:06.000000000 -0400
20829 @@ -195,45 +195,33 @@ setuserscan
20830  
20831           where [ARGS]:
20832  
20833 -      chan=[chan#][band][mode] where band is [a,b,g] and mode is
20834 -                               blank for active or 'p' for passive
20835        bssid=xx:xx:xx:xx:xx:xx  specify a BSSID filter for the scan
20836        ssid="[SSID]"            specify a SSID filter for the scan
20837        keep=[0 or 1]            keep the previous scan results (1), discard (0)
20838        dur=[scan time]          time to scan for each channel in milliseconds
20839 -      probes=[#]               number of probe requests to send on each chan
20840        type=[1,2,3]             BSS type: 1 (Infra), 2(Adhoc), 3(Any)
20841  
20842 -    Any combination of the above arguments can be supplied on the command line.
20843 -      If the chan token is absent, a full channel scan will be completed by
20844 -      the driver.  If the dur or probes tokens are absent, the driver default
20845 -      setting will be used.  The bssid and ssid fields, if blank,
20846 -      will produce an unfiltered scan. The type field will default to 3 (Any)
20847 -      and the keep field will default to 0 (Discard).
20848 +    Any combination of the above arguments can be supplied on the command
20849 +    line. If dur tokens are absent, the driver default setting will be used.
20850 +    The bssid and ssid fields, if blank, will produce an unfiltered scan.
20851 +    The type field will default to 3 (Any) and the keep field will default
20852 +    to 0 (Discard).
20853  
20854      Examples:
20855 -    1) Perform an active scan on channels 1, 6, and 11 in the 'g' band:
20856 -            echo "chan=1g,6g,11g" > setuserscan
20857 +    1) Perform a passive scan on all channels for 20 ms per channel:
20858 +            echo "dur=20" > setuserscan
20859  
20860 -    2) Perform a passive scan on channel 11 for 20 ms:
20861 -            echo "chan=11gp dur=20" > setuserscan
20862 +    2) Perform an active scan for a specific SSID:
20863 +            echo "ssid="TestAP"" > setuserscan
20864  
20865 -    3) Perform an active scan on channels 1, 6, and 11; and a passive scan on
20866 -       channel 36 in the 'a' band:
20867 -
20868 -            echo "chan=1g,6g,11g,36ap" > setuserscan
20869 -
20870 -    4) Perform an active scan on channel 6 and 36 for a specific SSID:
20871 -            echo "chan=6g,36a ssid="TestAP"" > setuserscan
20872 -
20873 -    5) Scan all available channels (B/G, A bands) for a specific BSSID, keep
20874 +    3) Scan all available channels (B/G, A bands) for a specific BSSID, keep
20875         the current scan table intact, update existing or append new scan data:
20876              echo "bssid=00:50:43:20:12:82 keep=1" > setuserscan
20877  
20878 -    6) Scan channel 6, for all infrastructure networks, sending two probe
20879 -       requests.  Keep the previous scan table intact. Update any duplicate
20880 -       BSSID/SSID matches with the new scan data:
20881 -            echo "chan=6g type=1 probes=2 keep=1" > setuserscan
20882 +    4) Scan for all infrastructure networks.
20883 +       Keep the previous scan table intact. Update any duplicate BSSID/SSID
20884 +       matches with the new scan data:
20885 +            echo "type=1 keep=1" > setuserscan
20886  
20887      All entries in the scan table (not just the new scan data when keep=1)
20888      will be displayed upon completion by use of the getscantable ioctl.
20889 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/rx.c linux-2.6.22-300/drivers/net/wireless/libertas/rx.c
20890 --- linux-2.6.22-250/drivers/net/wireless/libertas/rx.c 2007-07-08 19:32:17.000000000 -0400
20891 +++ linux-2.6.22-300/drivers/net/wireless/libertas/rx.c 2008-06-05 18:10:06.000000000 -0400
20892 @@ -35,133 +35,114 @@ struct rx80211packethdr {
20893         void *eth80211_hdr;
20894  } __attribute__ ((packed));
20895  
20896 -static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb);
20897 +static int process_rxed_802_11_packet(struct lbs_private *priv,
20898 +       struct sk_buff *skb);
20899  
20900  /**
20901   *  @brief This function computes the avgSNR .
20902   *
20903 - *  @param priv    A pointer to wlan_private structure
20904 + *  @param priv    A pointer to struct lbs_private structure
20905   *  @return       avgSNR
20906   */
20907 -static u8 wlan_getavgsnr(wlan_private * priv)
20908 +static u8 lbs_getavgsnr(struct lbs_private *priv)
20909  {
20910         u8 i;
20911         u16 temp = 0;
20912 -       wlan_adapter *adapter = priv->adapter;
20913 -       if (adapter->numSNRNF == 0)
20914 +       if (priv->numSNRNF == 0)
20915                 return 0;
20916 -       for (i = 0; i < adapter->numSNRNF; i++)
20917 -               temp += adapter->rawSNR[i];
20918 -       return (u8) (temp / adapter->numSNRNF);
20919 +       for (i = 0; i < priv->numSNRNF; i++)
20920 +               temp += priv->rawSNR[i];
20921 +       return (u8) (temp / priv->numSNRNF);
20922  
20923  }
20924  
20925  /**
20926   *  @brief This function computes the AvgNF
20927   *
20928 - *  @param priv    A pointer to wlan_private structure
20929 + *  @param priv    A pointer to struct lbs_private structure
20930   *  @return       AvgNF
20931   */
20932 -static u8 wlan_getavgnf(wlan_private * priv)
20933 +static u8 lbs_getavgnf(struct lbs_private *priv)
20934  {
20935         u8 i;
20936         u16 temp = 0;
20937 -       wlan_adapter *adapter = priv->adapter;
20938 -       if (adapter->numSNRNF == 0)
20939 +       if (priv->numSNRNF == 0)
20940                 return 0;
20941 -       for (i = 0; i < adapter->numSNRNF; i++)
20942 -               temp += adapter->rawNF[i];
20943 -       return (u8) (temp / adapter->numSNRNF);
20944 +       for (i = 0; i < priv->numSNRNF; i++)
20945 +               temp += priv->rawNF[i];
20946 +       return (u8) (temp / priv->numSNRNF);
20947  
20948  }
20949  
20950  /**
20951   *  @brief This function save the raw SNR/NF to our internel buffer
20952   *
20953 - *  @param priv    A pointer to wlan_private structure
20954 + *  @param priv    A pointer to struct lbs_private structure
20955   *  @param prxpd   A pointer to rxpd structure of received packet
20956   *  @return       n/a
20957   */
20958 -static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd)
20959 +static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
20960  {
20961 -       wlan_adapter *adapter = priv->adapter;
20962 -       if (adapter->numSNRNF < adapter->data_avg_factor)
20963 -               adapter->numSNRNF++;
20964 -       adapter->rawSNR[adapter->nextSNRNF] = p_rx_pd->snr;
20965 -       adapter->rawNF[adapter->nextSNRNF] = p_rx_pd->nf;
20966 -       adapter->nextSNRNF++;
20967 -       if (adapter->nextSNRNF >= adapter->data_avg_factor)
20968 -               adapter->nextSNRNF = 0;
20969 +       if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
20970 +               priv->numSNRNF++;
20971 +       priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr;
20972 +       priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf;
20973 +       priv->nextSNRNF++;
20974 +       if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
20975 +               priv->nextSNRNF = 0;
20976         return;
20977  }
20978  
20979  /**
20980   *  @brief This function computes the RSSI in received packet.
20981   *
20982 - *  @param priv    A pointer to wlan_private structure
20983 + *  @param priv    A pointer to struct lbs_private structure
20984   *  @param prxpd   A pointer to rxpd structure of received packet
20985   *  @return       n/a
20986   */
20987 -static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
20988 +static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
20989  {
20990 -       wlan_adapter *adapter = priv->adapter;
20991  
20992         lbs_deb_enter(LBS_DEB_RX);
20993  
20994         lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
20995         lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
20996 -              adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
20997 -              adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
20998 +              priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
20999 +              priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
21000  
21001 -       adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
21002 -       adapter->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
21003 -       wlan_save_rawSNRNF(priv, p_rx_pd);
21004 +       priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
21005 +       priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
21006 +       lbs_save_rawSNRNF(priv, p_rx_pd);
21007  
21008 -       adapter->rxpd_rate = p_rx_pd->rx_rate;
21009 -
21010 -       adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE;
21011 -       adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE;
21012 +       priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE;
21013 +       priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE;
21014         lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
21015 -              adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
21016 -              adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
21017 +              priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
21018 +              priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
21019  
21020 -       adapter->RSSI[TYPE_RXPD][TYPE_NOAVG] =
21021 -           CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
21022 -                    adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
21023 -
21024 -       adapter->RSSI[TYPE_RXPD][TYPE_AVG] =
21025 -           CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
21026 -                    adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
21027 +       priv->RSSI[TYPE_RXPD][TYPE_NOAVG] =
21028 +           CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG],
21029 +                    priv->NF[TYPE_RXPD][TYPE_NOAVG]);
21030 +
21031 +       priv->RSSI[TYPE_RXPD][TYPE_AVG] =
21032 +           CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
21033 +                    priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
21034  
21035         lbs_deb_leave(LBS_DEB_RX);
21036  }
21037  
21038 -void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
21039 -{
21040 -       lbs_deb_rx("skb->data %p\n", skb->data);
21041 -
21042 -       if (priv->mesh_dev && IS_MESH_FRAME(skb))
21043 -               skb->protocol = eth_type_trans(skb, priv->mesh_dev);
21044 -       else
21045 -               skb->protocol = eth_type_trans(skb, priv->dev);
21046 -       skb->ip_summed = CHECKSUM_UNNECESSARY;
21047 -
21048 -       netif_rx(skb);
21049 -}
21050 -
21051  /**
21052   *  @brief This function processes received packet and forwards it
21053   *  to kernel/upper layer
21054   *
21055 - *  @param priv    A pointer to wlan_private
21056 + *  @param priv    A pointer to struct lbs_private
21057   *  @param skb     A pointer to skb which includes the received packet
21058   *  @return       0 or -1
21059   */
21060 -int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
21061 +int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
21062  {
21063 -       wlan_adapter *adapter = priv->adapter;
21064         int ret = 0;
21065 -
21066 +       struct net_device *dev = priv->dev;
21067         struct rxpackethdr *p_rx_pkt;
21068         struct rxpd *p_rx_pd;
21069  
21070 @@ -172,21 +153,17 @@ int libertas_process_rxed_packet(wlan_pr
21071  
21072         lbs_deb_enter(LBS_DEB_RX);
21073  
21074 -       if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH)
21075 -               lbs_dbg_hex("RX packet: ", skb->data,
21076 -                        min_t(unsigned int, skb->len, 100));
21077 +       skb->ip_summed = CHECKSUM_NONE;
21078  
21079 -       if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
21080 +       if (priv->monitormode != LBS_MONITOR_OFF)
21081                 return process_rxed_802_11_packet(priv, skb);
21082  
21083         p_rx_pkt = (struct rxpackethdr *) skb->data;
21084         p_rx_pd = &p_rx_pkt->rx_pd;
21085 -       if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
21086 -               SET_MESH_FRAME(skb);
21087 -       else
21088 -               UNSET_MESH_FRAME(skb);
21089 +       if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
21090 +               dev = priv->mesh_dev;
21091  
21092 -       lbs_dbg_hex("RX Data: Before chop rxpd", skb->data,
21093 +       lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
21094                  min_t(unsigned int, skb->len, 100));
21095  
21096         if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
21097 @@ -210,9 +187,9 @@ int libertas_process_rxed_packet(wlan_pr
21098         lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
21099                skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
21100  
21101 -       lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
21102 +       lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
21103                 sizeof(p_rx_pkt->eth803_hdr.dest_addr));
21104 -       lbs_dbg_hex("RX Data: Src", p_rx_pkt->eth803_hdr.src_addr,
21105 +       lbs_deb_hex(LBS_DEB_RX, "RX Data: Src", p_rx_pkt->eth803_hdr.src_addr,
21106                 sizeof(p_rx_pkt->eth803_hdr.src_addr));
21107  
21108         if (memcmp(&p_rx_pkt->rfc1042_hdr,
21109 @@ -244,7 +221,7 @@ int libertas_process_rxed_packet(wlan_pr
21110                  */
21111                 hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
21112         } else {
21113 -               lbs_dbg_hex("RX Data: LLC/SNAP",
21114 +               lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
21115                         (u8 *) & p_rx_pkt->rfc1042_hdr,
21116                         sizeof(p_rx_pkt->rfc1042_hdr));
21117  
21118 @@ -260,23 +237,24 @@ int libertas_process_rxed_packet(wlan_pr
21119         /* Take the data rate from the rxpd structure
21120          * only if the rate is auto
21121          */
21122 -       if (adapter->is_datarate_auto)
21123 -               adapter->datarate = libertas_index_to_data_rate(p_rx_pd->rx_rate);
21124 +       if (priv->auto_rate)
21125 +               priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
21126  
21127 -       wlan_compute_rssi(priv, p_rx_pd);
21128 +       lbs_compute_rssi(priv, p_rx_pd);
21129  
21130         lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
21131         priv->stats.rx_bytes += skb->len;
21132         priv->stats.rx_packets++;
21133  
21134 -       libertas_upload_rx_packet(priv, skb);
21135 +       skb->protocol = eth_type_trans(skb, dev);
21136 +       netif_rx(skb);
21137  
21138         ret = 0;
21139  done:
21140         lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
21141         return ret;
21142  }
21143 -EXPORT_SYMBOL_GPL(libertas_process_rxed_packet);
21144 +EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
21145  
21146  /**
21147   *  @brief This function converts Tx/Rx rates from the Marvell WLAN format
21148 @@ -296,21 +274,22 @@ static u8 convert_mv_rate_to_radiotap(u8
21149                 return 11;
21150         case 3:         /*  11 Mbps */
21151                 return 22;
21152 -       case 4:         /*   6 Mbps */
21153 +       /* case 4: reserved */
21154 +       case 5:         /*   6 Mbps */
21155                 return 12;
21156 -       case 5:         /*   9 Mbps */
21157 +       case 6:         /*   9 Mbps */
21158                 return 18;
21159 -       case 6:         /*  12 Mbps */
21160 +       case 7:         /*  12 Mbps */
21161                 return 24;
21162 -       case 7:         /*  18 Mbps */
21163 +       case 8:         /*  18 Mbps */
21164                 return 36;
21165 -       case 8:         /*  24 Mbps */
21166 +       case 9:         /*  24 Mbps */
21167                 return 48;
21168 -       case 9:         /*  36 Mbps */
21169 +       case 10:                /*  36 Mbps */
21170                 return 72;
21171 -       case 10:                /*  48 Mbps */
21172 +       case 11:                /*  48 Mbps */
21173                 return 96;
21174 -       case 11:                /*  54 Mbps */
21175 +       case 12:                /*  54 Mbps */
21176                 return 108;
21177         }
21178         lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
21179 @@ -321,13 +300,13 @@ static u8 convert_mv_rate_to_radiotap(u8
21180   *  @brief This function processes a received 802.11 packet and forwards it
21181   *  to kernel/upper layer
21182   *
21183 - *  @param priv    A pointer to wlan_private
21184 + *  @param priv    A pointer to struct lbs_private
21185   *  @param skb     A pointer to skb which includes the received packet
21186   *  @return       0 or -1
21187   */
21188 -static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
21189 +static int process_rxed_802_11_packet(struct lbs_private *priv,
21190 +       struct sk_buff *skb)
21191  {
21192 -       wlan_adapter *adapter = priv->adapter;
21193         int ret = 0;
21194  
21195         struct rx80211packethdr *p_rx_pkt;
21196 @@ -340,12 +319,13 @@ static int process_rxed_802_11_packet(wl
21197         p_rx_pkt = (struct rx80211packethdr *) skb->data;
21198         prxpd = &p_rx_pkt->rx_pd;
21199  
21200 -       // lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
21201 +       // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
21202  
21203         if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
21204 -               lbs_deb_rx("rx err: frame received wit bad length\n");
21205 +               lbs_deb_rx("rx err: frame received with bad length\n");
21206                 priv->stats.rx_length_errors++;
21207 -               ret = 0;
21208 +               ret = -EINVAL;
21209 +               kfree(skb);
21210                 goto done;
21211         }
21212  
21213 @@ -361,85 +341,60 @@ static int process_rxed_802_11_packet(wl
21214                skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
21215  
21216         /* create the exported radio header */
21217 -       switch (priv->adapter->radiomode) {
21218 -       case WLAN_RADIOMODE_NONE:
21219 -               /* no radio header */
21220 -               /* chop the rxpd */
21221 -               skb_pull(skb, sizeof(struct rxpd));
21222 -               break;
21223 -
21224 -       case WLAN_RADIOMODE_RADIOTAP:
21225 -               /* radiotap header */
21226 -               radiotap_hdr.hdr.it_version = 0;
21227 -               /* XXX must check this value for pad */
21228 -               radiotap_hdr.hdr.it_pad = 0;
21229 -               radiotap_hdr.hdr.it_len = sizeof(struct rx_radiotap_hdr);
21230 -               radiotap_hdr.hdr.it_present = RX_RADIOTAP_PRESENT;
21231 -               /* unknown values */
21232 -               radiotap_hdr.flags = 0;
21233 -               radiotap_hdr.chan_freq = 0;
21234 -               radiotap_hdr.chan_flags = 0;
21235 -               radiotap_hdr.antenna = 0;
21236 -               /* known values */
21237 -               radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
21238 -               /* XXX must check no carryout */
21239 -               radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
21240 -               radiotap_hdr.rx_flags = 0;
21241 -               if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
21242 -                       radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
21243 -               //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
21244 -
21245 -               // lbs_dbg_hex1("RX radiomode packet BEF: ", skb->data, min(skb->len, 100));
21246 -
21247 -               /* chop the rxpd */
21248 -               skb_pull(skb, sizeof(struct rxpd));
21249 -
21250 -               /* add space for the new radio header */
21251 -               if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
21252 -                   pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
21253 -                                    GFP_ATOMIC)) {
21254 -                       lbs_pr_alert("%s: couldn't pskb_expand_head\n",
21255 -                              __func__);
21256 -               }
21257 -
21258 -               pradiotap_hdr =
21259 -                   (struct rx_radiotap_hdr *)skb_push(skb,
21260 -                                                    sizeof(struct
21261 -                                                           rx_radiotap_hdr));
21262 -               memcpy(pradiotap_hdr, &radiotap_hdr,
21263 -                      sizeof(struct rx_radiotap_hdr));
21264 -               //lbs_dbg_hex1("RX radiomode packet AFT: ", skb->data, min(skb->len, 100));
21265 -               break;
21266 -
21267 -       default:
21268 -               /* unknown header */
21269 -               lbs_pr_alert("Unknown radiomode %i\n",
21270 -                      priv->adapter->radiomode);
21271 -               /* don't export any header */
21272 -               /* chop the rxpd */
21273 -               skb_pull(skb, sizeof(struct rxpd));
21274 -               break;
21275 +
21276 +       /* radiotap header */
21277 +       radiotap_hdr.hdr.it_version = 0;
21278 +       /* XXX must check this value for pad */
21279 +       radiotap_hdr.hdr.it_pad = 0;
21280 +       radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
21281 +       radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
21282 +       /* unknown values */
21283 +       radiotap_hdr.flags = 0;
21284 +       radiotap_hdr.chan_freq = 0;
21285 +       radiotap_hdr.chan_flags = 0;
21286 +       radiotap_hdr.antenna = 0;
21287 +       /* known values */
21288 +       radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
21289 +       /* XXX must check no carryout */
21290 +       radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
21291 +       radiotap_hdr.rx_flags = 0;
21292 +       if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
21293 +               radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
21294 +       //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
21295 +
21296 +       /* chop the rxpd */
21297 +       skb_pull(skb, sizeof(struct rxpd));
21298 +
21299 +       /* add space for the new radio header */
21300 +       if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
21301 +           pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
21302 +               lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
21303 +               ret = -ENOMEM;
21304 +               kfree_skb(skb);
21305 +               goto done;
21306         }
21307  
21308 +       pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
21309 +       memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));
21310 +
21311         /* Take the data rate from the rxpd structure
21312          * only if the rate is auto
21313          */
21314 -       if (adapter->is_datarate_auto) {
21315 -               adapter->datarate = libertas_index_to_data_rate(prxpd->rx_rate);
21316 -       }
21317 +       if (priv->auto_rate)
21318 +               priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
21319  
21320 -       wlan_compute_rssi(priv, prxpd);
21321 +       lbs_compute_rssi(priv, prxpd);
21322  
21323         lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
21324         priv->stats.rx_bytes += skb->len;
21325         priv->stats.rx_packets++;
21326  
21327 -       libertas_upload_rx_packet(priv, skb);
21328 +       skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
21329 +       netif_rx(skb);
21330  
21331         ret = 0;
21332  
21333  done:
21334 -       skb->protocol = __constant_htons(0x0019);       /* ETH_P_80211_RAW */
21335         lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
21336         return ret;
21337  }
21338 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/scan.c linux-2.6.22-300/drivers/net/wireless/libertas/scan.c
21339 --- linux-2.6.22-250/drivers/net/wireless/libertas/scan.c       2007-07-08 19:32:17.000000000 -0400
21340 +++ linux-2.6.22-300/drivers/net/wireless/libertas/scan.c       2008-06-05 18:10:06.000000000 -0400
21341 @@ -13,10 +13,13 @@
21342  #include <net/ieee80211.h>
21343  #include <net/iw_handler.h>
21344  
21345 +#include <asm/unaligned.h>
21346 +
21347  #include "host.h"
21348  #include "decl.h"
21349  #include "dev.h"
21350  #include "scan.h"
21351 +#include "join.h"
21352  
21353  //! Approximate amount of data needed to pass a scan result back to iwlist
21354  #define MAX_SCAN_CELL_SIZE  (IW_EV_ADDR_LEN             \
21355 @@ -36,9 +39,8 @@
21356  //! Memory needed to store a max number/size SSID TLV for a firmware scan
21357  #define SSID_TLV_MAX_SIZE  (1 * sizeof(struct mrvlietypes_ssidparamset))
21358  
21359 -//! Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max
21360 -#define MAX_SCAN_CFG_ALLOC (sizeof(struct wlan_scan_cmd_config)  \
21361 -                            + sizeof(struct mrvlietypes_numprobes)   \
21362 +//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max
21363 +#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config)  \
21364                              + CHAN_TLV_MAX_SIZE                 \
21365                              + SSID_TLV_MAX_SIZE)
21366  
21367 @@ -62,80 +64,119 @@
21368  static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
21369  static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
21370  
21371 +
21372 +
21373 +
21374 +/*********************************************************************/
21375 +/*                                                                   */
21376 +/*  Misc helper functions                                            */
21377 +/*                                                                   */
21378 +/*********************************************************************/
21379 +
21380  static inline void clear_bss_descriptor (struct bss_descriptor * bss)
21381  {
21382         /* Don't blow away ->list, just BSS data */
21383         memset(bss, 0, offsetof(struct bss_descriptor, list));
21384  }
21385  
21386 -static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
21387 +/**
21388 + *  @brief Compare two SSIDs
21389 + *
21390 + *  @param ssid1    A pointer to ssid to compare
21391 + *  @param ssid2    A pointer to ssid to compare
21392 + *
21393 + *  @return         0: ssid is same, otherwise is different
21394 + */
21395 +int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
21396 +{
21397 +       if (ssid1_len != ssid2_len)
21398 +               return -1;
21399 +
21400 +       return memcmp(ssid1, ssid2, ssid1_len);
21401 +}
21402 +
21403 +static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
21404                         struct bss_descriptor * match_bss)
21405  {
21406         if (   !secinfo->wep_enabled
21407             && !secinfo->WPAenabled
21408             && !secinfo->WPA2enabled
21409 -           && match_bss->wpa_ie[0] != WPA_IE
21410 -           && match_bss->rsn_ie[0] != WPA2_IE
21411 -           && !match_bss->privacy) {
21412 +           && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC
21413 +           && match_bss->rsn_ie[0] != MFIE_TYPE_RSN
21414 +           && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
21415                 return 1;
21416         }
21417         return 0;
21418  }
21419  
21420 -static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo,
21421 +static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
21422                         struct bss_descriptor * match_bss)
21423  {
21424         if ( secinfo->wep_enabled
21425            && !secinfo->WPAenabled
21426            && !secinfo->WPA2enabled
21427 -          && match_bss->privacy) {
21428 +          && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
21429                 return 1;
21430         }
21431         return 0;
21432  }
21433  
21434 -static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
21435 +static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
21436                         struct bss_descriptor * match_bss)
21437  {
21438         if (  !secinfo->wep_enabled
21439            && secinfo->WPAenabled
21440 -          && (match_bss->wpa_ie[0] == WPA_IE)
21441 +          && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC)
21442            /* privacy bit may NOT be set in some APs like LinkSys WRT54G
21443 -             && bss->privacy */
21444 +             && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
21445 +           */
21446            ) {
21447                 return 1;
21448         }
21449         return 0;
21450  }
21451  
21452 -static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
21453 +static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
21454                         struct bss_descriptor * match_bss)
21455  {
21456         if (  !secinfo->wep_enabled
21457            && secinfo->WPA2enabled
21458 -          && (match_bss->rsn_ie[0] == WPA2_IE)
21459 +          && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN)
21460            /* privacy bit may NOT be set in some APs like LinkSys WRT54G
21461 -             && bss->privacy */
21462 +             && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
21463 +           */
21464            ) {
21465                 return 1;
21466         }
21467         return 0;
21468  }
21469  
21470 -static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
21471 +static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
21472                         struct bss_descriptor * match_bss)
21473  {
21474         if (  !secinfo->wep_enabled
21475            && !secinfo->WPAenabled
21476            && !secinfo->WPA2enabled
21477 -          && (match_bss->wpa_ie[0] != WPA_IE)
21478 -          && (match_bss->rsn_ie[0] != WPA2_IE)
21479 -          && match_bss->privacy) {
21480 +          && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC)
21481 +          && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN)
21482 +          && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
21483                 return 1;
21484         }
21485         return 0;
21486  }
21487  
21488 +static inline int is_same_network(struct bss_descriptor *src,
21489 +                                 struct bss_descriptor *dst)
21490 +{
21491 +       /* A network is only a duplicate if the channel, BSSID, and ESSID
21492 +        * all match.  We treat all <hidden> with the same BSSID and channel
21493 +        * as one network */
21494 +       return ((src->ssid_len == dst->ssid_len) &&
21495 +               (src->channel == dst->channel) &&
21496 +               !compare_ether_addr(src->bssid, dst->bssid) &&
21497 +               !memcmp(src->ssid, dst->ssid, src->ssid_len));
21498 +}
21499 +
21500  /**
21501   *  @brief Check if a scanned network compatible with the driver settings
21502   *
21503 @@ -149,79 +190,100 @@ static inline int match_bss_dynamic_wep(
21504   *    0       0        0       0     !=NONE     1      0    0   yes Dynamic WEP
21505   *
21506   *
21507 - *  @param adapter A pointer to wlan_adapter
21508 + *  @param priv A pointer to struct lbs_private
21509   *  @param index   Index in scantable to check against current driver settings
21510   *  @param mode    Network mode: Infrastructure or IBSS
21511   *
21512   *  @return        Index in scantable, or error code if negative
21513   */
21514 -static int is_network_compatible(wlan_adapter * adapter,
21515 +static int is_network_compatible(struct lbs_private *priv,
21516                 struct bss_descriptor * bss, u8 mode)
21517  {
21518         int matched = 0;
21519  
21520 -       lbs_deb_enter(LBS_DEB_ASSOC);
21521 +       lbs_deb_enter(LBS_DEB_SCAN);
21522  
21523         if (bss->mode != mode)
21524                 goto done;
21525  
21526 -       if ((matched = match_bss_no_security(&adapter->secinfo, bss))) {
21527 +       if ((matched = match_bss_no_security(&priv->secinfo, bss))) {
21528                 goto done;
21529 -       } else if ((matched = match_bss_static_wep(&adapter->secinfo, bss))) {
21530 +       } else if ((matched = match_bss_static_wep(&priv->secinfo, bss))) {
21531                 goto done;
21532 -       } else if ((matched = match_bss_wpa(&adapter->secinfo, bss))) {
21533 +       } else if ((matched = match_bss_wpa(&priv->secinfo, bss))) {
21534                 lbs_deb_scan(
21535 -                      "is_network_compatible() WPA: wpa_ie=%#x "
21536 -                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
21537 -                      "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
21538 -                      adapter->secinfo.wep_enabled ? "e" : "d",
21539 -                      adapter->secinfo.WPAenabled ? "e" : "d",
21540 -                      adapter->secinfo.WPA2enabled ? "e" : "d",
21541 -                      bss->privacy);
21542 +                      "is_network_compatible() WPA: wpa_ie 0x%x "
21543 +                      "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
21544 +                      "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
21545 +                      priv->secinfo.wep_enabled ? "e" : "d",
21546 +                      priv->secinfo.WPAenabled ? "e" : "d",
21547 +                      priv->secinfo.WPA2enabled ? "e" : "d",
21548 +                      (bss->capability & WLAN_CAPABILITY_PRIVACY));
21549                 goto done;
21550 -       } else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) {
21551 +       } else if ((matched = match_bss_wpa2(&priv->secinfo, bss))) {
21552                 lbs_deb_scan(
21553 -                      "is_network_compatible() WPA2: wpa_ie=%#x "
21554 -                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
21555 -                      "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
21556 -                      adapter->secinfo.wep_enabled ? "e" : "d",
21557 -                      adapter->secinfo.WPAenabled ? "e" : "d",
21558 -                      adapter->secinfo.WPA2enabled ? "e" : "d",
21559 -                      bss->privacy);
21560 +                      "is_network_compatible() WPA2: wpa_ie 0x%x "
21561 +                      "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
21562 +                      "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
21563 +                      priv->secinfo.wep_enabled ? "e" : "d",
21564 +                      priv->secinfo.WPAenabled ? "e" : "d",
21565 +                      priv->secinfo.WPA2enabled ? "e" : "d",
21566 +                      (bss->capability & WLAN_CAPABILITY_PRIVACY));
21567                 goto done;
21568 -       } else if ((matched = match_bss_dynamic_wep(&adapter->secinfo, bss))) {
21569 +       } else if ((matched = match_bss_dynamic_wep(&priv->secinfo, bss))) {
21570                 lbs_deb_scan(
21571                        "is_network_compatible() dynamic WEP: "
21572 -                      "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
21573 -                      bss->wpa_ie[0],
21574 -                      bss->rsn_ie[0],
21575 -                      bss->privacy);
21576 +                      "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n",
21577 +                      bss->wpa_ie[0], bss->rsn_ie[0],
21578 +                      (bss->capability & WLAN_CAPABILITY_PRIVACY));
21579                 goto done;
21580         }
21581  
21582         /* bss security settings don't match those configured on card */
21583         lbs_deb_scan(
21584 -              "is_network_compatible() FAILED: wpa_ie=%#x "
21585 -              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
21586 +              "is_network_compatible() FAILED: wpa_ie 0x%x "
21587 +              "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n",
21588                bss->wpa_ie[0], bss->rsn_ie[0],
21589 -              adapter->secinfo.wep_enabled ? "e" : "d",
21590 -              adapter->secinfo.WPAenabled ? "e" : "d",
21591 -              adapter->secinfo.WPA2enabled ? "e" : "d",
21592 -              bss->privacy);
21593 +              priv->secinfo.wep_enabled ? "e" : "d",
21594 +              priv->secinfo.WPAenabled ? "e" : "d",
21595 +              priv->secinfo.WPA2enabled ? "e" : "d",
21596 +              (bss->capability & WLAN_CAPABILITY_PRIVACY));
21597  
21598  done:
21599 -       lbs_deb_leave(LBS_DEB_SCAN);
21600 +       lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched);
21601         return matched;
21602  }
21603  
21604 +
21605 +
21606 +
21607 +/*********************************************************************/
21608 +/*                                                                   */
21609 +/*  Main scanning support                                            */
21610 +/*                                                                   */
21611 +/*********************************************************************/
21612 +
21613 +void lbs_scan_worker(struct work_struct *work)
21614 +{
21615 +       struct lbs_private *priv =
21616 +               container_of(work, struct lbs_private, scan_work.work);
21617 +
21618 +       lbs_deb_enter(LBS_DEB_SCAN);
21619 +       lbs_scan_networks(priv, NULL, 0);
21620 +       lbs_deb_leave(LBS_DEB_SCAN);
21621 +}
21622 +
21623 +
21624  /**
21625   *  @brief Create a channel list for the driver to scan based on region info
21626   *
21627 + *  Only used from lbs_scan_setup_scan_config()
21628 + *
21629   *  Use the driver region/band information to construct a comprehensive list
21630   *    of channels to scan.  This routine is used for any scan that is not
21631   *    provided a specific channel list to scan.
21632   *
21633 - *  @param priv          A pointer to wlan_private structure
21634 + *  @param priv          A pointer to struct lbs_private structure
21635   *  @param scanchanlist  Output parameter: resulting channel list to scan
21636   *  @param filteredscan  Flag indicating whether or not a BSSID or SSID filter
21637   *                       is being sent in the command to firmware.  Used to
21638 @@ -231,12 +293,11 @@ done:
21639   *
21640   *  @return              void
21641   */
21642 -static void wlan_scan_create_channel_list(wlan_private * priv,
21643 +static int lbs_scan_create_channel_list(struct lbs_private *priv,
21644                                           struct chanscanparamset * scanchanlist,
21645                                           u8 filteredscan)
21646  {
21647  
21648 -       wlan_adapter *adapter = priv->adapter;
21649         struct region_channel *scanregion;
21650         struct chan_freq_power *cfp;
21651         int rgnidx;
21652 @@ -250,23 +311,24 @@ static void wlan_scan_create_channel_lis
21653          *   be changed to passive on a per channel basis if restricted by
21654          *   regulatory requirements (11d or 11h)
21655          */
21656 -       scantype = adapter->scantype;
21657 +       scantype = CMD_SCAN_TYPE_ACTIVE;
21658  
21659 -       for (rgnidx = 0; rgnidx < ARRAY_SIZE(adapter->region_channel); rgnidx++) {
21660 -               if (priv->adapter->enable11d &&
21661 -                   adapter->connect_status != libertas_connected) {
21662 +       for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
21663 +               if (priv->enable11d &&
21664 +                   (priv->connect_status != LBS_CONNECTED) &&
21665 +                   (priv->mesh_connect_status != LBS_CONNECTED)) {
21666                         /* Scan all the supported chan for the first scan */
21667 -                       if (!adapter->universal_channel[rgnidx].valid)
21668 +                       if (!priv->universal_channel[rgnidx].valid)
21669                                 continue;
21670 -                       scanregion = &adapter->universal_channel[rgnidx];
21671 +                       scanregion = &priv->universal_channel[rgnidx];
21672  
21673                         /* clear the parsed_region_chan for the first scan */
21674 -                       memset(&adapter->parsed_region_chan, 0x00,
21675 -                              sizeof(adapter->parsed_region_chan));
21676 +                       memset(&priv->parsed_region_chan, 0x00,
21677 +                              sizeof(priv->parsed_region_chan));
21678                 } else {
21679 -                       if (!adapter->region_channel[rgnidx].valid)
21680 +                       if (!priv->region_channel[rgnidx].valid)
21681                                 continue;
21682 -                       scanregion = &adapter->region_channel[rgnidx];
21683 +                       scanregion = &priv->region_channel[rgnidx];
21684                 }
21685  
21686                 for (nextchan = 0;
21687 @@ -274,10 +336,10 @@ static void wlan_scan_create_channel_lis
21688  
21689                         cfp = scanregion->CFP + nextchan;
21690  
21691 -                       if (priv->adapter->enable11d) {
21692 +                       if (priv->enable11d) {
21693                                 scantype =
21694 -                                   libertas_get_scan_type_11d(cfp->channel,
21695 -                                                          &adapter->
21696 +                                   lbs_get_scan_type_11d(cfp->channel,
21697 +                                                          &priv->
21698                                                            parsed_region_chan);
21699                         }
21700  
21701 @@ -286,11 +348,11 @@ static void wlan_scan_create_channel_lis
21702                         case BAND_G:
21703                         default:
21704                                 scanchanlist[chanidx].radiotype =
21705 -                                   cmd_scan_radio_type_bg;
21706 +                                   CMD_SCAN_RADIO_TYPE_BG;
21707                                 break;
21708                         }
21709  
21710 -                       if (scantype == cmd_scan_type_passive) {
21711 +                       if (scantype == CMD_SCAN_TYPE_PASSIVE) {
21712                                 scanchanlist[chanidx].maxscantime =
21713                                     cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
21714                                 scanchanlist[chanidx].chanscanmode.passivescan =
21715 @@ -310,656 +372,373 @@ static void wlan_scan_create_channel_lis
21716                         }
21717                 }
21718         }
21719 +       return chanidx;
21720  }
21721  
21722 -/**
21723 - *  @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds
21724 - *
21725 - *  Application layer or other functions can invoke wlan_scan_networks
21726 - *    with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct.
21727 - *    This structure is used as the basis of one or many wlan_scan_cmd_config
21728 - *    commands that are sent to the command processing module and sent to
21729 - *    firmware.
21730 - *
21731 - *  Create a wlan_scan_cmd_config based on the following user supplied
21732 - *    parameters (if present):
21733 - *             - SSID filter
21734 - *             - BSSID filter
21735 - *             - Number of Probes to be sent
21736 - *             - channel list
21737 - *
21738 - *  If the SSID or BSSID filter is not present, disable/clear the filter.
21739 - *  If the number of probes is not set, use the adapter default setting
21740 - *  Qualify the channel
21741 - *
21742 - *  @param priv             A pointer to wlan_private structure
21743 - *  @param puserscanin      NULL or pointer to scan configuration parameters
21744 - *  @param ppchantlvout     Output parameter: Pointer to the start of the
21745 - *                          channel TLV portion of the output scan config
21746 - *  @param pscanchanlist    Output parameter: Pointer to the resulting channel
21747 - *                          list to scan
21748 - *  @param pmaxchanperscan  Output parameter: Number of channels to scan for
21749 - *                          each issuance of the firmware scan command
21750 - *  @param pfilteredscan    Output parameter: Flag indicating whether or not
21751 - *                          a BSSID or SSID filter is being sent in the
21752 - *                          command to firmware.  Used to increase the number
21753 - *                          of channels sent in a scan command and to
21754 - *                          disable the firmware channel scan filter.
21755 - *  @param pscancurrentonly Output parameter: Flag indicating whether or not
21756 - *                          we are only scanning our current active channel
21757 +
21758 +/*
21759 + * Add SSID TLV of the form:
21760   *
21761 - *  @return                 resulting scan configuration
21762 + * TLV-ID SSID     00 00
21763 + * length          06 00
21764 + * ssid            4d 4e 54 45 53 54
21765   */
21766 -static struct wlan_scan_cmd_config *
21767 -wlan_scan_setup_scan_config(wlan_private * priv,
21768 -                           const struct wlan_ioctl_user_scan_cfg * puserscanin,
21769 -                           struct mrvlietypes_chanlistparamset ** ppchantlvout,
21770 -                           struct chanscanparamset * pscanchanlist,
21771 -                           int *pmaxchanperscan,
21772 -                           u8 * pfilteredscan,
21773 -                           u8 * pscancurrentonly)
21774 -{
21775 -       wlan_adapter *adapter = priv->adapter;
21776 -       struct mrvlietypes_numprobes *pnumprobestlv;
21777 -       struct mrvlietypes_ssidparamset *pssidtlv;
21778 -       struct wlan_scan_cmd_config * pscancfgout = NULL;
21779 -       u8 *ptlvpos;
21780 -       u16 numprobes;
21781 -       int chanidx;
21782 -       int scantype;
21783 -       int scandur;
21784 -       int channel;
21785 -       int radiotype;
21786 -
21787 -       pscancfgout = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
21788 -       if (pscancfgout == NULL)
21789 -               goto out;
21790 -
21791 -       /* The tlvbufferlen is calculated for each scan command.  The TLVs added
21792 -        *   in this routine will be preserved since the routine that sends
21793 -        *   the command will append channelTLVs at *ppchantlvout.  The difference
21794 -        *   between the *ppchantlvout and the tlvbuffer start will be used
21795 -        *   to calculate the size of anything we add in this routine.
21796 -        */
21797 -       pscancfgout->tlvbufferlen = 0;
21798 -
21799 -       /* Running tlv pointer.  Assigned to ppchantlvout at end of function
21800 -        *  so later routines know where channels can be added to the command buf
21801 -        */
21802 -       ptlvpos = pscancfgout->tlvbuffer;
21803 -
21804 -       /*
21805 -        * Set the initial scan paramters for progressive scanning.  If a specific
21806 -        *   BSSID or SSID is used, the number of channels in the scan command
21807 -        *   will be increased to the absolute maximum
21808 -        */
21809 -       *pmaxchanperscan = MRVDRV_CHANNELS_PER_SCAN_CMD;
21810 -
21811 -       /* Initialize the scan as un-filtered by firmware, set to TRUE below if
21812 -        *   a SSID or BSSID filter is sent in the command
21813 -        */
21814 -       *pfilteredscan = 0;
21815 -
21816 -       /* Initialize the scan as not being only on the current channel.  If
21817 -        *   the channel list is customized, only contains one channel, and
21818 -        *   is the active channel, this is set true and data flow is not halted.
21819 -        */
21820 -       *pscancurrentonly = 0;
21821 -
21822 -       if (puserscanin) {
21823 -
21824 -               /* Set the bss type scan filter, use adapter setting if unset */
21825 -               pscancfgout->bsstype =
21826 -                   (puserscanin->bsstype ? puserscanin->bsstype : adapter->
21827 -                    scanmode);
21828 -
21829 -               /* Set the number of probes to send, use adapter setting if unset */
21830 -               numprobes = (puserscanin->numprobes ? puserscanin->numprobes :
21831 -                            adapter->scanprobes);
21832 -
21833 -               /*
21834 -                * Set the BSSID filter to the incoming configuration,
21835 -                *   if non-zero.  If not set, it will remain disabled (all zeros).
21836 -                */
21837 -               memcpy(pscancfgout->bssid, puserscanin->bssid,
21838 -                      sizeof(pscancfgout->bssid));
21839 -
21840 -               if (puserscanin->ssid_len) {
21841 -                       pssidtlv =
21842 -                           (struct mrvlietypes_ssidparamset *) pscancfgout->
21843 -                           tlvbuffer;
21844 -                       pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
21845 -                       pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len);
21846 -                       memcpy(pssidtlv->ssid, puserscanin->ssid,
21847 -                              puserscanin->ssid_len);
21848 -                       ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len;
21849 -               }
21850 -
21851 -               /*
21852 -                *  The default number of channels sent in the command is low to
21853 -                *    ensure the response buffer from the firmware does not truncate
21854 -                *    scan results.  That is not an issue with an SSID or BSSID
21855 -                *    filter applied to the scan results in the firmware.
21856 -                */
21857 -               if (   puserscanin->ssid_len
21858 -                   || (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) {
21859 -                       *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
21860 -                       *pfilteredscan = 1;
21861 -               }
21862 -       } else {
21863 -               pscancfgout->bsstype = adapter->scanmode;
21864 -               numprobes = adapter->scanprobes;
21865 -       }
21866 -
21867 -       /* If the input config or adapter has the number of Probes set, add tlv */
21868 -       if (numprobes) {
21869 -               pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
21870 -               pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
21871 -               pnumprobestlv->header.len = cpu_to_le16(2);
21872 -               pnumprobestlv->numprobes = cpu_to_le16(numprobes);
21873 -
21874 -               ptlvpos += sizeof(*pnumprobestlv);
21875 -       }
21876 -
21877 -       /*
21878 -        * Set the output for the channel TLV to the address in the tlv buffer
21879 -        *   past any TLVs that were added in this fuction (SSID, numprobes).
21880 -        *   channel TLVs will be added past this for each scan command, preserving
21881 -        *   the TLVs that were previously added.
21882 -        */
21883 -       *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos;
21884 -
21885 -       if (puserscanin && puserscanin->chanlist[0].channumber) {
21886 -
21887 -               lbs_deb_scan("Scan: Using supplied channel list\n");
21888 -
21889 -               for (chanidx = 0;
21890 -                    chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX
21891 -                    && puserscanin->chanlist[chanidx].channumber; chanidx++) {
21892 -
21893 -                       channel = puserscanin->chanlist[chanidx].channumber;
21894 -                       (pscanchanlist + chanidx)->channumber = channel;
21895 -
21896 -                       radiotype = puserscanin->chanlist[chanidx].radiotype;
21897 -                       (pscanchanlist + chanidx)->radiotype = radiotype;
21898 -
21899 -                       scantype = puserscanin->chanlist[chanidx].scantype;
21900 -
21901 -                       if (scantype == cmd_scan_type_passive) {
21902 -                               (pscanchanlist +
21903 -                                chanidx)->chanscanmode.passivescan = 1;
21904 -                       } else {
21905 -                               (pscanchanlist +
21906 -                                chanidx)->chanscanmode.passivescan = 0;
21907 -                       }
21908 -
21909 -                       if (puserscanin->chanlist[chanidx].scantime) {
21910 -                               scandur =
21911 -                                   puserscanin->chanlist[chanidx].scantime;
21912 -                       } else {
21913 -                               if (scantype == cmd_scan_type_passive) {
21914 -                                       scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
21915 -                               } else {
21916 -                                       scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
21917 -                               }
21918 -                       }
21919 -
21920 -                       (pscanchanlist + chanidx)->minscantime =
21921 -                           cpu_to_le16(scandur);
21922 -                       (pscanchanlist + chanidx)->maxscantime =
21923 -                           cpu_to_le16(scandur);
21924 -               }
21925 +static int lbs_scan_add_ssid_tlv(u8 *tlv,
21926 +       const struct lbs_ioctl_user_scan_cfg *user_cfg)
21927 +{
21928 +       struct mrvlietypes_ssidparamset *ssid_tlv =
21929 +               (struct mrvlietypes_ssidparamset *)tlv;
21930 +       ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
21931 +       ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len);
21932 +       memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len);
21933 +       return sizeof(ssid_tlv->header) + user_cfg->ssid_len;
21934 +}
21935  
21936 -               /* Check if we are only scanning the current channel */
21937 -               if ((chanidx == 1) && (puserscanin->chanlist[0].channumber
21938 -                                      ==
21939 -                                      priv->adapter->curbssparams.channel)) {
21940 -                       *pscancurrentonly = 1;
21941 -                       lbs_deb_scan("Scan: Scanning current channel only");
21942 -               }
21943  
21944 -       } else {
21945 -               lbs_deb_scan("Scan: Creating full region channel list\n");
21946 -               wlan_scan_create_channel_list(priv, pscanchanlist,
21947 -                                             *pfilteredscan);
21948 -       }
21949 +/*
21950 + * Add CHANLIST TLV of the form
21951 + *
21952 + * TLV-ID CHANLIST 01 01
21953 + * length          5b 00
21954 + * channel 1       00 01 00 00 00 64 00
21955 + *   radio type    00
21956 + *   channel          01
21957 + *   scan type           00
21958 + *   min scan time          00 00
21959 + *   max scan time                64 00
21960 + * channel 2       00 02 00 00 00 64 00
21961 + * channel 3       00 03 00 00 00 64 00
21962 + * channel 4       00 04 00 00 00 64 00
21963 + * channel 5       00 05 00 00 00 64 00
21964 + * channel 6       00 06 00 00 00 64 00
21965 + * channel 7       00 07 00 00 00 64 00
21966 + * channel 8       00 08 00 00 00 64 00
21967 + * channel 9       00 09 00 00 00 64 00
21968 + * channel 10      00 0a 00 00 00 64 00
21969 + * channel 11      00 0b 00 00 00 64 00
21970 + * channel 12      00 0c 00 00 00 64 00
21971 + * channel 13      00 0d 00 00 00 64 00
21972 + *
21973 + */
21974 +static int lbs_scan_add_chanlist_tlv(u8 *tlv,
21975 +       struct chanscanparamset *chan_list,
21976 +       int chan_count)
21977 +{
21978 +       size_t size = sizeof(struct chanscanparamset) * chan_count;
21979 +       struct mrvlietypes_chanlistparamset *chan_tlv =
21980 +               (struct mrvlietypes_chanlistparamset *) tlv;
21981  
21982 -out:
21983 -       return pscancfgout;
21984 +       chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
21985 +       memcpy(chan_tlv->chanscanparam, chan_list, size);
21986 +       chan_tlv->header.len = cpu_to_le16(size);
21987 +       return sizeof(chan_tlv->header) + size;
21988  }
21989  
21990 -/**
21991 - *  @brief Construct and send multiple scan config commands to the firmware
21992 +
21993 +/*
21994 + * Add RATES TLV of the form
21995   *
21996 - *  Previous routines have created a wlan_scan_cmd_config with any requested
21997 - *   TLVs.  This function splits the channel TLV into maxchanperscan lists
21998 - *   and sends the portion of the channel TLV along with the other TLVs
21999 - *   to the wlan_cmd routines for execution in the firmware.
22000 - *
22001 - *  @param priv            A pointer to wlan_private structure
22002 - *  @param maxchanperscan  Maximum number channels to be included in each
22003 - *                         scan command sent to firmware
22004 - *  @param filteredscan    Flag indicating whether or not a BSSID or SSID
22005 - *                         filter is being used for the firmware command
22006 - *                         scan command sent to firmware
22007 - *  @param pscancfgout     Scan configuration used for this scan.
22008 - *  @param pchantlvout     Pointer in the pscancfgout where the channel TLV
22009 - *                         should start.  This is past any other TLVs that
22010 - *                         must be sent down in each firmware command.
22011 - *  @param pscanchanlist   List of channels to scan in maxchanperscan segments
22012 + * TLV-ID RATES    01 00
22013 + * length          0e 00
22014 + * rates           82 84 8b 96 0c 12 18 24 30 48 60 6c
22015   *
22016 - *  @return                0 or error return otherwise
22017 + * The rates are in lbs_bg_rates[], but for the 802.11b
22018 + * rates the high bit isn't set.
22019   */
22020 -static int wlan_scan_channel_list(wlan_private * priv,
22021 -                                 int maxchanperscan,
22022 -                                 u8 filteredscan,
22023 -                                 struct wlan_scan_cmd_config * pscancfgout,
22024 -                                 struct mrvlietypes_chanlistparamset * pchantlvout,
22025 -                                 struct chanscanparamset * pscanchanlist,
22026 -                                 const struct wlan_ioctl_user_scan_cfg * puserscanin,
22027 -                                 int full_scan)
22028 -{
22029 -       struct chanscanparamset *ptmpchan;
22030 -       struct chanscanparamset *pstartchan;
22031 -       u8 scanband;
22032 -       int doneearly;
22033 -       int tlvidx;
22034 -       int ret = 0;
22035 -       int scanned = 0;
22036 -       union iwreq_data wrqu;
22037 -
22038 -       lbs_deb_enter(LBS_DEB_ASSOC);
22039 -
22040 -       if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) {
22041 -               lbs_deb_scan("Scan: Null detect: %p, %p, %p\n",
22042 -                      pscancfgout, pchantlvout, pscanchanlist);
22043 -               return -1;
22044 -       }
22045 -
22046 -       pchantlvout->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
22047 -
22048 -       /* Set the temp channel struct pointer to the start of the desired list */
22049 -       ptmpchan = pscanchanlist;
22050 -
22051 -       if (priv->adapter->last_scanned_channel && !puserscanin)
22052 -               ptmpchan += priv->adapter->last_scanned_channel;
22053 -
22054 -       /* Loop through the desired channel list, sending a new firmware scan
22055 -        *   commands for each maxchanperscan channels (or for 1,6,11 individually
22056 -        *   if configured accordingly)
22057 -        */
22058 -       while (ptmpchan->channumber) {
22059 -
22060 -               tlvidx = 0;
22061 -               pchantlvout->header.len = 0;
22062 -               scanband = ptmpchan->radiotype;
22063 -               pstartchan = ptmpchan;
22064 -               doneearly = 0;
22065 -
22066 -               /* Construct the channel TLV for the scan command.  Continue to
22067 -                *  insert channel TLVs until:
22068 -                *    - the tlvidx hits the maximum configured per scan command
22069 -                *    - the next channel to insert is 0 (end of desired channel list)
22070 -                *    - doneearly is set (controlling individual scanning of 1,6,11)
22071 -                */
22072 -               while (tlvidx < maxchanperscan && ptmpchan->channumber
22073 -                      && !doneearly && scanned < 2) {
22074 -
22075 -            lbs_deb_scan(
22076 -                    "Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n",
22077 -                ptmpchan->channumber, ptmpchan->radiotype,
22078 -                ptmpchan->chanscanmode.passivescan,
22079 -                ptmpchan->chanscanmode.disablechanfilt,
22080 -                ptmpchan->maxscantime);
22081 -
22082 -                       /* Copy the current channel TLV to the command being prepared */
22083 -                       memcpy(pchantlvout->chanscanparam + tlvidx,
22084 -                              ptmpchan, sizeof(pchantlvout->chanscanparam));
22085 -
22086 -                       /* Increment the TLV header length by the size appended */
22087 -                       /* Ew, it would be _so_ nice if we could just declare the
22088 -                          variable little-endian and let GCC handle it for us */
22089 -                       pchantlvout->header.len =
22090 -                               cpu_to_le16(le16_to_cpu(pchantlvout->header.len) +
22091 -                                           sizeof(pchantlvout->chanscanparam));
22092 -
22093 -                       /*
22094 -                        *  The tlv buffer length is set to the number of bytes of the
22095 -                        *    between the channel tlv pointer and the start of the
22096 -                        *    tlv buffer.  This compensates for any TLVs that were appended
22097 -                        *    before the channel list.
22098 -                        */
22099 -                       pscancfgout->tlvbufferlen = ((u8 *) pchantlvout
22100 -                                                    - pscancfgout->tlvbuffer);
22101 -
22102 -                       /*  Add the size of the channel tlv header and the data length */
22103 -                       pscancfgout->tlvbufferlen +=
22104 -                           (sizeof(pchantlvout->header)
22105 -                            + le16_to_cpu(pchantlvout->header.len));
22106 -
22107 -                       /* Increment the index to the channel tlv we are constructing */
22108 -                       tlvidx++;
22109 -
22110 -                       doneearly = 0;
22111 -
22112 -                       /* Stop the loop if the *current* channel is in the 1,6,11 set
22113 -                        *   and we are not filtering on a BSSID or SSID.
22114 -                        */
22115 -                       if (!filteredscan && (ptmpchan->channumber == 1
22116 -                                             || ptmpchan->channumber == 6
22117 -                                             || ptmpchan->channumber == 11)) {
22118 -                               doneearly = 1;
22119 -                       }
22120 -
22121 -                       /* Increment the tmp pointer to the next channel to be scanned */
22122 -                       ptmpchan++;
22123 -                       scanned++;
22124 -
22125 -                       /* Stop the loop if the *next* channel is in the 1,6,11 set.
22126 -                        *  This will cause it to be the only channel scanned on the next
22127 -                        *  interation
22128 -                        */
22129 -                       if (!filteredscan && (ptmpchan->channumber == 1
22130 -                                             || ptmpchan->channumber == 6
22131 -                                             || ptmpchan->channumber == 11)) {
22132 -                               doneearly = 1;
22133 -                       }
22134 -               }
22135 -
22136 -               /* Send the scan command to the firmware with the specified cfg */
22137 -               ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0,
22138 -                                           0, 0, pscancfgout);
22139 -               if (scanned >= 2 && !full_scan) {
22140 -                       ret = 0;
22141 -                       goto done;
22142 -               }
22143 -               scanned = 0;
22144 -       }
22145 +static int lbs_scan_add_rates_tlv(u8 *tlv)
22146 +{
22147 +       int i;
22148 +       struct mrvlietypes_ratesparamset *rate_tlv =
22149 +               (struct mrvlietypes_ratesparamset *) tlv;
22150 +
22151 +       rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
22152 +       tlv += sizeof(rate_tlv->header);
22153 +       for (i = 0; i < MAX_RATES; i++) {
22154 +               *tlv = lbs_bg_rates[i];
22155 +               if (*tlv == 0)
22156 +                       break;
22157 +               /* This code makes sure that the 802.11b rates (1 MBit/s, 2
22158 +                  MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set.
22159 +                  Note that the values are MBit/s * 2, to mark them as
22160 +                  basic rates so that the firmware likes it better */
22161 +               if (*tlv == 0x02 || *tlv == 0x04 ||
22162 +                   *tlv == 0x0b || *tlv == 0x16)
22163 +                       *tlv |= 0x80;
22164 +               tlv++;
22165 +       }
22166 +       rate_tlv->header.len = cpu_to_le16(i);
22167 +       return sizeof(rate_tlv->header) + i;
22168 +}
22169  
22170 -done:
22171 -       priv->adapter->last_scanned_channel = ptmpchan->channumber;
22172  
22173 -       /* Tell userspace the scan table has been updated */
22174 -       memset(&wrqu, 0, sizeof(union iwreq_data));
22175 -       wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
22176 +/*
22177 + * Generate the CMD_802_11_SCAN command with the proper tlv
22178 + * for a bunch of channels.
22179 + */
22180 +static int lbs_do_scan(struct lbs_private *priv,
22181 +       u8 bsstype,
22182 +       struct chanscanparamset *chan_list,
22183 +       int chan_count,
22184 +       const struct lbs_ioctl_user_scan_cfg *user_cfg)
22185 +{
22186 +       int ret = -ENOMEM;
22187 +       struct lbs_scan_cmd_config *scan_cmd;
22188 +       u8 *tlv;    /* pointer into our current, growing TLV storage area */
22189 +
22190 +       lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, "
22191 +               "chan_count %d",
22192 +               bsstype, chan_list[0].channumber, chan_count);
22193 +
22194 +       /* create the fixed part for scan command */
22195 +       scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
22196 +       if (scan_cmd == NULL)
22197 +               goto out;
22198 +       tlv = scan_cmd->tlvbuffer;
22199 +       if (user_cfg)
22200 +               memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN);
22201 +       scan_cmd->bsstype = bsstype;
22202 +
22203 +       /* add TLVs */
22204 +       if (user_cfg && user_cfg->ssid_len)
22205 +               tlv += lbs_scan_add_ssid_tlv(tlv, user_cfg);
22206 +       if (chan_list && chan_count)
22207 +               tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count);
22208 +       tlv += lbs_scan_add_rates_tlv(tlv);
22209 +
22210 +       /* This is the final data we are about to send */
22211 +       scan_cmd->tlvbufferlen = tlv - scan_cmd->tlvbuffer;
22212 +       lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 1+6);
22213 +       lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
22214 +               scan_cmd->tlvbufferlen);
22215  
22216 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0,
22217 +               CMD_OPTION_WAITFORRSP, 0, scan_cmd);
22218 +out:
22219 +       kfree(scan_cmd);
22220         lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
22221         return ret;
22222  }
22223  
22224 -static void
22225 -clear_selected_scan_list_entries(wlan_adapter * adapter,
22226 -                                 const struct wlan_ioctl_user_scan_cfg * scan_cfg)
22227 -{
22228 -       struct bss_descriptor * bss;
22229 -       struct bss_descriptor * safe;
22230 -       u32 clear_ssid_flag = 0, clear_bssid_flag = 0;
22231 -
22232 -       if (!scan_cfg)
22233 -               return;
22234 -
22235 -       if (scan_cfg->clear_ssid && scan_cfg->ssid_len)
22236 -               clear_ssid_flag = 1;
22237 -
22238 -       if (scan_cfg->clear_bssid
22239 -           && (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0)
22240 -           && (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) {
22241 -               clear_bssid_flag = 1;
22242 -       }
22243 -
22244 -       if (!clear_ssid_flag && !clear_bssid_flag)
22245 -               return;
22246 -
22247 -       mutex_lock(&adapter->lock);
22248 -       list_for_each_entry_safe (bss, safe, &adapter->network_list, list) {
22249 -               u32 clear = 0;
22250 -
22251 -               /* Check for an SSID match */
22252 -               if (   clear_ssid_flag
22253 -                   && (bss->ssid_len == scan_cfg->ssid_len)
22254 -                   && !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len))
22255 -                       clear = 1;
22256 -
22257 -               /* Check for a BSSID match */
22258 -               if (   clear_bssid_flag
22259 -                   && !compare_ether_addr(bss->bssid, scan_cfg->bssid))
22260 -                       clear = 1;
22261 -
22262 -               if (clear) {
22263 -                       list_move_tail (&bss->list, &adapter->network_free_list);
22264 -                       clear_bss_descriptor(bss);
22265 -               }
22266 -       }
22267 -       mutex_unlock(&adapter->lock);
22268 -}
22269 -
22270  
22271  /**
22272   *  @brief Internal function used to start a scan based on an input config
22273   *
22274 + *  Also used from debugfs
22275 + *
22276   *  Use the input user scan configuration information when provided in
22277   *    order to send the appropriate scan commands to firmware to populate or
22278   *    update the internal driver scan table
22279   *
22280 - *  @param priv          A pointer to wlan_private structure
22281 + *  @param priv          A pointer to struct lbs_private structure
22282   *  @param puserscanin   Pointer to the input configuration for the requested
22283   *                       scan.
22284   *
22285   *  @return              0 or < 0 if error
22286   */
22287 -int wlan_scan_networks(wlan_private * priv,
22288 -                             const struct wlan_ioctl_user_scan_cfg * puserscanin,
22289 -                             int full_scan)
22290 -{
22291 -       wlan_adapter * adapter = priv->adapter;
22292 -       struct mrvlietypes_chanlistparamset *pchantlvout;
22293 -       struct chanscanparamset * scan_chan_list = NULL;
22294 -       struct wlan_scan_cmd_config * scan_cfg = NULL;
22295 -       u8 filteredscan;
22296 -       u8 scancurrentchanonly;
22297 -       int maxchanperscan;
22298 -       int ret;
22299 +int lbs_scan_networks(struct lbs_private *priv,
22300 +       const struct lbs_ioctl_user_scan_cfg *user_cfg,
22301 +                       int full_scan)
22302 +{
22303 +       int ret = -ENOMEM;
22304 +       struct chanscanparamset *chan_list;
22305 +       struct chanscanparamset *curr_chans;
22306 +       int chan_count;
22307 +       u8 bsstype = CMD_BSS_TYPE_ANY;
22308 +       int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD;
22309 +       int filteredscan = 0;
22310 +       union iwreq_data wrqu;
22311  #ifdef CONFIG_LIBERTAS_DEBUG
22312 -       struct bss_descriptor * iter_bss;
22313 +       struct bss_descriptor *iter;
22314         int i = 0;
22315 +       DECLARE_MAC_BUF(mac);
22316  #endif
22317  
22318 -       lbs_deb_enter(LBS_DEB_ASSOC);
22319 +       lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d",
22320 +               full_scan);
22321  
22322 -       scan_chan_list = kzalloc(sizeof(struct chanscanparamset) *
22323 -                               WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
22324 -       if (scan_chan_list == NULL) {
22325 -               ret = -ENOMEM;
22326 -               goto out;
22327 -       }
22328 +       /* Cancel any partial outstanding partial scans if this scan
22329 +        * is a full scan.
22330 +        */
22331 +       if (full_scan && delayed_work_pending(&priv->scan_work))
22332 +               cancel_delayed_work(&priv->scan_work);
22333  
22334 -       scan_cfg = wlan_scan_setup_scan_config(priv,
22335 -                                              puserscanin,
22336 -                                              &pchantlvout,
22337 -                                              scan_chan_list,
22338 -                                              &maxchanperscan,
22339 -                                              &filteredscan,
22340 -                                              &scancurrentchanonly);
22341 -       if (scan_cfg == NULL) {
22342 -               ret = -ENOMEM;
22343 +       /* Determine same scan parameters */
22344 +       if (user_cfg) {
22345 +               if (user_cfg->bsstype)
22346 +                       bsstype = user_cfg->bsstype;
22347 +               if (compare_ether_addr(user_cfg->bssid, &zeromac[0]) != 0) {
22348 +                       numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN;
22349 +                       filteredscan = 1;
22350 +               }
22351 +       }
22352 +       lbs_deb_scan("numchannels %d, bsstype %d, "
22353 +               "filteredscan %d\n",
22354 +               numchannels, bsstype, filteredscan);
22355 +
22356 +       /* Create list of channels to scan */
22357 +       chan_list = kzalloc(sizeof(struct chanscanparamset) *
22358 +                               LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
22359 +       if (!chan_list) {
22360 +               lbs_pr_alert("SCAN: chan_list empty\n");
22361                 goto out;
22362         }
22363  
22364 -       clear_selected_scan_list_entries(adapter, puserscanin);
22365 -
22366 -       /* Keep the data path active if we are only scanning our current channel */
22367 -       if (!scancurrentchanonly) {
22368 -               netif_stop_queue(priv->dev);
22369 -               netif_carrier_off(priv->dev);
22370 +       /* We want to scan all channels */
22371 +       chan_count = lbs_scan_create_channel_list(priv, chan_list,
22372 +               filteredscan);
22373 +
22374 +       netif_stop_queue(priv->dev);
22375 +       netif_carrier_off(priv->dev);
22376 +       if (priv->mesh_dev) {
22377                 netif_stop_queue(priv->mesh_dev);
22378                 netif_carrier_off(priv->mesh_dev);
22379         }
22380  
22381 -       ret = wlan_scan_channel_list(priv,
22382 -                                    maxchanperscan,
22383 -                                    filteredscan,
22384 -                                    scan_cfg,
22385 -                                    pchantlvout,
22386 -                                    scan_chan_list,
22387 -                                    puserscanin,
22388 -                                    full_scan);
22389 +       /* Prepare to continue an interrupted scan */
22390 +       lbs_deb_scan("chan_count %d, last_scanned_channel %d\n",
22391 +                    chan_count, priv->last_scanned_channel);
22392 +       curr_chans = chan_list;
22393 +       /* advance channel list by already-scanned-channels */
22394 +       if (priv->last_scanned_channel > 0) {
22395 +               curr_chans += priv->last_scanned_channel;
22396 +               chan_count -= priv->last_scanned_channel;
22397 +       }
22398 +
22399 +       /* Send scan command(s)
22400 +        * numchannels contains the number of channels we should maximally scan
22401 +        * chan_count is the total number of channels to scan
22402 +        */
22403 +
22404 +       while (chan_count) {
22405 +               int to_scan = min(numchannels, chan_count);
22406 +               lbs_deb_scan("scanning %d of %d channels\n",
22407 +                       to_scan, chan_count);
22408 +               ret = lbs_do_scan(priv, bsstype, curr_chans,
22409 +                       to_scan, user_cfg);
22410 +               if (ret) {
22411 +                       lbs_pr_err("SCAN_CMD failed\n");
22412 +                       goto out2;
22413 +               }
22414 +               curr_chans += to_scan;
22415 +               chan_count -= to_scan;
22416 +
22417 +               /* somehow schedule the next part of the scan */
22418 +               if (chan_count &&
22419 +                   !full_scan &&
22420 +                   !priv->surpriseremoved) {
22421 +                       /* -1 marks just that we're currently scanning */
22422 +                       if (priv->last_scanned_channel < 0)
22423 +                               priv->last_scanned_channel = to_scan;
22424 +                       else
22425 +                               priv->last_scanned_channel += to_scan;
22426 +                       cancel_delayed_work(&priv->scan_work);
22427 +                       queue_delayed_work(priv->work_thread, &priv->scan_work,
22428 +                               msecs_to_jiffies(300));
22429 +                       /* skip over GIWSCAN event */
22430 +                       goto out;
22431 +               }
22432 +
22433 +       }
22434 +       memset(&wrqu, 0, sizeof(union iwreq_data));
22435 +       wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
22436  
22437  #ifdef CONFIG_LIBERTAS_DEBUG
22438         /* Dump the scan table */
22439 -       mutex_lock(&adapter->lock);
22440 -       list_for_each_entry (iter_bss, &adapter->network_list, list) {
22441 -               lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
22442 -                      i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi,
22443 -                      escape_essid(iter_bss->ssid, iter_bss->ssid_len));
22444 -       }
22445 -       mutex_unlock(&adapter->lock);
22446 +       mutex_lock(&priv->lock);
22447 +       lbs_deb_scan("scan table:\n");
22448 +       list_for_each_entry(iter, &priv->network_list, list)
22449 +               lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n",
22450 +                      i++, print_mac(mac, iter->bssid), (s32) iter->rssi,
22451 +                      escape_essid(iter->ssid, iter->ssid_len));
22452 +       mutex_unlock(&priv->lock);
22453  #endif
22454  
22455 -       if (priv->adapter->connect_status == libertas_connected) {
22456 +out2:
22457 +       priv->last_scanned_channel = 0;
22458 +
22459 +out:
22460 +       if (priv->connect_status == LBS_CONNECTED) {
22461                 netif_carrier_on(priv->dev);
22462 -               netif_wake_queue(priv->dev);
22463 +               if (!priv->tx_pending_len)
22464 +                       netif_wake_queue(priv->dev);
22465 +       }
22466 +       if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
22467                 netif_carrier_on(priv->mesh_dev);
22468 -               netif_wake_queue(priv->mesh_dev);
22469 +               if (!priv->tx_pending_len)
22470 +                       netif_wake_queue(priv->mesh_dev);
22471         }
22472 -
22473 -out:
22474 -       if (scan_cfg)
22475 -               kfree(scan_cfg);
22476 -
22477 -       if (scan_chan_list)
22478 -               kfree(scan_chan_list);
22479 +       kfree(chan_list);
22480  
22481         lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
22482         return ret;
22483  }
22484  
22485 -/**
22486 - *  @brief Inspect the scan response buffer for pointers to expected TLVs
22487 - *
22488 - *  TLVs can be included at the end of the scan response BSS information.
22489 - *    Parse the data in the buffer for pointers to TLVs that can potentially
22490 - *    be passed back in the response
22491 - *
22492 - *  @param ptlv        Pointer to the start of the TLV buffer to parse
22493 - *  @param tlvbufsize  size of the TLV buffer
22494 - *  @param ptsftlv     Output parameter: Pointer to the TSF TLV if found
22495 - *
22496 - *  @return            void
22497 - */
22498 -static
22499 -void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
22500 -                                      int tlvbufsize,
22501 -                                      struct mrvlietypes_tsftimestamp ** ptsftlv)
22502 -{
22503 -       struct mrvlietypes_data *pcurrenttlv;
22504 -       int tlvbufleft;
22505 -       u16 tlvtype;
22506 -       u16 tlvlen;
22507 -
22508 -       pcurrenttlv = ptlv;
22509 -       tlvbufleft = tlvbufsize;
22510 -       *ptsftlv = NULL;
22511 -
22512 -       lbs_deb_scan("SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
22513 -       lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize);
22514 -
22515 -       while (tlvbufleft >= sizeof(struct mrvlietypesheader)) {
22516 -               tlvtype = le16_to_cpu(pcurrenttlv->header.type);
22517 -               tlvlen = le16_to_cpu(pcurrenttlv->header.len);
22518 -
22519 -               switch (tlvtype) {
22520 -               case TLV_TYPE_TSFTIMESTAMP:
22521 -                       *ptsftlv = (struct mrvlietypes_tsftimestamp *) pcurrenttlv;
22522 -                       break;
22523  
22524 -               default:
22525 -                       lbs_deb_scan("SCAN_RESP: Unhandled TLV = %d\n",
22526 -                              tlvtype);
22527 -                       /* Give up, this seems corrupted */
22528 -                       return;
22529 -               }               /* switch */
22530 -
22531 -               tlvbufleft -= (sizeof(ptlv->header) + tlvlen);
22532 -               pcurrenttlv =
22533 -                   (struct mrvlietypes_data *) (pcurrenttlv->Data + tlvlen);
22534 -       }                       /* while */
22535 -}
22536 +
22537 +
22538 +/*********************************************************************/
22539 +/*                                                                   */
22540 +/*  Result interpretation                                            */
22541 +/*                                                                   */
22542 +/*********************************************************************/
22543  
22544  /**
22545   *  @brief Interpret a BSS scan response returned from the firmware
22546   *
22547   *  Parse the various fixed fields and IEs passed back for a a BSS probe
22548 - *   response or beacon from the scan command.  Record information as needed
22549 - *   in the scan table struct bss_descriptor for that entry.
22550 + *  response or beacon from the scan command.  Record information as needed
22551 + *  in the scan table struct bss_descriptor for that entry.
22552   *
22553   *  @param bss  Output parameter: Pointer to the BSS Entry
22554   *
22555   *  @return             0 or -1
22556   */
22557 -static int libertas_process_bss(struct bss_descriptor * bss,
22558 +static int lbs_process_bss(struct bss_descriptor *bss,
22559                                 u8 ** pbeaconinfo, int *bytesleft)
22560  {
22561 -       enum ieeetypes_elementid elemID;
22562         struct ieeetypes_fhparamset *pFH;
22563         struct ieeetypes_dsparamset *pDS;
22564         struct ieeetypes_cfparamset *pCF;
22565         struct ieeetypes_ibssparamset *pibss;
22566 -       struct ieeetypes_capinfo *pcap;
22567 -       struct WLAN_802_11_FIXED_IEs fixedie;
22568 -       u8 *pcurrentptr;
22569 -       u8 *pRate;
22570 -       u8 elemlen;
22571 -       u8 bytestocopy;
22572 -       u8 ratesize;
22573 -       u16 beaconsize;
22574 -       u8 founddatarateie;
22575 -       int bytesleftforcurrentbeacon;
22576 -       int ret;
22577 -
22578 -       struct IE_WPA *pIe;
22579 -       const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
22580 -
22581 +       DECLARE_MAC_BUF(mac);
22582         struct ieeetypes_countryinfoset *pcountryinfo;
22583 +       u8 *pos, *end, *p;
22584 +       u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
22585 +       u16 beaconsize = 0;
22586 +       int ret;
22587  
22588 -       lbs_deb_enter(LBS_DEB_ASSOC);
22589 -
22590 -       founddatarateie = 0;
22591 -       ratesize = 0;
22592 -       beaconsize = 0;
22593 +       lbs_deb_enter(LBS_DEB_SCAN);
22594  
22595         if (*bytesleft >= sizeof(beaconsize)) {
22596                 /* Extract & convert beacon size from the command buffer */
22597 -               beaconsize = le16_to_cpup((void *)*pbeaconinfo);
22598 +               beaconsize = le16_to_cpu(get_unaligned((__le16 *)*pbeaconinfo));
22599                 *bytesleft -= sizeof(beaconsize);
22600                 *pbeaconinfo += sizeof(beaconsize);
22601         }
22602  
22603         if (beaconsize == 0 || beaconsize > *bytesleft) {
22604 -
22605                 *pbeaconinfo += *bytesleft;
22606                 *bytesleft = 0;
22607 -
22608 -               return -1;
22609 +               ret = -1;
22610 +               goto done;
22611         }
22612  
22613         /* Initialize the current working beacon pointer for this BSS iteration */
22614 -       pcurrentptr = *pbeaconinfo;
22615 +       pos = *pbeaconinfo;
22616 +       end = pos + beaconsize;
22617  
22618         /* Advance the return beacon pointer past the current beacon */
22619         *pbeaconinfo += beaconsize;
22620         *bytesleft -= beaconsize;
22621  
22622 -       bytesleftforcurrentbeacon = beaconsize;
22623 -
22624 -       memcpy(bss->bssid, pcurrentptr, ETH_ALEN);
22625 -       lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid));
22626 -
22627 -       pcurrentptr += ETH_ALEN;
22628 -       bytesleftforcurrentbeacon -= ETH_ALEN;
22629 +       memcpy(bss->bssid, pos, ETH_ALEN);
22630 +       lbs_deb_scan("process_bss: BSSID %s\n", print_mac(mac, bss->bssid));
22631 +       pos += ETH_ALEN;
22632  
22633 -       if (bytesleftforcurrentbeacon < 12) {
22634 +       if ((end - pos) < 12) {
22635                 lbs_deb_scan("process_bss: Not enough bytes left\n");
22636 -               return -1;
22637 +               ret = -1;
22638 +               goto done;
22639         }
22640  
22641         /*
22642 @@ -968,124 +747,97 @@ static int libertas_process_bss(struct b
22643          */
22644  
22645         /* RSSI is 1 byte long */
22646 -       bss->rssi = *pcurrentptr;
22647 -       lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
22648 -       pcurrentptr += 1;
22649 -       bytesleftforcurrentbeacon -= 1;
22650 +       bss->rssi = *pos;
22651 +       lbs_deb_scan("process_bss: RSSI %d\n", *pos);
22652 +       pos++;
22653  
22654         /* time stamp is 8 bytes long */
22655 -       fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr);
22656 -       pcurrentptr += 8;
22657 -       bytesleftforcurrentbeacon -= 8;
22658 +       pos += 8;
22659  
22660         /* beacon interval is 2 bytes long */
22661 -       fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
22662 -       pcurrentptr += 2;
22663 -       bytesleftforcurrentbeacon -= 2;
22664 +       bss->beaconperiod = le16_to_cpup((void *) pos);
22665 +       pos += 2;
22666  
22667         /* capability information is 2 bytes long */
22668 -        memcpy(&fixedie.capabilities, pcurrentptr, 2);
22669 -       lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n",
22670 -              fixedie.capabilities);
22671 -       pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities;
22672 -       memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo));
22673 -       pcurrentptr += 2;
22674 -       bytesleftforcurrentbeacon -= 2;
22675 -
22676 -       /* rest of the current buffer are IE's */
22677 -       lbs_deb_scan("process_bss: IE length for this AP = %d\n",
22678 -              bytesleftforcurrentbeacon);
22679 -
22680 -       lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr,
22681 -               bytesleftforcurrentbeacon);
22682 -
22683 -       if (pcap->privacy) {
22684 -               lbs_deb_scan("process_bss: AP WEP enabled\n");
22685 -               bss->privacy = wlan802_11privfilter8021xWEP;
22686 -       } else {
22687 -               bss->privacy = wlan802_11privfilteracceptall;
22688 -       }
22689 -
22690 -       if (pcap->ibss == 1) {
22691 +       bss->capability = le16_to_cpup((void *) pos);
22692 +       lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability);
22693 +       pos += 2;
22694 +
22695 +       if (bss->capability & WLAN_CAPABILITY_PRIVACY)
22696 +               lbs_deb_scan("process_bss: WEP enabled\n");
22697 +       if (bss->capability & WLAN_CAPABILITY_IBSS)
22698                 bss->mode = IW_MODE_ADHOC;
22699 -       } else {
22700 +       else
22701                 bss->mode = IW_MODE_INFRA;
22702 -       }
22703 +
22704 +       /* rest of the current buffer are IE's */
22705 +       lbs_deb_scan("process_bss: IE len %zd\n", end - pos);
22706 +       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos);
22707  
22708         /* process variable IE */
22709 -       while (bytesleftforcurrentbeacon >= 2) {
22710 -               elemID = (enum ieeetypes_elementid) (*((u8 *) pcurrentptr));
22711 -               elemlen = *((u8 *) pcurrentptr + 1);
22712 +       while (pos <= end - 2) {
22713 +               struct ieee80211_info_element * elem =
22714 +                       (struct ieee80211_info_element *) pos;
22715  
22716 -               if (bytesleftforcurrentbeacon < elemlen) {
22717 +               if (pos + elem->len > end) {
22718                         lbs_deb_scan("process_bss: error in processing IE, "
22719                                "bytes left < IE length\n");
22720 -                       bytesleftforcurrentbeacon = 0;
22721 -                       continue;
22722 +                       break;
22723                 }
22724  
22725 -               switch (elemID) {
22726 -               case SSID:
22727 -                       bss->ssid_len = elemlen;
22728 -                       memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
22729 -                       lbs_deb_scan("ssid '%s', ssid length %u\n",
22730 +               switch (elem->id) {
22731 +               case MFIE_TYPE_SSID:
22732 +                       bss->ssid_len = elem->len;
22733 +                       memcpy(bss->ssid, elem->data, elem->len);
22734 +                       lbs_deb_scan("got SSID IE: '%s', len %u\n",
22735                                      escape_essid(bss->ssid, bss->ssid_len),
22736                                      bss->ssid_len);
22737                         break;
22738  
22739 -               case SUPPORTED_RATES:
22740 -                       memcpy(bss->datarates, (pcurrentptr + 2), elemlen);
22741 -                       memmove(bss->libertas_supported_rates, (pcurrentptr + 2),
22742 -                               elemlen);
22743 -                       ratesize = elemlen;
22744 -                       founddatarateie = 1;
22745 +               case MFIE_TYPE_RATES:
22746 +                       n_basic_rates = min_t(u8, MAX_RATES, elem->len);
22747 +                       memcpy(bss->rates, elem->data, n_basic_rates);
22748 +                       got_basic_rates = 1;
22749 +                       lbs_deb_scan("got RATES IE\n");
22750                         break;
22751  
22752 -               case EXTRA_IE:
22753 -                       lbs_deb_scan("process_bss: EXTRA_IE Found!\n");
22754 -                       break;
22755 -
22756 -               case FH_PARAM_SET:
22757 -                       pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
22758 +               case MFIE_TYPE_FH_SET:
22759 +                       pFH = (struct ieeetypes_fhparamset *) pos;
22760                         memmove(&bss->phyparamset.fhparamset, pFH,
22761                                 sizeof(struct ieeetypes_fhparamset));
22762 -#if 0 /* I think we can store these LE */
22763 -                       bss->phyparamset.fhparamset.dwelltime
22764 -                           = le16_to_cpu(bss->phyparamset.fhparamset.dwelltime);
22765 -#endif
22766 +                       lbs_deb_scan("got FH IE\n");
22767                         break;
22768  
22769 -               case DS_PARAM_SET:
22770 -                       pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
22771 +               case MFIE_TYPE_DS_SET:
22772 +                       pDS = (struct ieeetypes_dsparamset *) pos;
22773                         bss->channel = pDS->currentchan;
22774                         memcpy(&bss->phyparamset.dsparamset, pDS,
22775                                sizeof(struct ieeetypes_dsparamset));
22776 +                       lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
22777                         break;
22778  
22779 -               case CF_PARAM_SET:
22780 -                       pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
22781 +               case MFIE_TYPE_CF_SET:
22782 +                       pCF = (struct ieeetypes_cfparamset *) pos;
22783                         memcpy(&bss->ssparamset.cfparamset, pCF,
22784                                sizeof(struct ieeetypes_cfparamset));
22785 +                       lbs_deb_scan("got CF IE\n");
22786                         break;
22787  
22788 -               case IBSS_PARAM_SET:
22789 -                       pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
22790 -                       bss->atimwindow = le32_to_cpu(pibss->atimwindow);
22791 +               case MFIE_TYPE_IBSS_SET:
22792 +                       pibss = (struct ieeetypes_ibssparamset *) pos;
22793 +                       bss->atimwindow = le16_to_cpu(pibss->atimwindow);
22794                         memmove(&bss->ssparamset.ibssparamset, pibss,
22795                                 sizeof(struct ieeetypes_ibssparamset));
22796 -#if 0
22797 -                       bss->ssparamset.ibssparamset.atimwindow
22798 -                           = le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow);
22799 -#endif
22800 +                       lbs_deb_scan("got IBSS IE\n");
22801                         break;
22802  
22803 -                       /* Handle Country Info IE */
22804 -               case COUNTRY_INFO:
22805 -                       pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr;
22806 +               case MFIE_TYPE_COUNTRY:
22807 +                       pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
22808 +                       lbs_deb_scan("got COUNTRY IE\n");
22809                         if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
22810                             || pcountryinfo->len > 254) {
22811                                 lbs_deb_scan("process_bss: 11D- Err "
22812 -                                      "CountryInfo len =%d min=%zd max=254\n",
22813 +                                      "CountryInfo len %d, min %zd, max 254\n",
22814                                        pcountryinfo->len,
22815                                        sizeof(pcountryinfo->countrycode));
22816                                 ret = -1;
22817 @@ -1094,70 +846,78 @@ static int libertas_process_bss(struct b
22818  
22819                         memcpy(&bss->countryinfo,
22820                                pcountryinfo, pcountryinfo->len + 2);
22821 -                       lbs_dbg_hex("process_bss: 11D- CountryInfo:",
22822 +                       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
22823                                 (u8 *) pcountryinfo,
22824                                 (u32) (pcountryinfo->len + 2));
22825                         break;
22826  
22827 -               case EXTENDED_SUPPORTED_RATES:
22828 -                       /*
22829 -                        * only process extended supported rate
22830 -                        * if data rate is already found.
22831 -                        * data rate IE should come before
22832 +               case MFIE_TYPE_RATES_EX:
22833 +                       /* only process extended supported rate if data rate is
22834 +                        * already found. Data rate IE should come before
22835                          * extended supported rate IE
22836                          */
22837 -                       if (founddatarateie) {
22838 -                               if ((elemlen + ratesize) > WLAN_SUPPORTED_RATES) {
22839 -                                       bytestocopy =
22840 -                                           (WLAN_SUPPORTED_RATES - ratesize);
22841 -                               } else {
22842 -                                       bytestocopy = elemlen;
22843 -                               }
22844 -
22845 -                               pRate = (u8 *) bss->datarates;
22846 -                               pRate += ratesize;
22847 -                               memmove(pRate, (pcurrentptr + 2), bytestocopy);
22848 -                               pRate = (u8 *) bss->libertas_supported_rates;
22849 -                               pRate += ratesize;
22850 -                               memmove(pRate, (pcurrentptr + 2), bytestocopy);
22851 -                       }
22852 -                       break;
22853 -
22854 -               case VENDOR_SPECIFIC_221:
22855 -#define IE_ID_LEN_FIELDS_BYTES 2
22856 -                       pIe = (struct IE_WPA *)pcurrentptr;
22857 -
22858 -                       if (memcmp(pIe->oui, oui01, sizeof(oui01)))
22859 +                       lbs_deb_scan("got RATESEX IE\n");
22860 +                       if (!got_basic_rates) {
22861 +                               lbs_deb_scan("... but ignoring it\n");
22862                                 break;
22863 +                       }
22864  
22865 -                       bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
22866 -                               MAX_WPA_IE_LEN);
22867 -                       memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len);
22868 -                       lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen);
22869 -                       break;
22870 -               case WPA2_IE:
22871 -                       pIe = (struct IE_WPA *)pcurrentptr;
22872 -                       bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
22873 -                               MAX_WPA_IE_LEN);
22874 -                       memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len);
22875 -                       lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen);
22876 +                       n_ex_rates = elem->len;
22877 +                       if (n_basic_rates + n_ex_rates > MAX_RATES)
22878 +                               n_ex_rates = MAX_RATES - n_basic_rates;
22879 +
22880 +                       p = bss->rates + n_basic_rates;
22881 +                       memcpy(p, elem->data, n_ex_rates);
22882 +                       break;
22883 +
22884 +               case MFIE_TYPE_GENERIC:
22885 +                       if (elem->len >= 4 &&
22886 +                           elem->data[0] == 0x00 &&
22887 +                           elem->data[1] == 0x50 &&
22888 +                           elem->data[2] == 0xf2 &&
22889 +                           elem->data[3] == 0x01) {
22890 +                               bss->wpa_ie_len = min(elem->len + 2,
22891 +                                                     MAX_WPA_IE_LEN);
22892 +                               memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
22893 +                               lbs_deb_scan("got WPA IE\n");
22894 +                               lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie,
22895 +                                           elem->len);
22896 +                       } else if (elem->len >= MARVELL_MESH_IE_LENGTH &&
22897 +                           elem->data[0] == 0x00 &&
22898 +                           elem->data[1] == 0x50 &&
22899 +                           elem->data[2] == 0x43 &&
22900 +                           elem->data[3] == 0x04) {
22901 +                               lbs_deb_scan("got mesh IE\n");
22902 +                               bss->mesh = 1;
22903 +                       } else {
22904 +                               lbs_deb_scan("got generiec IE: "
22905 +                                       "%02x:%02x:%02x:%02x, len %d\n",
22906 +                                       elem->data[0], elem->data[1],
22907 +                                       elem->data[2], elem->data[3],
22908 +                                       elem->len);
22909 +                       }
22910                         break;
22911 -               case TIM:
22912 +
22913 +               case MFIE_TYPE_RSN:
22914 +                       lbs_deb_scan("got RSN IE\n");
22915 +                       bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
22916 +                       memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
22917 +                       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
22918 +                               bss->rsn_ie, elem->len);
22919                         break;
22920  
22921 -               case CHALLENGE_TEXT:
22922 +               default:
22923 +                       lbs_deb_scan("got IE 0x%04x, len %d\n",
22924 +                               elem->id, elem->len);
22925                         break;
22926                 }
22927  
22928 -               pcurrentptr += elemlen + 2;
22929 -
22930 -               /* need to account for IE ID and IE len */
22931 -               bytesleftforcurrentbeacon -= (elemlen + 2);
22932 -
22933 -       }                       /* while (bytesleftforcurrentbeacon > 2) */
22934 +               pos += elem->len + 2;
22935 +       }
22936  
22937         /* Timestamp */
22938         bss->last_scanned = jiffies;
22939 +       lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates));
22940  
22941         ret = 0;
22942  
22943 @@ -1167,54 +927,42 @@ done:
22944  }
22945  
22946  /**
22947 - *  @brief Compare two SSIDs
22948 - *
22949 - *  @param ssid1    A pointer to ssid to compare
22950 - *  @param ssid2    A pointer to ssid to compare
22951 - *
22952 - *  @return         0--ssid is same, otherwise is different
22953 - */
22954 -int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
22955 -{
22956 -       if (ssid1_len != ssid2_len)
22957 -               return -1;
22958 -
22959 -       return memcmp(ssid1, ssid2, ssid1_len);
22960 -}
22961 -
22962 -/**
22963   *  @brief This function finds a specific compatible BSSID in the scan list
22964   *
22965 - *  @param adapter  A pointer to wlan_adapter
22966 + *  Used in association code
22967 + *
22968 + *  @param priv  A pointer to struct lbs_private
22969   *  @param bssid    BSSID to find in the scan list
22970   *  @param mode     Network mode: Infrastructure or IBSS
22971   *
22972   *  @return         index in BSSID list, or error return code (< 0)
22973   */
22974 -struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
22975 +struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
22976                 u8 * bssid, u8 mode)
22977  {
22978         struct bss_descriptor * iter_bss;
22979         struct bss_descriptor * found_bss = NULL;
22980  
22981 +       lbs_deb_enter(LBS_DEB_SCAN);
22982 +
22983         if (!bssid)
22984 -               return NULL;
22985 +               goto out;
22986  
22987 -       lbs_dbg_hex("libertas_find_BSSID_in_list: looking for ",
22988 +       lbs_deb_hex(LBS_DEB_SCAN, "looking for",
22989                 bssid, ETH_ALEN);
22990  
22991         /* Look through the scan table for a compatible match.  The loop will
22992          *   continue past a matched bssid that is not compatible in case there
22993          *   is an AP with multiple SSIDs assigned to the same BSSID
22994          */
22995 -       mutex_lock(&adapter->lock);
22996 -       list_for_each_entry (iter_bss, &adapter->network_list, list) {
22997 +       mutex_lock(&priv->lock);
22998 +       list_for_each_entry (iter_bss, &priv->network_list, list) {
22999                 if (compare_ether_addr(iter_bss->bssid, bssid))
23000                         continue; /* bssid doesn't match */
23001                 switch (mode) {
23002                 case IW_MODE_INFRA:
23003                 case IW_MODE_ADHOC:
23004 -                       if (!is_network_compatible(adapter, iter_bss, mode))
23005 +                       if (!is_network_compatible(priv, iter_bss, mode))
23006                                 break;
23007                         found_bss = iter_bss;
23008                         break;
23009 @@ -1223,22 +971,26 @@ struct bss_descriptor * libertas_find_bs
23010                         break;
23011                 }
23012         }
23013 -       mutex_unlock(&adapter->lock);
23014 +       mutex_unlock(&priv->lock);
23015  
23016 +out:
23017 +       lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
23018         return found_bss;
23019  }
23020  
23021  /**
23022   *  @brief This function finds ssid in ssid list.
23023   *
23024 - *  @param adapter  A pointer to wlan_adapter
23025 + *  Used in association code
23026 + *
23027 + *  @param priv  A pointer to struct lbs_private
23028   *  @param ssid     SSID to find in the list
23029   *  @param bssid    BSSID to qualify the SSID selection (if provided)
23030   *  @param mode     Network mode: Infrastructure or IBSS
23031   *
23032   *  @return         index in BSSID list
23033   */
23034 -struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
23035 +struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
23036                    u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
23037                    int channel)
23038  {
23039 @@ -1247,14 +999,16 @@ struct bss_descriptor * libertas_find_ss
23040         struct bss_descriptor * found_bss = NULL;
23041         struct bss_descriptor * tmp_oldest = NULL;
23042  
23043 -       mutex_lock(&adapter->lock);
23044 +       lbs_deb_enter(LBS_DEB_SCAN);
23045 +
23046 +       mutex_lock(&priv->lock);
23047  
23048 -       list_for_each_entry (iter_bss, &adapter->network_list, list) {
23049 +       list_for_each_entry (iter_bss, &priv->network_list, list) {
23050                 if (   !tmp_oldest
23051                     || (iter_bss->last_scanned < tmp_oldest->last_scanned))
23052                         tmp_oldest = iter_bss;
23053  
23054 -               if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
23055 +               if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
23056                                       ssid, ssid_len) != 0)
23057                         continue; /* ssid doesn't match */
23058                 if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
23059 @@ -1265,7 +1019,7 @@ struct bss_descriptor * libertas_find_ss
23060                 switch (mode) {
23061                 case IW_MODE_INFRA:
23062                 case IW_MODE_ADHOC:
23063 -                       if (!is_network_compatible(adapter, iter_bss, mode))
23064 +                       if (!is_network_compatible(priv, iter_bss, mode))
23065                                 break;
23066  
23067                         if (bssid) {
23068 @@ -1290,7 +1044,8 @@ struct bss_descriptor * libertas_find_ss
23069         }
23070  
23071  out:
23072 -       mutex_unlock(&adapter->lock);
23073 +       mutex_unlock(&priv->lock);
23074 +       lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
23075         return found_bss;
23076  }
23077  
23078 @@ -1300,24 +1055,27 @@ out:
23079   *  Search the scan table for the best SSID that also matches the current
23080   *   adapter network preference (infrastructure or adhoc)
23081   *
23082 - *  @param adapter  A pointer to wlan_adapter
23083 + *  @param priv  A pointer to struct lbs_private
23084   *
23085   *  @return         index in BSSID list
23086   */
23087 -struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
23088 -               u8 mode)
23089 +static struct bss_descriptor *lbs_find_best_ssid_in_list(
23090 +       struct lbs_private *priv,
23091 +       u8 mode)
23092  {
23093         u8 bestrssi = 0;
23094         struct bss_descriptor * iter_bss;
23095         struct bss_descriptor * best_bss = NULL;
23096  
23097 -       mutex_lock(&adapter->lock);
23098 +       lbs_deb_enter(LBS_DEB_SCAN);
23099 +
23100 +       mutex_lock(&priv->lock);
23101  
23102 -       list_for_each_entry (iter_bss, &adapter->network_list, list) {
23103 +       list_for_each_entry (iter_bss, &priv->network_list, list) {
23104                 switch (mode) {
23105                 case IW_MODE_INFRA:
23106                 case IW_MODE_ADHOC:
23107 -                       if (!is_network_compatible(adapter, iter_bss, mode))
23108 +                       if (!is_network_compatible(priv, iter_bss, mode))
23109                                 break;
23110                         if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
23111                                 break;
23112 @@ -1334,34 +1092,34 @@ struct bss_descriptor * libertas_find_be
23113                 }
23114         }
23115  
23116 -       mutex_unlock(&adapter->lock);
23117 +       mutex_unlock(&priv->lock);
23118 +       lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss);
23119         return best_bss;
23120  }
23121  
23122  /**
23123   *  @brief Find the AP with specific ssid in the scan list
23124   *
23125 - *  @param priv         A pointer to wlan_private structure
23126 + *  Used from association worker.
23127 + *
23128 + *  @param priv         A pointer to struct lbs_private structure
23129   *  @param pSSID        A pointer to AP's ssid
23130   *
23131   *  @return             0--success, otherwise--fail
23132   */
23133 -int libertas_find_best_network_ssid(wlan_private * priv,
23134 +int lbs_find_best_network_ssid(struct lbs_private *priv,
23135                 u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode)
23136  {
23137 -       wlan_adapter *adapter = priv->adapter;
23138         int ret = -1;
23139         struct bss_descriptor * found;
23140  
23141 -       lbs_deb_enter(LBS_DEB_ASSOC);
23142 -
23143 -       wlan_scan_networks(priv, NULL, 1);
23144 -       if (adapter->surpriseremoved)
23145 -               return -1;
23146 +       lbs_deb_enter(LBS_DEB_SCAN);
23147  
23148 -       wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
23149 +       lbs_scan_networks(priv, NULL, 1);
23150 +       if (priv->surpriseremoved)
23151 +               goto out;
23152  
23153 -       found = libertas_find_best_ssid_in_list(adapter, preferred_mode);
23154 +       found = lbs_find_best_ssid_in_list(priv, preferred_mode);
23155         if (found && (found->ssid_len > 0)) {
23156                 memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
23157                 *out_ssid_len = found->ssid_len;
23158 @@ -1369,54 +1127,33 @@ int libertas_find_best_network_ssid(wlan
23159                 ret = 0;
23160         }
23161  
23162 +out:
23163         lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
23164         return ret;
23165  }
23166  
23167 -/**
23168 - *  @brief Scan Network
23169 - *
23170 - *  @param dev          A pointer to net_device structure
23171 - *  @param info         A pointer to iw_request_info structure
23172 - *  @param vwrq         A pointer to iw_param structure
23173 - *  @param extra        A pointer to extra data buf
23174 - *
23175 - *  @return             0 --success, otherwise fail
23176 - */
23177 -int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
23178 -                 struct iw_param *vwrq, char *extra)
23179 -{
23180 -       wlan_private *priv = dev->priv;
23181 -       wlan_adapter *adapter = priv->adapter;
23182 -
23183 -       lbs_deb_enter(LBS_DEB_SCAN);
23184 -
23185 -       wlan_scan_networks(priv, NULL, 0);
23186 -
23187 -       if (adapter->surpriseremoved)
23188 -               return -1;
23189 -
23190 -       lbs_deb_leave(LBS_DEB_SCAN);
23191 -       return 0;
23192 -}
23193  
23194  /**
23195   *  @brief Send a scan command for all available channels filtered on a spec
23196   *
23197 - *  @param priv             A pointer to wlan_private structure
23198 - *  @param prequestedssid   A pointer to AP's ssid
23199 - *  @param keeppreviousscan Flag used to save/clear scan table before scan
23200 + *  Used in association code and from debugfs
23201 + *
23202 + *  @param priv             A pointer to struct lbs_private structure
23203 + *  @param ssid             A pointer to the SSID to scan for
23204 + *  @param ssid_len         Length of the SSID
23205 + *  @param clear_ssid       Should existing scan results with this SSID
23206 + *                          be cleared?
23207   *
23208   *  @return                0-success, otherwise fail
23209   */
23210 -int libertas_send_specific_ssid_scan(wlan_private * priv,
23211 +int lbs_send_specific_ssid_scan(struct lbs_private *priv,
23212                         u8 *ssid, u8 ssid_len, u8 clear_ssid)
23213  {
23214 -       wlan_adapter *adapter = priv->adapter;
23215 -       struct wlan_ioctl_user_scan_cfg scancfg;
23216 +       struct lbs_ioctl_user_scan_cfg scancfg;
23217         int ret = 0;
23218  
23219 -       lbs_deb_enter(LBS_DEB_ASSOC);
23220 +       lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d",
23221 +               escape_essid(ssid, ssid_len), clear_ssid);
23222  
23223         if (!ssid_len)
23224                 goto out;
23225 @@ -1426,54 +1163,33 @@ int libertas_send_specific_ssid_scan(wla
23226         scancfg.ssid_len = ssid_len;
23227         scancfg.clear_ssid = clear_ssid;
23228  
23229 -       wlan_scan_networks(priv, &scancfg, 1);
23230 -       if (adapter->surpriseremoved)
23231 -               return -1;
23232 -       wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
23233 +       lbs_scan_networks(priv, &scancfg, 1);
23234 +       if (priv->surpriseremoved) {
23235 +               ret = -1;
23236 +               goto out;
23237 +       }
23238  
23239  out:
23240 -       lbs_deb_leave(LBS_DEB_ASSOC);
23241 +       lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
23242         return ret;
23243  }
23244  
23245 -/**
23246 - *  @brief scan an AP with specific BSSID
23247 - *
23248 - *  @param priv             A pointer to wlan_private structure
23249 - *  @param bssid            A pointer to AP's bssid
23250 - *  @param keeppreviousscan Flag used to save/clear scan table before scan
23251 - *
23252 - *  @return          0-success, otherwise fail
23253 - */
23254 -int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
23255 -{
23256 -       struct wlan_ioctl_user_scan_cfg scancfg;
23257  
23258 -       lbs_deb_enter(LBS_DEB_ASSOC);
23259  
23260 -       if (bssid == NULL)
23261 -               goto out;
23262  
23263 -       memset(&scancfg, 0x00, sizeof(scancfg));
23264 -       memcpy(scancfg.bssid, bssid, ETH_ALEN);
23265 -       scancfg.clear_bssid = clear_bssid;
23266 +/*********************************************************************/
23267 +/*                                                                   */
23268 +/*  Support for Wireless Extensions                                  */
23269 +/*                                                                   */
23270 +/*********************************************************************/
23271  
23272 -       wlan_scan_networks(priv, &scancfg, 1);
23273 -       if (priv->adapter->surpriseremoved)
23274 -               return -1;
23275 -       wait_event_interruptible(priv->adapter->cmd_pending,
23276 -               !priv->adapter->nr_cmd_pending);
23277  
23278 -out:
23279 -       lbs_deb_leave(LBS_DEB_ASSOC);
23280 -       return 0;
23281 -}
23282 +#define MAX_CUSTOM_LEN 64
23283  
23284 -static inline char *libertas_translate_scan(wlan_private *priv,
23285 +static inline char *lbs_translate_scan(struct lbs_private *priv,
23286                                         char *start, char *stop,
23287                                         struct bss_descriptor *bss)
23288  {
23289 -       wlan_adapter *adapter = priv->adapter;
23290         struct chan_freq_power *cfp;
23291         char *current_val;      /* For rates */
23292         struct iw_event iwe;    /* Temporary buffer */
23293 @@ -1483,13 +1199,16 @@ static inline char *libertas_translate_s
23294  #define RSSI_DIFF    ((u8)(PERFECT_RSSI - WORST_RSSI))
23295         u8 rssi;
23296  
23297 -       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel);
23298 +       lbs_deb_enter(LBS_DEB_SCAN);
23299 +
23300 +       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, bss->channel);
23301         if (!cfp) {
23302                 lbs_deb_scan("Invalid channel number %d\n", bss->channel);
23303 -               return NULL;
23304 +               start = NULL;
23305 +               goto out;
23306         }
23307  
23308 -       /* First entry *MUST* be the AP BSSID */
23309 +       /* First entry *MUST* be the BSSID */
23310         iwe.cmd = SIOCGIWAP;
23311         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
23312         memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
23313 @@ -1525,32 +1244,32 @@ static inline char *libertas_translate_s
23314         if (iwe.u.qual.qual > 100)
23315                 iwe.u.qual.qual = 100;
23316  
23317 -       if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
23318 +       if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
23319                 iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
23320         } else {
23321                 iwe.u.qual.noise =
23322 -                   CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
23323 +                   CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
23324         }
23325  
23326         /* Locally created ad-hoc BSSs won't have beacons if this is the
23327          * only station in the adhoc network; so get signal strength
23328          * from receive statistics.
23329          */
23330 -       if ((adapter->mode == IW_MODE_ADHOC)
23331 -           && adapter->adhoccreate
23332 -           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
23333 -                                 adapter->curbssparams.ssid_len,
23334 +       if ((priv->mode == IW_MODE_ADHOC)
23335 +           && priv->adhoccreate
23336 +           && !lbs_ssid_cmp(priv->curbssparams.ssid,
23337 +                                 priv->curbssparams.ssid_len,
23338                                   bss->ssid, bss->ssid_len)) {
23339                 int snr, nf;
23340 -               snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
23341 -               nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
23342 +               snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
23343 +               nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
23344                 iwe.u.qual.level = CAL_RSSI(snr, nf);
23345         }
23346         start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
23347  
23348         /* Add encryption capability */
23349         iwe.cmd = SIOCGIWENCODE;
23350 -       if (bss->privacy) {
23351 +       if (bss->capability & WLAN_CAPABILITY_PRIVACY) {
23352                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
23353         } else {
23354                 iwe.u.data.flags = IW_ENCODE_DISABLED;
23355 @@ -1565,20 +1284,17 @@ static inline char *libertas_translate_s
23356         iwe.u.bitrate.disabled = 0;
23357         iwe.u.bitrate.value = 0;
23358  
23359 -       for (j = 0; j < sizeof(bss->libertas_supported_rates); j++) {
23360 -               u8 rate = bss->libertas_supported_rates[j];
23361 -               if (rate == 0)
23362 -                       break; /* no more rates */
23363 -               /* Bit rate given in 500 kb/s units (+ 0x80) */
23364 -               iwe.u.bitrate.value = (rate & 0x7f) * 500000;
23365 +       for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
23366 +               /* Bit rate given in 500 kb/s units */
23367 +               iwe.u.bitrate.value = bss->rates[j] * 500000;
23368                 current_val = iwe_stream_add_value(start, current_val,
23369                                          stop, &iwe, IW_EV_PARAM_LEN);
23370         }
23371         if ((bss->mode == IW_MODE_ADHOC)
23372 -           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
23373 -                                 adapter->curbssparams.ssid_len,
23374 +           && !lbs_ssid_cmp(priv->curbssparams.ssid,
23375 +                                 priv->curbssparams.ssid_len,
23376                                   bss->ssid, bss->ssid_len)
23377 -           && adapter->adhoccreate) {
23378 +           && priv->adhoccreate) {
23379                 iwe.u.bitrate.value = 22 * 500000;
23380                 current_val = iwe_stream_add_value(start, current_val,
23381                                          stop, &iwe, IW_EV_PARAM_LEN);
23382 @@ -1605,11 +1321,73 @@ static inline char *libertas_translate_s
23383                 start = iwe_stream_add_point(start, stop, &iwe, buf);
23384         }
23385  
23386 +       if (bss->mesh) {
23387 +               char custom[MAX_CUSTOM_LEN];
23388 +               char *p = custom;
23389 +
23390 +               iwe.cmd = IWEVCUSTOM;
23391 +               p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
23392 +                             "mesh-type: olpc");
23393 +               iwe.u.data.length = p - custom;
23394 +               if (iwe.u.data.length)
23395 +                       start = iwe_stream_add_point(start, stop, &iwe, custom);
23396 +       }
23397 +
23398 +out:
23399 +       lbs_deb_leave_args(LBS_DEB_SCAN, "start %p", start);
23400         return start;
23401  }
23402  
23403 +
23404  /**
23405 - *  @brief  Retrieve the scan table entries via wireless tools IOCTL call
23406 + *  @brief Handle Scan Network ioctl
23407 + *
23408 + *  @param dev          A pointer to net_device structure
23409 + *  @param info         A pointer to iw_request_info structure
23410 + *  @param vwrq         A pointer to iw_param structure
23411 + *  @param extra        A pointer to extra data buf
23412 + *
23413 + *  @return             0 --success, otherwise fail
23414 + */
23415 +int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
23416 +                 struct iw_param *wrqu, char *extra)
23417 +{
23418 +       struct lbs_private *priv = dev->priv;
23419 +
23420 +       lbs_deb_enter(LBS_DEB_SCAN);
23421 +
23422 +       if (!netif_running(dev))
23423 +               return -ENETDOWN;
23424 +
23425 +       /* mac80211 does this:
23426 +       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
23427 +       if (sdata->type != IEEE80211_IF_TYPE_xxx)
23428 +               return -EOPNOTSUPP;
23429 +
23430 +       if (wrqu->data.length == sizeof(struct iw_scan_req) &&
23431 +           wrqu->data.flags & IW_SCAN_THIS_ESSID) {
23432 +               req = (struct iw_scan_req *)extra;
23433 +                       ssid = req->essid;
23434 +               ssid_len = req->essid_len;
23435 +       }
23436 +       */
23437 +
23438 +       if (!delayed_work_pending(&priv->scan_work))
23439 +               queue_delayed_work(priv->work_thread, &priv->scan_work,
23440 +                       msecs_to_jiffies(50));
23441 +       /* set marker that currently a scan is taking place */
23442 +       priv->last_scanned_channel = -1;
23443 +
23444 +       if (priv->surpriseremoved)
23445 +               return -EIO;
23446 +
23447 +       lbs_deb_leave(LBS_DEB_SCAN);
23448 +       return 0;
23449 +}
23450 +
23451 +
23452 +/**
23453 + *  @brief  Handle Retrieve scan table ioctl
23454   *
23455   *  @param dev          A pointer to net_device structure
23456   *  @param info         A pointer to iw_request_info structure
23457 @@ -1618,32 +1396,31 @@ static inline char *libertas_translate_s
23458   *
23459   *  @return             0 --success, otherwise fail
23460   */
23461 -int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
23462 +int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
23463                   struct iw_point *dwrq, char *extra)
23464  {
23465  #define SCAN_ITEM_SIZE 128
23466 -       wlan_private *priv = dev->priv;
23467 -       wlan_adapter *adapter = priv->adapter;
23468 +       struct lbs_private *priv = dev->priv;
23469         int err = 0;
23470         char *ev = extra;
23471         char *stop = ev + dwrq->length;
23472         struct bss_descriptor * iter_bss;
23473         struct bss_descriptor * safe;
23474  
23475 -       lbs_deb_enter(LBS_DEB_ASSOC);
23476 +       lbs_deb_enter(LBS_DEB_SCAN);
23477  
23478 -       /* If we've got an uncompleted scan, schedule the next part */
23479 -       if (!adapter->nr_cmd_pending && adapter->last_scanned_channel)
23480 -               wlan_scan_networks(priv, NULL, 0);
23481 +       /* iwlist should wait until the current scan is finished */
23482 +       if (priv->last_scanned_channel)
23483 +               return -EAGAIN;
23484  
23485         /* Update RSSI if current BSS is a locally created ad-hoc BSS */
23486 -       if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) {
23487 -               libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
23488 -                                       cmd_option_waitforrsp, 0, NULL);
23489 +       if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) {
23490 +               lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
23491 +                                       CMD_OPTION_WAITFORRSP, 0, NULL);
23492         }
23493  
23494 -       mutex_lock(&adapter->lock);
23495 -       list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
23496 +       mutex_lock(&priv->lock);
23497 +       list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
23498                 char * next_ev;
23499                 unsigned long stale_time;
23500  
23501 @@ -1652,95 +1429,87 @@ int libertas_get_scan(struct net_device 
23502                         break;
23503                 }
23504  
23505 +               /* For mesh device, list only mesh networks */
23506 +               if (dev == priv->mesh_dev && !iter_bss->mesh)
23507 +                       continue;
23508 +
23509                 /* Prune old an old scan result */
23510                 stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
23511                 if (time_after(jiffies, stale_time)) {
23512                         list_move_tail (&iter_bss->list,
23513 -                                       &adapter->network_free_list);
23514 +                                       &priv->network_free_list);
23515                         clear_bss_descriptor(iter_bss);
23516                         continue;
23517                 }
23518  
23519                 /* Translate to WE format this entry */
23520 -               next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
23521 +               next_ev = lbs_translate_scan(priv, ev, stop, iter_bss);
23522                 if (next_ev == NULL)
23523                         continue;
23524                 ev = next_ev;
23525         }
23526 -       mutex_unlock(&adapter->lock);
23527 +       mutex_unlock(&priv->lock);
23528  
23529         dwrq->length = (ev - extra);
23530         dwrq->flags = 0;
23531  
23532 -       lbs_deb_leave(LBS_DEB_ASSOC);
23533 +       lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", err);
23534         return err;
23535  }
23536  
23537 +
23538 +
23539 +
23540 +/*********************************************************************/
23541 +/*                                                                   */
23542 +/*  Command execution                                                */
23543 +/*                                                                   */
23544 +/*********************************************************************/
23545 +
23546 +
23547  /**
23548   *  @brief Prepare a scan command to be sent to the firmware
23549   *
23550 - *  Use the wlan_scan_cmd_config sent to the command processing module in
23551 - *   the libertas_prepare_and_send_command to configure a cmd_ds_802_11_scan command
23552 - *   struct to send to firmware.
23553 + *  Called via lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, ...)
23554 + *  from cmd.c
23555   *
23556 - *  The fixed fields specifying the BSS type and BSSID filters as well as a
23557 - *   variable number/length of TLVs are sent in the command to firmware.
23558 + *  Sends a fixed lenght data part (specifying the BSS type and BSSID filters)
23559 + *  as well as a variable number/length of TLVs to the firmware.
23560   *
23561 - *  @param priv       A pointer to wlan_private structure
23562 + *  @param priv       A pointer to struct lbs_private structure
23563   *  @param cmd        A pointer to cmd_ds_command structure to be sent to
23564   *                    firmware with the cmd_DS_801_11_SCAN structure
23565 - *  @param pdata_buf  Void pointer cast of a wlan_scan_cmd_config struct used
23566 + *  @param pdata_buf  Void pointer cast of a lbs_scan_cmd_config struct used
23567   *                    to set the fields/TLVs for the command sent to firmware
23568   *
23569   *  @return           0 or -1
23570 - *
23571 - *  @sa wlan_scan_create_channel_list
23572   */
23573 -int libertas_cmd_80211_scan(wlan_private * priv,
23574 -                        struct cmd_ds_command *cmd, void *pdata_buf)
23575 +int lbs_cmd_80211_scan(struct lbs_private *priv,
23576 +       struct cmd_ds_command *cmd, void *pdata_buf)
23577  {
23578         struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
23579 -       struct wlan_scan_cmd_config *pscancfg;
23580 -
23581 -       lbs_deb_enter(LBS_DEB_ASSOC);
23582 +       struct lbs_scan_cmd_config *pscancfg = pdata_buf;
23583  
23584 -       pscancfg = pdata_buf;
23585 +       lbs_deb_enter(LBS_DEB_SCAN);
23586  
23587         /* Set fixed field variables in scan command */
23588         pscan->bsstype = pscancfg->bsstype;
23589 -       memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID));
23590 +       memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN);
23591         memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
23592  
23593 -       cmd->command = cpu_to_le16(cmd_802_11_scan);
23594 -
23595         /* size is equal to the sizeof(fixed portions) + the TLV len + header */
23596 -       cmd->size = cpu_to_le16(sizeof(pscan->bsstype)
23597 -                                    + sizeof(pscan->BSSID)
23598 -                                    + pscancfg->tlvbufferlen + S_DS_GEN);
23599 -
23600 -       lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
23601 -                    le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
23602 -                    le16_to_cpu(cmd->seqnum));
23603 +       cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN
23604 +                               + pscancfg->tlvbufferlen + S_DS_GEN);
23605  
23606 -       lbs_deb_leave(LBS_DEB_ASSOC);
23607 +       lbs_deb_leave(LBS_DEB_SCAN);
23608         return 0;
23609  }
23610  
23611 -static inline int is_same_network(struct bss_descriptor *src,
23612 -                                 struct bss_descriptor *dst)
23613 -{
23614 -       /* A network is only a duplicate if the channel, BSSID, and ESSID
23615 -        * all match.  We treat all <hidden> with the same BSSID and channel
23616 -        * as one network */
23617 -       return ((src->ssid_len == dst->ssid_len) &&
23618 -               (src->channel == dst->channel) &&
23619 -               !compare_ether_addr(src->bssid, dst->bssid) &&
23620 -               !memcmp(src->ssid, dst->ssid, src->ssid_len));
23621 -}
23622 -
23623  /**
23624   *  @brief This function handles the command response of scan
23625   *
23626 + *  Called from handle_cmd_response() in cmdrespc.
23627 + *
23628   *   The response buffer for the scan command has the following
23629   *      memory layout:
23630   *
23631 @@ -1757,17 +1526,14 @@ static inline int is_same_network(struct
23632   *     |            bufsize and sizeof the fixed fields above)     |
23633   *     .-----------------------------------------------------------.
23634   *
23635 - *  @param priv    A pointer to wlan_private structure
23636 + *  @param priv    A pointer to struct lbs_private structure
23637   *  @param resp    A pointer to cmd_ds_command
23638   *
23639   *  @return        0 or -1
23640   */
23641 -int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
23642 +int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
23643  {
23644 -       wlan_adapter *adapter = priv->adapter;
23645         struct cmd_ds_802_11_scan_rsp *pscan;
23646 -       struct mrvlietypes_data *ptlv;
23647 -       struct mrvlietypes_tsftimestamp *ptsftlv;
23648         struct bss_descriptor * iter_bss;
23649         struct bss_descriptor * safe;
23650         u8 *pbssinfo;
23651 @@ -1777,14 +1543,14 @@ int libertas_ret_80211_scan(wlan_private
23652         int tlvbufsize;
23653         int ret;
23654  
23655 -       lbs_deb_enter(LBS_DEB_ASSOC);
23656 +       lbs_deb_enter(LBS_DEB_SCAN);
23657  
23658         /* Prune old entries from scan table */
23659 -       list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
23660 +       list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
23661                 unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
23662                 if (time_before(jiffies, stale_time))
23663                         continue;
23664 -               list_move_tail (&iter_bss->list, &adapter->network_free_list);
23665 +               list_move_tail (&iter_bss->list, &priv->network_free_list);
23666                 clear_bss_descriptor(iter_bss);
23667         }
23668  
23669 @@ -1802,8 +1568,7 @@ int libertas_ret_80211_scan(wlan_private
23670         lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
23671  
23672         scanrespsize = le16_to_cpu(resp->size);
23673 -       lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n",
23674 -              pscan->nr_sets);
23675 +       lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets);
23676  
23677         pbssinfo = pscan->bssdesc_and_tlvbuffer;
23678  
23679 @@ -1816,11 +1581,6 @@ int libertas_ret_80211_scan(wlan_private
23680                                      + sizeof(pscan->nr_sets)
23681                                      + S_DS_GEN);
23682  
23683 -       ptlv = (struct mrvlietypes_data *) (pscan->bssdesc_and_tlvbuffer + bytesleft);
23684 -
23685 -       /* Search the TLV buffer space in the scan response for any valid TLVs */
23686 -       wlan_ret_802_11_scan_get_tlv_ptrs(ptlv, tlvbufsize, &ptsftlv);
23687 -
23688         /*
23689          *  Process each scan response returned (pscan->nr_sets).  Save
23690          *    the information in the newbssentry and then insert into the
23691 @@ -1831,17 +1591,18 @@ int libertas_ret_80211_scan(wlan_private
23692                 struct bss_descriptor new;
23693                 struct bss_descriptor * found = NULL;
23694                 struct bss_descriptor * oldest = NULL;
23695 +               DECLARE_MAC_BUF(mac);
23696  
23697                 /* Process the data fields and IEs returned for this BSS */
23698                 memset(&new, 0, sizeof (struct bss_descriptor));
23699 -               if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
23700 +               if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
23701                         /* error parsing the scan response, skipped */
23702                         lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
23703                         continue;
23704                 }
23705  
23706                 /* Try to find this bss in the scan table */
23707 -               list_for_each_entry (iter_bss, &adapter->network_list, list) {
23708 +               list_for_each_entry (iter_bss, &priv->network_list, list) {
23709                         if (is_same_network(iter_bss, &new)) {
23710                                 found = iter_bss;
23711                                 break;
23712 @@ -1855,33 +1616,22 @@ int libertas_ret_80211_scan(wlan_private
23713                 if (found) {
23714                         /* found, clear it */
23715                         clear_bss_descriptor(found);
23716 -               } else if (!list_empty(&adapter->network_free_list)) {
23717 +               } else if (!list_empty(&priv->network_free_list)) {
23718                         /* Pull one from the free list */
23719 -                       found = list_entry(adapter->network_free_list.next,
23720 +                       found = list_entry(priv->network_free_list.next,
23721                                            struct bss_descriptor, list);
23722 -                       list_move_tail(&found->list, &adapter->network_list);
23723 +                       list_move_tail(&found->list, &priv->network_list);
23724                 } else if (oldest) {
23725                         /* If there are no more slots, expire the oldest */
23726                         found = oldest;
23727                         clear_bss_descriptor(found);
23728 -                       list_move_tail(&found->list, &adapter->network_list);
23729 +                       list_move_tail(&found->list, &priv->network_list);
23730                 } else {
23731                         continue;
23732                 }
23733  
23734 -               lbs_deb_scan("SCAN_RESP: BSSID = " MAC_FMT "\n",
23735 -                      new.bssid[0], new.bssid[1], new.bssid[2],
23736 -                      new.bssid[3], new.bssid[4], new.bssid[5]);
23737 -
23738 -               /*
23739 -                * If the TSF TLV was appended to the scan results, save the
23740 -                *   this entries TSF value in the networktsf field.  The
23741 -                *   networktsf is the firmware's TSF value at the time the
23742 -                *   beacon or probe response was received.
23743 -                */
23744 -               if (ptsftlv) {
23745 -                       new.networktsf = le64_to_cpup(&ptsftlv->tsftable[idx]);
23746 -               }
23747 +               lbs_deb_scan("SCAN_RESP: BSSID %s\n",
23748 +                            print_mac(mac, new.bssid));
23749  
23750                 /* Copy the locally created newbssentry to the scan table */
23751                 memcpy(found, &new, offsetof(struct bss_descriptor, list));
23752 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/scan.h linux-2.6.22-300/drivers/net/wireless/libertas/scan.h
23753 --- linux-2.6.22-250/drivers/net/wireless/libertas/scan.h       2007-07-08 19:32:17.000000000 -0400
23754 +++ linux-2.6.22-300/drivers/net/wireless/libertas/scan.h       2008-06-05 18:10:06.000000000 -0400
23755 @@ -2,10 +2,10 @@
23756    * Interface for the wlan network scan routines
23757    *
23758    * Driver interface functions and type declarations for the scan module
23759 -  *   implemented in wlan_scan.c.
23760 +  * implemented in scan.c.
23761    */
23762 -#ifndef _WLAN_SCAN_H
23763 -#define _WLAN_SCAN_H
23764 +#ifndef _LBS_SCAN_H
23765 +#define _LBS_SCAN_H
23766  
23767  #include <net/ieee80211.h>
23768  #include "hostcmd.h"
23769 @@ -13,38 +13,38 @@
23770  /**
23771   *  @brief Maximum number of channels that can be sent in a setuserscan ioctl
23772   *
23773 - *  @sa wlan_ioctl_user_scan_cfg
23774 + *  @sa lbs_ioctl_user_scan_cfg
23775   */
23776 -#define WLAN_IOCTL_USER_SCAN_CHAN_MAX  50
23777 +#define LBS_IOCTL_USER_SCAN_CHAN_MAX  50
23778  
23779 -//! Infrastructure BSS scan type in wlan_scan_cmd_config
23780 -#define WLAN_SCAN_BSS_TYPE_BSS         1
23781 +//! Infrastructure BSS scan type in lbs_scan_cmd_config
23782 +#define LBS_SCAN_BSS_TYPE_BSS         1
23783  
23784 -//! Adhoc BSS scan type in wlan_scan_cmd_config
23785 -#define WLAN_SCAN_BSS_TYPE_IBSS        2
23786 +//! Adhoc BSS scan type in lbs_scan_cmd_config
23787 +#define LBS_SCAN_BSS_TYPE_IBSS        2
23788  
23789 -//! Adhoc or Infrastructure BSS scan type in wlan_scan_cmd_config, no filter
23790 -#define WLAN_SCAN_BSS_TYPE_ANY         3
23791 +//! Adhoc or Infrastructure BSS scan type in lbs_scan_cmd_config, no filter
23792 +#define LBS_SCAN_BSS_TYPE_ANY         3
23793  
23794  /**
23795   * @brief Structure used internally in the wlan driver to configure a scan.
23796   *
23797   * Sent to the command processing module to configure the firmware
23798 - *   scan command prepared by libertas_cmd_80211_scan.
23799 + *   scan command prepared by lbs_cmd_80211_scan.
23800   *
23801 - * @sa wlan_scan_networks
23802 + * @sa lbs_scan_networks
23803   *
23804   */
23805 -struct wlan_scan_cmd_config {
23806 +struct lbs_scan_cmd_config {
23807      /**
23808       *  @brief BSS type to be sent in the firmware command
23809       *
23810       *  Field can be used to restrict the types of networks returned in the
23811       *    scan.  valid settings are:
23812       *
23813 -     *   - WLAN_SCAN_BSS_TYPE_BSS  (infrastructure)
23814 -     *   - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
23815 -     *   - WLAN_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
23816 +     *   - LBS_SCAN_BSS_TYPE_BSS  (infrastructure)
23817 +     *   - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
23818 +     *   - LBS_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
23819       */
23820         u8 bsstype;
23821  
23822 @@ -68,12 +68,12 @@ struct wlan_scan_cmd_config {
23823  };
23824  
23825  /**
23826 - *  @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg
23827 + *  @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg
23828   *
23829   *  Multiple instances of this structure are included in the IOCTL command
23830   *   to configure a instance of a scan on the specific channel.
23831   */
23832 -struct wlan_ioctl_user_scan_chan {
23833 +struct lbs_ioctl_user_scan_chan {
23834         u8 channumber;          //!< channel Number to scan
23835         u8 radiotype;           //!< Radio type: 'B/G' band = 0, 'A' band = 1
23836         u8 scantype;            //!< Scan type: Active = 0, Passive = 1
23837 @@ -83,31 +83,26 @@ struct wlan_ioctl_user_scan_chan {
23838  /**
23839   *  @brief IOCTL input structure to configure an immediate scan cmd to firmware
23840   *
23841 - *  Used in the setuserscan (WLAN_SET_USER_SCAN) private ioctl.  Specifies
23842 + *  Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl.  Specifies
23843   *   a number of parameters to be used in general for the scan as well
23844 - *   as a channel list (wlan_ioctl_user_scan_chan) for each scan period
23845 + *   as a channel list (lbs_ioctl_user_scan_chan) for each scan period
23846   *   desired.
23847   *
23848 - *  @sa libertas_set_user_scan_ioctl
23849 + *  @sa lbs_set_user_scan_ioctl
23850   */
23851 -struct wlan_ioctl_user_scan_cfg {
23852 +struct lbs_ioctl_user_scan_cfg {
23853      /**
23854       *  @brief BSS type to be sent in the firmware command
23855       *
23856       *  Field can be used to restrict the types of networks returned in the
23857       *    scan.  valid settings are:
23858       *
23859 -     *   - WLAN_SCAN_BSS_TYPE_BSS  (infrastructure)
23860 -     *   - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
23861 -     *   - WLAN_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
23862 +     *   - LBS_SCAN_BSS_TYPE_BSS  (infrastructure)
23863 +     *   - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
23864 +     *   - LBS_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
23865       */
23866         u8 bsstype;
23867  
23868 -    /**
23869 -     *  @brief Configure the number of probe requests for active chan scans
23870 -     */
23871 -       u8 numprobes;
23872 -
23873         /**
23874          *  @brief BSSID filter sent in the firmware command to limit the results
23875          */
23876 @@ -124,11 +119,6 @@ struct wlan_ioctl_user_scan_cfg {
23877  
23878         /* Clear existing scan results matching this SSID */
23879         u8 clear_ssid;
23880 -
23881 -    /**
23882 -     *  @brief Variable number (fixed maximum) of channels to scan up
23883 -     */
23884 -       struct wlan_ioctl_user_scan_chan chanlist[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
23885  };
23886  
23887  /**
23888 @@ -140,8 +130,7 @@ struct bss_descriptor {
23889         u8 ssid[IW_ESSID_MAX_SIZE + 1];
23890         u8 ssid_len;
23891  
23892 -       /* WEP encryption requirement */
23893 -       u32 privacy;
23894 +       u16 capability;
23895  
23896         /* receive signal strength in dBm */
23897         long rssi;
23898 @@ -152,18 +141,16 @@ struct bss_descriptor {
23899  
23900         u32 atimwindow;
23901  
23902 +       /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
23903         u8 mode;
23904 -       u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
23905  
23906 -       __le64 timestamp;       //!< TSF value included in the beacon/probe response
23907 +       /* zero-terminated array of supported data rates */
23908 +       u8 rates[MAX_RATES + 1];
23909 +
23910         unsigned long last_scanned;
23911  
23912         union ieeetypes_phyparamset phyparamset;
23913         union IEEEtypes_ssparamset ssparamset;
23914 -       struct ieeetypes_capinfo cap;
23915 -       u8 datarates[WLAN_SUPPORTED_RATES];
23916 -
23917 -       u64 networktsf;         //!< TSF timestamp from the current firmware TSF
23918  
23919         struct ieeetypes_countryinfofullset countryinfo;
23920  
23921 @@ -172,38 +159,35 @@ struct bss_descriptor {
23922         u8 rsn_ie[MAX_WPA_IE_LEN];
23923         size_t rsn_ie_len;
23924  
23925 +       u8 mesh;
23926 +
23927         struct list_head list;
23928  };
23929  
23930 -extern int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
23931 +int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
23932  
23933 -struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
23934 -                       u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
23935 -                       int channel);
23936 +struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
23937 +               u8 *ssid, u8 ssid_len, u8 *bssid, u8 mode,
23938 +               int channel);
23939  
23940 -struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
23941 -                       u8 mode);
23942 +struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
23943 +       u8 *bssid, u8 mode);
23944  
23945 -extern struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
23946 -                       u8 * bssid, u8 mode);
23947 -
23948 -int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid,
23949 +int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid,
23950                         u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode);
23951  
23952 -extern int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid,
23953 +int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
23954                                 u8 ssid_len, u8 clear_ssid);
23955 -extern int libertas_send_specific_bssid_scan(wlan_private * priv,
23956 -                                u8 * bssid, u8 clear_bssid);
23957  
23958 -extern int libertas_cmd_80211_scan(wlan_private * priv,
23959 +int lbs_cmd_80211_scan(struct lbs_private *priv,
23960                                 struct cmd_ds_command *cmd,
23961                                 void *pdata_buf);
23962  
23963 -extern int libertas_ret_80211_scan(wlan_private * priv,
23964 +int lbs_ret_80211_scan(struct lbs_private *priv,
23965                                 struct cmd_ds_command *resp);
23966  
23967 -int wlan_scan_networks(wlan_private * priv,
23968 -                const struct wlan_ioctl_user_scan_cfg * puserscanin,
23969 +int lbs_scan_networks(struct lbs_private *priv,
23970 +       const struct lbs_ioctl_user_scan_cfg *puserscanin,
23971                  int full_scan);
23972  
23973  struct ifreq;
23974 @@ -211,9 +195,11 @@ struct ifreq;
23975  struct iw_point;
23976  struct iw_param;
23977  struct iw_request_info;
23978 -extern int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
23979 +int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
23980                          struct iw_point *dwrq, char *extra);
23981 -extern int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
23982 +int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
23983                          struct iw_param *vwrq, char *extra);
23984  
23985 -#endif                         /* _WLAN_SCAN_H */
23986 +void lbs_scan_worker(struct work_struct *work);
23987 +
23988 +#endif
23989 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/thread.h linux-2.6.22-300/drivers/net/wireless/libertas/thread.h
23990 --- linux-2.6.22-250/drivers/net/wireless/libertas/thread.h     2007-07-08 19:32:17.000000000 -0400
23991 +++ linux-2.6.22-300/drivers/net/wireless/libertas/thread.h     1969-12-31 19:00:00.000000000 -0500
23992 @@ -1,52 +0,0 @@
23993 -#ifndef        __WLAN_THREAD_H_
23994 -#define        __WLAN_THREAD_H_
23995 -
23996 -#include       <linux/kthread.h>
23997 -
23998 -struct wlan_thread {
23999 -       struct task_struct *task;
24000 -       wait_queue_head_t waitq;
24001 -       pid_t pid;
24002 -       void *priv;
24003 -};
24004 -
24005 -static inline void wlan_activate_thread(struct wlan_thread * thr)
24006 -{
24007 -       /** Record the thread pid */
24008 -       thr->pid = current->pid;
24009 -
24010 -       /** Initialize the wait queue */
24011 -       init_waitqueue_head(&thr->waitq);
24012 -}
24013 -
24014 -static inline void wlan_deactivate_thread(struct wlan_thread * thr)
24015 -{
24016 -       lbs_deb_enter(LBS_DEB_THREAD);
24017 -
24018 -       thr->pid = 0;
24019 -
24020 -       lbs_deb_leave(LBS_DEB_THREAD);
24021 -}
24022 -
24023 -static inline void wlan_create_thread(int (*wlanfunc) (void *),
24024 -                                     struct wlan_thread * thr, char *name)
24025 -{
24026 -       thr->task = kthread_run(wlanfunc, thr, "%s", name);
24027 -}
24028 -
24029 -static inline int wlan_terminate_thread(struct wlan_thread * thr)
24030 -{
24031 -       lbs_deb_enter(LBS_DEB_THREAD);
24032 -
24033 -       /* Check if the thread is active or not */
24034 -       if (!thr->pid) {
24035 -               printk(KERN_ERR "Thread does not exist\n");
24036 -               return -1;
24037 -       }
24038 -       kthread_stop(thr->task);
24039 -
24040 -       lbs_deb_leave(LBS_DEB_THREAD);
24041 -       return 0;
24042 -}
24043 -
24044 -#endif
24045 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/tx.c linux-2.6.22-300/drivers/net/wireless/libertas/tx.c
24046 --- linux-2.6.22-250/drivers/net/wireless/libertas/tx.c 2007-07-08 19:32:17.000000000 -0400
24047 +++ linux-2.6.22-300/drivers/net/wireless/libertas/tx.c 2008-06-05 18:10:06.000000000 -0400
24048 @@ -2,6 +2,7 @@
24049    * This file contains the handling of TX in wlan driver.
24050    */
24051  #include <linux/netdevice.h>
24052 +#include <linux/etherdevice.h>
24053  
24054  #include "hostcmd.h"
24055  #include "radiotap.h"
24056 @@ -10,6 +11,13 @@
24057  #include "dev.h"
24058  #include "wext.h"
24059  
24060 +static int multicast_ttl_override = 1;
24061 +static int broadcast_ttl_override = 0;
24062 +static int unicast_ttl_override = 0;
24063 +module_param(multicast_ttl_override, int, 0644);
24064 +module_param(broadcast_ttl_override, int, 0644);
24065 +module_param(unicast_ttl_override, int, 0644);
24066 +
24067  /**
24068   *  @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
24069   *  units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
24070 @@ -49,194 +57,146 @@ static u32 convert_radiotap_rate_to_mv(u
24071  }
24072  
24073  /**
24074 - *  @brief This function processes a single packet and sends
24075 - *  to IF layer
24076 + *  @brief This function checks the conditions and sends packet to IF
24077 + *  layer if everything is ok.
24078   *
24079 - *  @param priv    A pointer to wlan_private structure
24080 + *  @param priv    A pointer to struct lbs_private structure
24081   *  @param skb     A pointer to skb which includes TX packet
24082   *  @return       0 or -1
24083   */
24084 -static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
24085 +int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
24086  {
24087 -       wlan_adapter *adapter = priv->adapter;
24088 -       int ret = 0;
24089 -       struct txpd localtxpd;
24090 -       struct txpd *plocaltxpd = &localtxpd;
24091 -       u8 *p802x_hdr;
24092 -       struct tx_radiotap_hdr *pradiotap_hdr;
24093 -       u32 new_rate;
24094 -       u8 *ptr = priv->adapter->tmptxbuf;
24095 +       unsigned long flags;
24096 +       struct lbs_private *priv = dev->priv;
24097 +       struct txpd *txpd;
24098 +       char *tx_data;
24099 +       char *p802x_hdr;
24100 +       uint16_t pkt_len;
24101 +       int ret;
24102  
24103         lbs_deb_enter(LBS_DEB_TX);
24104  
24105 -       if (priv->adapter->surpriseremoved)
24106 -               return -1;
24107 +       ret = NETDEV_TX_OK;
24108 +
24109 +       /* We need to protect against the queues being restarted before
24110 +          we get round to stopping them */
24111 +       spin_lock_irqsave(&priv->driver_lock, flags);
24112  
24113 -       if ((priv->adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0)
24114 -               lbs_dbg_hex("TX packet: ", skb->data,
24115 -                        min_t(unsigned int, skb->len, 100));
24116 +       if (priv->surpriseremoved)
24117 +               goto free;
24118  
24119         if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
24120                 lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
24121                        skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
24122 -               ret = -1;
24123 -               goto done;
24124 -       }
24125 +               /* We'll never manage to send this one; drop it and return 'OK' */
24126  
24127 -       memset(plocaltxpd, 0, sizeof(struct txpd));
24128 +               priv->stats.tx_dropped++;
24129 +               priv->stats.tx_errors++;
24130 +               goto free;
24131 +       }
24132  
24133 -       plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
24134  
24135 -       /* offset of actual data */
24136 -       plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
24137 +       netif_stop_queue(priv->dev);
24138 +       if (priv->mesh_dev)
24139 +               netif_stop_queue(priv->mesh_dev);
24140  
24141 -       /* TxCtrl set by user or default */
24142 -       plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl);
24143 +       if (priv->tx_pending_len) {
24144 +               /* This can happen if packets come in on the mesh and eth
24145 +                  device simultaneously -- there's no mutual exclusion on
24146 +                  hard_start_xmit() calls between devices. */
24147 +               lbs_deb_tx("Packet on %s while busy\n", dev->name);
24148 +               ret = NETDEV_TX_BUSY;
24149 +               goto unlock;
24150 +       }
24151 +
24152 +       priv->tx_pending_len = -1;
24153 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
24154 +
24155 +       lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
24156 +
24157 +       txpd = (void *)priv->tx_pending_buf;
24158 +       tx_data = (void *)&txpd[1];
24159 +       memset(txpd, 0, sizeof(struct txpd));
24160  
24161         p802x_hdr = skb->data;
24162 -       if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
24163 +       pkt_len = skb->len;
24164  
24165 -               /* locate radiotap header */
24166 -               pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data;
24167 +       if (dev == priv->rtap_net_dev) {
24168 +               struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
24169  
24170                 /* set txpd fields from the radiotap header */
24171 -               new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
24172 -               if (new_rate != 0) {
24173 -                       /* use new tx_control[4:0] */
24174 -                       new_rate |= (adapter->pkttxctrl & ~0x1f);
24175 -                       plocaltxpd->tx_control = cpu_to_le32(new_rate);
24176 -               }
24177 +               txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
24178  
24179                 /* skip the radiotap header */
24180 -               p802x_hdr += sizeof(struct tx_radiotap_hdr);
24181 -               plocaltxpd->tx_packet_length =
24182 -                       cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
24183 -                                   - sizeof(struct tx_radiotap_hdr));
24184 +               p802x_hdr += sizeof(*rtap_hdr);
24185 +               pkt_len -= sizeof(*rtap_hdr);
24186  
24187 +               /* copy destination address from 802.11 header */
24188 +               memcpy(txpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
24189 +       } else {
24190 +               /* copy destination address from 802.3 header */
24191 +               memcpy(txpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
24192         }
24193 -       /* copy destination address from 802.3 or 802.11 header */
24194 -       if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
24195 -               memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
24196 -       else
24197 -               memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
24198  
24199 -       lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
24200 +       txpd->tx_packet_length = cpu_to_le16(pkt_len);
24201 +       txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
24202  
24203 -       if (IS_MESH_FRAME(skb)) {
24204 -               plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
24205 +       if (dev == priv->mesh_dev) {
24206 +               int ttl_override;
24207 +
24208 +               txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
24209 +
24210 +               if (is_broadcast_ether_addr(txpd->tx_dest_addr_high))
24211 +                       ttl_override = broadcast_ttl_override;
24212 +               else if (is_multicast_ether_addr(txpd->tx_dest_addr_high))
24213 +                       ttl_override = multicast_ttl_override;
24214 +               else
24215 +                       ttl_override = unicast_ttl_override;
24216 +
24217 +               if (ttl_override) {
24218 +                       /* Hack: set mesh ttl to 1 for mesh multicasts. If
24219 +                        tx_packet_location has room for the extra three
24220 +                        bytes, the firmware treats it as follows: */
24221 +                       tx_data[0] = 0; /* reserved */
24222 +                       tx_data[1] = 0; /* reserved */
24223 +                       tx_data[2] = ttl_override; /* ttl */
24224 +                       tx_data += 3;
24225 +                       txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd) + 3);
24226 +               }
24227         }
24228 +                       
24229  
24230 -       memcpy(ptr, plocaltxpd, sizeof(struct txpd));
24231 +       lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
24232  
24233 -       ptr += sizeof(struct txpd);
24234 +       lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, pkt_len);
24235  
24236 -       lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
24237 -       memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
24238 -       ret = priv->hw_host_to_card(priv, MVMS_DAT,
24239 -                                   priv->adapter->tmptxbuf,
24240 -                                   le16_to_cpu(plocaltxpd->tx_packet_length) +
24241 -                                   sizeof(struct txpd));
24242 -
24243 -       if (ret) {
24244 -               lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
24245 -               goto done;
24246 -       }
24247 +       memcpy(tx_data, p802x_hdr, pkt_len);
24248  
24249 -       lbs_deb_tx("SendSinglePacket succeeds\n");
24250 +       spin_lock_irqsave(&priv->driver_lock, flags);
24251 +       priv->tx_pending_len = pkt_len + le32_to_cpu(txpd->tx_packet_location);
24252  
24253 -done:
24254 -       if (!ret) {
24255 -               priv->stats.tx_packets++;
24256 -               priv->stats.tx_bytes += skb->len;
24257 -       } else {
24258 -               priv->stats.tx_dropped++;
24259 -               priv->stats.tx_errors++;
24260 -       }
24261 +       lbs_deb_tx("%s lined up packet\n", __func__);
24262 +
24263 +       priv->stats.tx_packets++;
24264 +       priv->stats.tx_bytes += skb->len;
24265  
24266 -       if (!ret && priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
24267 +       dev->trans_start = jiffies;
24268 +
24269 +       if (priv->monitormode != LBS_MONITOR_OFF) {
24270                 /* Keep the skb to echo it back once Tx feedback is
24271                    received from FW */
24272                 skb_orphan(skb);
24273 -               /* stop processing outgoing pkts */
24274 -               netif_stop_queue(priv->dev);
24275 -               netif_stop_queue(priv->mesh_dev);
24276 -               /* freeze any packets already in our queues */
24277 -               priv->adapter->TxLockFlag = 1;
24278 -       } else {
24279 -               dev_kfree_skb_any(skb);
24280 -               priv->adapter->currenttxskb = NULL;
24281 -       }
24282  
24283 -       lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
24284 -       return ret;
24285 -}
24286 -
24287 -
24288 -void libertas_tx_runqueue(wlan_private *priv)
24289 -{
24290 -       wlan_adapter *adapter = priv->adapter;
24291 -       int i;
24292 -
24293 -       spin_lock(&adapter->txqueue_lock);
24294 -       for (i = 0; i < adapter->tx_queue_idx; i++) {
24295 -               struct sk_buff *skb = adapter->tx_queue_ps[i];
24296 -               spin_unlock(&adapter->txqueue_lock);
24297 -               SendSinglePacket(priv, skb);
24298 -               spin_lock(&adapter->txqueue_lock);
24299 -       }
24300 -       adapter->tx_queue_idx = 0;
24301 -       spin_unlock(&adapter->txqueue_lock);
24302 -}
24303 -
24304 -static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
24305 -{
24306 -       wlan_adapter *adapter = priv->adapter;
24307 -
24308 -       spin_lock(&adapter->txqueue_lock);
24309 -
24310 -       WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
24311 -       adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
24312 -       if (adapter->tx_queue_idx == NR_TX_QUEUE) {
24313 -               netif_stop_queue(priv->dev);
24314 -               netif_stop_queue(priv->mesh_dev);
24315 +               /* Keep the skb around for when we get feedback */
24316 +               priv->currenttxskb = skb;
24317         } else {
24318 -               netif_start_queue(priv->dev);
24319 -               netif_start_queue(priv->mesh_dev);
24320 -       }
24321 -
24322 -       spin_unlock(&adapter->txqueue_lock);
24323 -}
24324 -
24325 -/**
24326 - *  @brief This function checks the conditions and sends packet to IF
24327 - *  layer if everything is ok.
24328 - *
24329 - *  @param priv    A pointer to wlan_private structure
24330 - *  @return       n/a
24331 - */
24332 -int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
24333 -{
24334 -       int ret = -1;
24335 -
24336 -       lbs_deb_enter(LBS_DEB_TX);
24337 -       lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100));
24338 -
24339 -       if (priv->dnld_sent) {
24340 -               lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
24341 -                      priv->dnld_sent);
24342 -               goto done;
24343 -       }
24344 -
24345 -       if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
24346 -           (priv->adapter->psstate == PS_STATE_PRE_SLEEP)) {
24347 -               wlan_tx_queue(priv, skb);
24348 -               return ret;
24349 + free:
24350 +               dev_kfree_skb_any(skb);
24351         }
24352 + unlock:
24353 +       spin_unlock_irqrestore(&priv->driver_lock, flags);
24354 +       wake_up(&priv->waitq);
24355  
24356 -       priv->adapter->currenttxskb = skb;
24357 -
24358 -       ret = SendSinglePacket(priv, skb);
24359 -done:
24360         lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
24361         return ret;
24362  }
24363 @@ -245,28 +205,23 @@ done:
24364   *  @brief This function sends to the host the last transmitted packet,
24365   *  filling the radiotap headers with transmission information.
24366   *
24367 - *  @param priv     A pointer to wlan_private structure
24368 + *  @param priv     A pointer to struct lbs_private structure
24369   *  @param status   A 32 bit value containing transmission status.
24370   *
24371   *  @returns void
24372   */
24373 -void libertas_send_tx_feedback(wlan_private * priv)
24374 +void lbs_send_tx_feedback(struct lbs_private *priv)
24375  {
24376 -       wlan_adapter *adapter = priv->adapter;
24377         struct tx_radiotap_hdr *radiotap_hdr;
24378 -       u32 status = adapter->eventcause;
24379 +       u32 status = priv->eventcause;
24380         int txfail;
24381         int try_count;
24382  
24383 -       if (adapter->radiomode != WLAN_RADIOMODE_RADIOTAP ||
24384 -           adapter->currenttxskb == NULL)
24385 +       if (priv->monitormode == LBS_MONITOR_OFF ||
24386 +           priv->currenttxskb == NULL)
24387                 return;
24388  
24389 -       radiotap_hdr = (struct tx_radiotap_hdr *)adapter->currenttxskb->data;
24390 -
24391 -       if ((adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0)
24392 -               lbs_dbg_hex("TX feedback: ", (u8 *) radiotap_hdr,
24393 -                       min_t(unsigned int, adapter->currenttxskb->len, 100));
24394 +       radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data;
24395  
24396         txfail = (status >> 24);
24397  
24398 @@ -279,13 +234,19 @@ void libertas_send_tx_feedback(wlan_priv
24399  #endif
24400         try_count = (status >> 16) & 0xff;
24401         radiotap_hdr->data_retries = (try_count) ?
24402 -           (1 + adapter->txretrycount - try_count) : 0;
24403 -       libertas_upload_rx_packet(priv, adapter->currenttxskb);
24404 -       adapter->currenttxskb = NULL;
24405 -       priv->adapter->TxLockFlag = 0;
24406 -       if (priv->adapter->connect_status == libertas_connected) {
24407 +           (1 + priv->txretrycount - try_count) : 0;
24408 +
24409 +
24410 +       priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb,
24411 +                                                     priv->rtap_net_dev);
24412 +       netif_rx(priv->currenttxskb);
24413 +
24414 +       priv->currenttxskb = NULL;
24415 +
24416 +       if (priv->connect_status == LBS_CONNECTED)
24417                 netif_wake_queue(priv->dev);
24418 +
24419 +       if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED))
24420                 netif_wake_queue(priv->mesh_dev);
24421 -       }
24422  }
24423 -EXPORT_SYMBOL_GPL(libertas_send_tx_feedback);
24424 +EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
24425 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/types.h linux-2.6.22-300/drivers/net/wireless/libertas/types.h
24426 --- linux-2.6.22-250/drivers/net/wireless/libertas/types.h      2007-07-08 19:32:17.000000000 -0400
24427 +++ linux-2.6.22-300/drivers/net/wireless/libertas/types.h      2008-06-05 18:10:06.000000000 -0400
24428 @@ -1,76 +1,13 @@
24429  /**
24430    * This header file contains definition for global types
24431    */
24432 -#ifndef _WLAN_TYPES_
24433 -#define _WLAN_TYPES_
24434 +#ifndef _LBS_TYPES_H_
24435 +#define _LBS_TYPES_H_
24436  
24437  #include <linux/if_ether.h>
24438  #include <asm/byteorder.h>
24439 -
24440 -/** IEEE type definitions  */
24441 -enum ieeetypes_elementid {
24442 -       SSID = 0,
24443 -       SUPPORTED_RATES,
24444 -       FH_PARAM_SET,
24445 -       DS_PARAM_SET,
24446 -       CF_PARAM_SET,
24447 -       TIM,
24448 -       IBSS_PARAM_SET,
24449 -       COUNTRY_INFO = 7,
24450 -
24451 -       CHALLENGE_TEXT = 16,
24452 -
24453 -       EXTENDED_SUPPORTED_RATES = 50,
24454 -
24455 -       VENDOR_SPECIFIC_221 = 221,
24456 -
24457 -       WPA_IE = 221,
24458 -       WPA2_IE = 48,
24459 -
24460 -       EXTRA_IE = 133,
24461 -} __attribute__ ((packed));
24462 -
24463 -#ifdef __BIG_ENDIAN
24464 -#define CAPINFO_MASK   (~(0xda00))
24465 -#else
24466 -#define CAPINFO_MASK   (~(0x00da))
24467 -#endif
24468 -
24469 -struct ieeetypes_capinfo {
24470 -#ifdef __BIG_ENDIAN_BITFIELD
24471 -       u8 chanagility:1;
24472 -       u8 pbcc:1;
24473 -       u8 shortpreamble:1;
24474 -       u8 privacy:1;
24475 -       u8 cfpollrqst:1;
24476 -       u8 cfpollable:1;
24477 -       u8 ibss:1;
24478 -       u8 ess:1;
24479 -       u8 rsrvd1:2;
24480 -       u8 dsssofdm:1;
24481 -       u8 rsvrd2:1;
24482 -       u8 apsd:1;
24483 -       u8 shortslottime:1;
24484 -       u8 rsrvd3:1;
24485 -       u8 spectrummgmt:1;
24486 -#else
24487 -       u8 ess:1;
24488 -       u8 ibss:1;
24489 -       u8 cfpollable:1;
24490 -       u8 cfpollrqst:1;
24491 -       u8 privacy:1;
24492 -       u8 shortpreamble:1;
24493 -       u8 pbcc:1;
24494 -       u8 chanagility:1;
24495 -       u8 spectrummgmt:1;
24496 -       u8 rsrvd3:1;
24497 -       u8 shortslottime:1;
24498 -       u8 apsd:1;
24499 -       u8 rsvrd2:1;
24500 -       u8 dsssofdm:1;
24501 -       u8 rsrvd1:2;
24502 -#endif
24503 -} __attribute__ ((packed));
24504 +#include <linux/wireless.h>
24505 +#include <net/ieee80211.h>
24506  
24507  struct ieeetypes_cfparamset {
24508         u8 elementid;
24509 @@ -114,7 +51,7 @@ union ieeetypes_phyparamset {
24510  } __attribute__ ((packed));
24511  
24512  struct ieeetypes_assocrsp {
24513 -       struct ieeetypes_capinfo capability;
24514 +       __le16 capability;
24515         __le16 statuscode;
24516         __le16 aid;
24517         u8 iebuffer[1];
24518 @@ -266,22 +203,11 @@ struct mrvlietypes_powercapability {
24519         s8 maxpower;
24520  } __attribute__ ((packed));
24521  
24522 -struct mrvlietypes_rssithreshold {
24523 -       struct mrvlietypesheader header;
24524 -       u8 rssivalue;
24525 -       u8 rssifreq;
24526 -} __attribute__ ((packed));
24527 -
24528 -struct mrvlietypes_snrthreshold {
24529 +/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
24530 +struct mrvlietypes_thresholds {
24531         struct mrvlietypesheader header;
24532 -       u8 snrvalue;
24533 -       u8 snrfreq;
24534 -} __attribute__ ((packed));
24535 -
24536 -struct mrvlietypes_failurecount {
24537 -       struct mrvlietypesheader header;
24538 -       u8 failvalue;
24539 -       u8 Failfreq;
24540 +       u8 value;
24541 +       u8 freq;
24542  } __attribute__ ((packed));
24543  
24544  struct mrvlietypes_beaconsmissed {
24545 @@ -315,4 +241,45 @@ struct mrvlietypes_ledgpio {
24546         struct led_pin ledpin[1];
24547  } __attribute__ ((packed));
24548  
24549 -#endif                         /* _WLAN_TYPES_ */
24550 +struct led_bhv {
24551 +       uint8_t firmwarestate;
24552 +       uint8_t led;
24553 +       uint8_t ledstate;
24554 +       uint8_t ledarg;
24555 +} __attribute__ ((packed));
24556 +
24557 +
24558 +struct mrvlietypes_ledbhv {
24559 +       struct mrvlietypesheader header;
24560 +       struct led_bhv ledbhv[1];
24561 +} __attribute__ ((packed));
24562 +
24563 +/* Meant to be packed as the value member of a struct ieee80211_info_element.
24564 + * Note that the len member of the ieee80211_info_element varies depending on
24565 + * the mesh_id_len */
24566 +struct mrvl_meshie_val {
24567 +       uint8_t oui[P80211_OUI_LEN];
24568 +       uint8_t type;
24569 +       uint8_t subtype;
24570 +       uint8_t version;
24571 +       uint8_t active_protocol_id;
24572 +       uint8_t active_metric_id;
24573 +       uint8_t mesh_capability;
24574 +       uint8_t mesh_id_len;
24575 +       uint8_t mesh_id[IW_ESSID_MAX_SIZE];
24576 +} __attribute__ ((packed));
24577 +
24578 +struct mrvl_meshie {
24579 +       struct ieee80211_info_element hdr;
24580 +       struct mrvl_meshie_val val;
24581 +} __attribute__ ((packed));
24582 +
24583 +struct mrvl_mesh_defaults {
24584 +       __le32 bootflag;
24585 +       uint8_t boottime;
24586 +       uint8_t reserved;
24587 +       __le16 channel;
24588 +       struct mrvl_meshie meshie;
24589 +} __attribute__ ((packed));
24590 +
24591 +#endif
24592 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/version.h linux-2.6.22-300/drivers/net/wireless/libertas/version.h
24593 --- linux-2.6.22-250/drivers/net/wireless/libertas/version.h    2007-07-08 19:32:17.000000000 -0400
24594 +++ linux-2.6.22-300/drivers/net/wireless/libertas/version.h    1969-12-31 19:00:00.000000000 -0500
24595 @@ -1 +0,0 @@
24596 -
24597 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/wext.c linux-2.6.22-300/drivers/net/wireless/libertas/wext.c
24598 --- linux-2.6.22-250/drivers/net/wireless/libertas/wext.c       2008-07-17 00:17:57.000000000 -0400
24599 +++ linux-2.6.22-300/drivers/net/wireless/libertas/wext.c       2008-06-05 18:10:06.000000000 -0400
24600 @@ -19,84 +19,47 @@
24601  #include "join.h"
24602  #include "wext.h"
24603  #include "assoc.h"
24604 +#include "cmd.h"
24605 +#include "ioctl.h"
24606  
24607 +static inline void lbs_postpone_association_work(struct lbs_private *priv)
24608 +{
24609 +       if (priv->surpriseremoved)
24610 +               return;
24611 +       cancel_delayed_work(&priv->assoc_work);
24612 +       queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2);
24613 +}
24614  
24615 -/**
24616 - * the rates supported by the card
24617 - */
24618 -static u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
24619 -    { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
24620 -      0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
24621 -};
24622 -
24623 -/**
24624 - *  @brief Convert mw value to dbm value
24625 - *
24626 - *  @param mw     the value of mw
24627 - *  @return       the value of dbm
24628 - */
24629 -static int mw_to_dbm(int mw)
24630 +static inline void lbs_cancel_association_work(struct lbs_private *priv)
24631  {
24632 -       if (mw < 2)
24633 -               return 0;
24634 -       else if (mw < 3)
24635 -               return 3;
24636 -       else if (mw < 4)
24637 -               return 5;
24638 -       else if (mw < 6)
24639 -               return 7;
24640 -       else if (mw < 7)
24641 -               return 8;
24642 -       else if (mw < 8)
24643 -               return 9;
24644 -       else if (mw < 10)
24645 -               return 10;
24646 -       else if (mw < 13)
24647 -               return 11;
24648 -       else if (mw < 16)
24649 -               return 12;
24650 -       else if (mw < 20)
24651 -               return 13;
24652 -       else if (mw < 25)
24653 -               return 14;
24654 -       else if (mw < 32)
24655 -               return 15;
24656 -       else if (mw < 40)
24657 -               return 16;
24658 -       else if (mw < 50)
24659 -               return 17;
24660 -       else if (mw < 63)
24661 -               return 18;
24662 -       else if (mw < 79)
24663 -               return 19;
24664 -       else if (mw < 100)
24665 -               return 20;
24666 -       else
24667 -               return 21;
24668 +       cancel_delayed_work(&priv->assoc_work);
24669 +       kfree(priv->pending_assoc_req);
24670 +       priv->pending_assoc_req = NULL;
24671  }
24672  
24673 +
24674  /**
24675   *  @brief Find the channel frequency power info with specific channel
24676   *
24677 - *  @param adapter     A pointer to wlan_adapter structure
24678 + *  @param priv        A pointer to struct lbs_private structure
24679   *  @param band                it can be BAND_A, BAND_G or BAND_B
24680   *  @param channel      the channel for looking
24681   *  @return            A pointer to struct chan_freq_power structure or NULL if not find.
24682   */
24683 -struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * adapter,
24684 -                                                u8 band, u16 channel)
24685 +struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
24686 +       struct lbs_private *priv,
24687 +       u8 band,
24688 +       u16 channel)
24689  {
24690         struct chan_freq_power *cfp = NULL;
24691         struct region_channel *rc;
24692 -       int count = sizeof(adapter->region_channel) /
24693 -           sizeof(adapter->region_channel[0]);
24694         int i, j;
24695  
24696 -       for (j = 0; !cfp && (j < count); j++) {
24697 -               rc = &adapter->region_channel[j];
24698 +       for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
24699 +               rc = &priv->region_channel[j];
24700  
24701 -               if (adapter->enable11d)
24702 -                       rc = &adapter->universal_channel[j];
24703 +               if (priv->enable11d)
24704 +                       rc = &priv->universal_channel[j];
24705                 if (!rc->valid || !rc->CFP)
24706                         continue;
24707                 if (rc->band != band)
24708 @@ -110,7 +73,7 @@ struct chan_freq_power *libertas_find_cf
24709         }
24710  
24711         if (!cfp && channel)
24712 -               lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find "
24713 +               lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find "
24714                        "cfp by band %d / channel %d\n", band, channel);
24715  
24716         return cfp;
24717 @@ -119,25 +82,25 @@ struct chan_freq_power *libertas_find_cf
24718  /**
24719   *  @brief Find the channel frequency power info with specific frequency
24720   *
24721 - *  @param adapter     A pointer to wlan_adapter structure
24722 + *  @param priv        A pointer to struct lbs_private structure
24723   *  @param band                it can be BAND_A, BAND_G or BAND_B
24724   *  @param freq                the frequency for looking
24725   *  @return            A pointer to struct chan_freq_power structure or NULL if not find.
24726   */
24727 -static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
24728 -                                                    u8 band, u32 freq)
24729 +static struct chan_freq_power *find_cfp_by_band_and_freq(
24730 +       struct lbs_private *priv,
24731 +       u8 band,
24732 +       u32 freq)
24733  {
24734         struct chan_freq_power *cfp = NULL;
24735         struct region_channel *rc;
24736 -       int count = sizeof(adapter->region_channel) /
24737 -           sizeof(adapter->region_channel[0]);
24738         int i, j;
24739  
24740 -       for (j = 0; !cfp && (j < count); j++) {
24741 -               rc = &adapter->region_channel[j];
24742 +       for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
24743 +               rc = &priv->region_channel[j];
24744  
24745 -               if (adapter->enable11d)
24746 -                       rc = &adapter->universal_channel[j];
24747 +               if (priv->enable11d)
24748 +                       rc = &priv->universal_channel[j];
24749                 if (!rc->valid || !rc->CFP)
24750                         continue;
24751                 if (rc->band != band)
24752 @@ -161,25 +124,24 @@ static struct chan_freq_power *find_cfp_
24753  /**
24754   *  @brief Set Radio On/OFF
24755   *
24756 - *  @param priv                 A pointer to wlan_private structure
24757 + *  @param priv                 A pointer to struct lbs_private structure
24758   *  @option                    Radio Option
24759   *  @return                    0 --success, otherwise fail
24760   */
24761 -int wlan_radio_ioctl(wlan_private * priv, u8 option)
24762 +static int lbs_radio_ioctl(struct lbs_private *priv, u8 option)
24763  {
24764         int ret = 0;
24765 -       wlan_adapter *adapter = priv->adapter;
24766  
24767         lbs_deb_enter(LBS_DEB_WEXT);
24768  
24769 -       if (adapter->radioon != option) {
24770 +       if (priv->radioon != option) {
24771                 lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
24772 -               adapter->radioon = option;
24773 +               priv->radioon = option;
24774  
24775 -               ret = libertas_prepare_and_send_command(priv,
24776 -                                           cmd_802_11_radio_control,
24777 -                                           cmd_act_set,
24778 -                                           cmd_option_waitforrsp, 0, NULL);
24779 +               ret = lbs_prepare_and_send_command(priv,
24780 +                                           CMD_802_11_RADIO_CONTROL,
24781 +                                           CMD_ACT_SET,
24782 +                                           CMD_OPTION_WAITFORRSP, 0, NULL);
24783         }
24784  
24785         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
24786 @@ -187,105 +149,52 @@ int wlan_radio_ioctl(wlan_private * priv
24787  }
24788  
24789  /**
24790 - *  @brief Copy rates
24791 - *
24792 - *  @param dest                 A pointer to Dest Buf
24793 - *  @param src                 A pointer to Src Buf
24794 - *  @param len                  The len of Src Buf
24795 - *  @return                    Number of rates copyed
24796 - */
24797 -static inline int copyrates(u8 * dest, int pos, u8 * src, int len)
24798 -{
24799 -       int i;
24800 -
24801 -       for (i = 0; i < len && src[i]; i++, pos++) {
24802 -               if (pos >= sizeof(u8) * WLAN_SUPPORTED_RATES)
24803 -                       break;
24804 -               dest[pos] = src[i];
24805 -       }
24806 -
24807 -       return pos;
24808 -}
24809 -
24810 -/**
24811 - *  @brief Get active data rates
24812 + *  @brief Copy active data rates based on adapter mode and status
24813   *
24814 - *  @param adapter              A pointer to wlan_adapter structure
24815 + *  @param priv              A pointer to struct lbs_private structure
24816   *  @param rate                        The buf to return the active rates
24817 - *  @return                    The number of rates
24818   */
24819 -static int get_active_data_rates(wlan_adapter * adapter,
24820 -                                u8* rates)
24821 +static void copy_active_data_rates(struct lbs_private *priv, u8 *rates)
24822  {
24823 -       int k = 0;
24824 -
24825         lbs_deb_enter(LBS_DEB_WEXT);
24826  
24827 -       if (adapter->connect_status != libertas_connected) {
24828 -               if (adapter->mode == IW_MODE_INFRA) {
24829 -                       lbs_deb_wext("infra\n");
24830 -                       k = copyrates(rates, k, libertas_supported_rates,
24831 -                                     sizeof(libertas_supported_rates));
24832 -               } else {
24833 -                       lbs_deb_wext("Adhoc G\n");
24834 -                       k = copyrates(rates, k, libertas_adhoc_rates_g,
24835 -                                     sizeof(libertas_adhoc_rates_g));
24836 -               }
24837 -       } else {
24838 -               k = copyrates(rates, 0, adapter->curbssparams.datarates,
24839 -                             adapter->curbssparams.numofrates);
24840 -       }
24841 +       if ((priv->connect_status != LBS_CONNECTED) &&
24842 +               (priv->mesh_connect_status != LBS_CONNECTED))
24843 +               memcpy(rates, lbs_bg_rates, MAX_RATES);
24844 +       else
24845 +               memcpy(rates, priv->curbssparams.rates, MAX_RATES);
24846  
24847 -       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k);
24848 -       return k;
24849 +       lbs_deb_leave(LBS_DEB_WEXT);
24850  }
24851  
24852 -static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
24853 +static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
24854                          char *cwrq, char *extra)
24855  {
24856 -       const char *cp;
24857 -       char comm[6] = { "COMM-" };
24858 -       char mrvl[6] = { "MRVL-" };
24859 -       int cnt;
24860  
24861         lbs_deb_enter(LBS_DEB_WEXT);
24862  
24863 -       strcpy(cwrq, mrvl);
24864 -
24865 -       cp = strstr(libertas_driver_version, comm);
24866 -       if (cp == libertas_driver_version)      //skip leading "COMM-"
24867 -               cp = libertas_driver_version + strlen(comm);
24868 -       else
24869 -               cp = libertas_driver_version;
24870 -
24871 -       cnt = strlen(mrvl);
24872 -       cwrq += cnt;
24873 -       while (cnt < 16 && (*cp != '-')) {
24874 -               *cwrq++ = toupper(*cp++);
24875 -               cnt++;
24876 -       }
24877 -       *cwrq = '\0';
24878 +       /* We could add support for 802.11n here as needed. Jean II */
24879 +       snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g");
24880  
24881         lbs_deb_leave(LBS_DEB_WEXT);
24882         return 0;
24883  }
24884  
24885 -static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
24886 +static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
24887                          struct iw_freq *fwrq, char *extra)
24888  {
24889 -       wlan_private *priv = dev->priv;
24890 -       wlan_adapter *adapter = priv->adapter;
24891 +       struct lbs_private *priv = dev->priv;
24892         struct chan_freq_power *cfp;
24893  
24894         lbs_deb_enter(LBS_DEB_WEXT);
24895  
24896 -       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,
24897 -                                          adapter->curbssparams.channel);
24898 +       cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
24899 +                                          priv->curbssparams.channel);
24900  
24901         if (!cfp) {
24902 -               if (adapter->curbssparams.channel)
24903 +               if (priv->curbssparams.channel)
24904                         lbs_deb_wext("invalid channel %d\n",
24905 -                              adapter->curbssparams.channel);
24906 +                              priv->curbssparams.channel);
24907                 return -EINVAL;
24908         }
24909  
24910 @@ -297,16 +206,15 @@ static int wlan_get_freq(struct net_devi
24911         return 0;
24912  }
24913  
24914 -static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
24915 +static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
24916                         struct sockaddr *awrq, char *extra)
24917  {
24918 -       wlan_private *priv = dev->priv;
24919 -       wlan_adapter *adapter = priv->adapter;
24920 +       struct lbs_private *priv = dev->priv;
24921  
24922         lbs_deb_enter(LBS_DEB_WEXT);
24923  
24924 -       if (adapter->connect_status == libertas_connected) {
24925 -               memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);
24926 +       if (priv->connect_status == LBS_CONNECTED) {
24927 +               memcpy(awrq->sa_data, priv->curbssparams.bssid, ETH_ALEN);
24928         } else {
24929                 memset(awrq->sa_data, 0, ETH_ALEN);
24930         }
24931 @@ -316,11 +224,10 @@ static int wlan_get_wap(struct net_devic
24932         return 0;
24933  }
24934  
24935 -static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
24936 +static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
24937                          struct iw_point *dwrq, char *extra)
24938  {
24939 -       wlan_private *priv = dev->priv;
24940 -       wlan_adapter *adapter = priv->adapter;
24941 +       struct lbs_private *priv = dev->priv;
24942  
24943         lbs_deb_enter(LBS_DEB_WEXT);
24944  
24945 @@ -332,41 +239,27 @@ static int wlan_set_nick(struct net_devi
24946                 return -E2BIG;
24947         }
24948  
24949 -       mutex_lock(&adapter->lock);
24950 -       memset(adapter->nodename, 0, sizeof(adapter->nodename));
24951 -       memcpy(adapter->nodename, extra, dwrq->length);
24952 -       mutex_unlock(&adapter->lock);
24953 +       mutex_lock(&priv->lock);
24954 +       memset(priv->nodename, 0, sizeof(priv->nodename));
24955 +       memcpy(priv->nodename, extra, dwrq->length);
24956 +       mutex_unlock(&priv->lock);
24957  
24958         lbs_deb_leave(LBS_DEB_WEXT);
24959         return 0;
24960  }
24961  
24962 -static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
24963 +static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
24964                          struct iw_point *dwrq, char *extra)
24965  {
24966 -       wlan_private *priv = dev->priv;
24967 -       wlan_adapter *adapter = priv->adapter;
24968 +       struct lbs_private *priv = dev->priv;
24969  
24970         lbs_deb_enter(LBS_DEB_WEXT);
24971  
24972 -       /*
24973 -        * Get the Nick Name saved
24974 -        */
24975 -
24976 -       mutex_lock(&adapter->lock);
24977 -       strncpy(extra, adapter->nodename, 16);
24978 -       mutex_unlock(&adapter->lock);
24979 -
24980 -       extra[16] = '\0';
24981 -
24982 -       /*
24983 -        * If none, we may want to get the one that was set
24984 -        */
24985 +       dwrq->length = strlen(priv->nodename);
24986 +       memcpy(extra, priv->nodename, dwrq->length);
24987 +       extra[dwrq->length] = '\0';
24988  
24989 -       /*
24990 -        * Push it out !
24991 -        */
24992 -       dwrq->length = strlen(extra) + 1;
24993 +       dwrq->flags = 1;        /* active */
24994  
24995         lbs_deb_leave(LBS_DEB_WEXT);
24996         return 0;
24997 @@ -375,70 +268,68 @@ static int wlan_get_nick(struct net_devi
24998  static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
24999                          struct iw_point *dwrq, char *extra)
25000  {
25001 -       wlan_private *priv = dev->priv;
25002 -       wlan_adapter *adapter = priv->adapter;
25003 +       struct lbs_private *priv = dev->priv;
25004  
25005         lbs_deb_enter(LBS_DEB_WEXT);
25006  
25007         /* Use nickname to indicate that mesh is on */
25008  
25009 -       if (adapter->connect_status == libertas_connected) {
25010 +       if (priv->mesh_connect_status == LBS_CONNECTED) {
25011                 strncpy(extra, "Mesh", 12);
25012                 extra[12] = '\0';
25013 -               dwrq->length = strlen(extra) + 1;
25014 +               dwrq->length = strlen(extra);
25015         }
25016  
25017         else {
25018                 extra[0] = '\0';
25019 -               dwrq->length = 1 ;
25020 +               dwrq->length = 0;
25021         }
25022  
25023         lbs_deb_leave(LBS_DEB_WEXT);
25024         return 0;
25025  }
25026 -static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
25027 +
25028 +static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
25029                         struct iw_param *vwrq, char *extra)
25030  {
25031         int ret = 0;
25032 -       wlan_private *priv = dev->priv;
25033 -       wlan_adapter *adapter = priv->adapter;
25034 +       struct lbs_private *priv = dev->priv;
25035         u32 rthr = vwrq->value;
25036  
25037         lbs_deb_enter(LBS_DEB_WEXT);
25038  
25039         if (vwrq->disabled) {
25040 -               adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
25041 +               priv->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
25042         } else {
25043                 if (rthr < MRVDRV_RTS_MIN_VALUE || rthr > MRVDRV_RTS_MAX_VALUE)
25044                         return -EINVAL;
25045 -               adapter->rtsthsd = rthr;
25046 +               priv->rtsthsd = rthr;
25047         }
25048  
25049 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
25050 -                                   cmd_act_set, cmd_option_waitforrsp,
25051 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
25052 +                                   CMD_ACT_SET, CMD_OPTION_WAITFORRSP,
25053                                     OID_802_11_RTS_THRESHOLD, &rthr);
25054  
25055         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25056         return ret;
25057  }
25058  
25059 -static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,
25060 +static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
25061                         struct iw_param *vwrq, char *extra)
25062  {
25063         int ret = 0;
25064 -       wlan_private *priv = dev->priv;
25065 -       wlan_adapter *adapter = priv->adapter;
25066 +       struct lbs_private *priv = dev->priv;
25067  
25068         lbs_deb_enter(LBS_DEB_WEXT);
25069  
25070 -       adapter->rtsthsd = 0;
25071 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
25072 -                                   cmd_act_get, cmd_option_waitforrsp,
25073 +       priv->rtsthsd = 0;
25074 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
25075 +                                   CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
25076                                     OID_802_11_RTS_THRESHOLD, NULL);
25077         if (ret)
25078                 goto out;
25079  
25080 -       vwrq->value = adapter->rtsthsd;
25081 +       vwrq->value = priv->rtsthsd;
25082         vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)
25083                           || (vwrq->value > MRVDRV_RTS_MAX_VALUE));
25084         vwrq->fixed = 1;
25085 @@ -448,51 +339,49 @@ out:
25086         return ret;
25087  }
25088  
25089 -static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
25090 +static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
25091                          struct iw_param *vwrq, char *extra)
25092  {
25093         int ret = 0;
25094         u32 fthr = vwrq->value;
25095 -       wlan_private *priv = dev->priv;
25096 -       wlan_adapter *adapter = priv->adapter;
25097 +       struct lbs_private *priv = dev->priv;
25098  
25099         lbs_deb_enter(LBS_DEB_WEXT);
25100  
25101         if (vwrq->disabled) {
25102 -               adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
25103 +               priv->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
25104         } else {
25105                 if (fthr < MRVDRV_FRAG_MIN_VALUE
25106                     || fthr > MRVDRV_FRAG_MAX_VALUE)
25107                         return -EINVAL;
25108 -               adapter->fragthsd = fthr;
25109 +               priv->fragthsd = fthr;
25110         }
25111  
25112 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
25113 -                                   cmd_act_set, cmd_option_waitforrsp,
25114 +       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
25115 +                                   CMD_ACT_SET, CMD_OPTION_WAITFORRSP,
25116                                     OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);
25117  
25118         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25119         return ret;
25120  }
25121  
25122 -static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,
25123 +static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
25124                          struct iw_param *vwrq, char *extra)
25125  {
25126         int ret = 0;
25127 -       wlan_private *priv = dev->priv;
25128 -       wlan_adapter *adapter = priv->adapter;
25129 +       struct lbs_private *priv = dev->priv;
25130  
25131         lbs_deb_enter(LBS_DEB_WEXT);
25132  
25133 -       adapter->fragthsd = 0;
25134 -       ret = libertas_prepare_and_send_command(priv,
25135 -                                   cmd_802_11_snmp_mib,
25136 -                                   cmd_act_get, cmd_option_waitforrsp,
25137 +       priv->fragthsd = 0;
25138 +       ret = lbs_prepare_and_send_command(priv,
25139 +                                   CMD_802_11_SNMP_MIB,
25140 +                                   CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
25141                                     OID_802_11_FRAGMENTATION_THRESHOLD, NULL);
25142         if (ret)
25143                 goto out;
25144  
25145 -       vwrq->value = adapter->fragthsd;
25146 +       vwrq->value = priv->fragthsd;
25147         vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)
25148                           || (vwrq->value > MRVDRV_FRAG_MAX_VALUE));
25149         vwrq->fixed = 1;
25150 @@ -502,15 +391,14 @@ out:
25151         return ret;
25152  }
25153  
25154 -static int wlan_get_mode(struct net_device *dev,
25155 +static int lbs_get_mode(struct net_device *dev,
25156                          struct iw_request_info *info, u32 * uwrq, char *extra)
25157  {
25158 -       wlan_private *priv = dev->priv;
25159 -       wlan_adapter *adapter = priv->adapter;
25160 +       struct lbs_private *priv = dev->priv;
25161  
25162         lbs_deb_enter(LBS_DEB_WEXT);
25163  
25164 -       *uwrq = adapter->mode;
25165 +       *uwrq = priv->mode;
25166  
25167         lbs_deb_leave(LBS_DEB_WEXT);
25168         return 0;
25169 @@ -528,28 +416,27 @@ static int mesh_wlan_get_mode(struct net
25170         return 0;
25171  }
25172  
25173 -static int wlan_get_txpow(struct net_device *dev,
25174 +static int lbs_get_txpow(struct net_device *dev,
25175                           struct iw_request_info *info,
25176                           struct iw_param *vwrq, char *extra)
25177  {
25178         int ret = 0;
25179 -       wlan_private *priv = dev->priv;
25180 -       wlan_adapter *adapter = priv->adapter;
25181 +       struct lbs_private *priv = dev->priv;
25182  
25183         lbs_deb_enter(LBS_DEB_WEXT);
25184  
25185 -       ret = libertas_prepare_and_send_command(priv,
25186 -                                   cmd_802_11_rf_tx_power,
25187 -                                   cmd_act_tx_power_opt_get,
25188 -                                   cmd_option_waitforrsp, 0, NULL);
25189 +       ret = lbs_prepare_and_send_command(priv,
25190 +                                   CMD_802_11_RF_TX_POWER,
25191 +                                   CMD_ACT_TX_POWER_OPT_GET,
25192 +                                   CMD_OPTION_WAITFORRSP, 0, NULL);
25193  
25194         if (ret)
25195                 goto out;
25196  
25197 -       lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel);
25198 -       vwrq->value = adapter->txpowerlevel;
25199 +       lbs_deb_wext("tx power level %d dbm\n", priv->txpowerlevel);
25200 +       vwrq->value = priv->txpowerlevel;
25201         vwrq->fixed = 1;
25202 -       if (adapter->radioon) {
25203 +       if (priv->radioon) {
25204                 vwrq->disabled = 0;
25205                 vwrq->flags = IW_TXPOW_DBM;
25206         } else {
25207 @@ -561,12 +448,11 @@ out:
25208         return ret;
25209  }
25210  
25211 -static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
25212 +static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
25213                           struct iw_param *vwrq, char *extra)
25214  {
25215         int ret = 0;
25216 -       wlan_private *priv = dev->priv;
25217 -       wlan_adapter *adapter = priv->adapter;
25218 +       struct lbs_private *priv = dev->priv;
25219  
25220         lbs_deb_enter(LBS_DEB_WEXT);
25221  
25222 @@ -579,11 +465,11 @@ static int wlan_set_retry(struct net_dev
25223                         return -EINVAL;
25224  
25225                 /* Adding 1 to convert retry count to try count */
25226 -               adapter->txretrycount = vwrq->value + 1;
25227 +               priv->txretrycount = vwrq->value + 1;
25228  
25229 -               ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
25230 -                                           cmd_act_set,
25231 -                                           cmd_option_waitforrsp,
25232 +               ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
25233 +                                           CMD_ACT_SET,
25234 +                                           CMD_OPTION_WAITFORRSP,
25235                                             OID_802_11_TX_RETRYCOUNT, NULL);
25236  
25237                 if (ret)
25238 @@ -597,19 +483,18 @@ out:
25239         return ret;
25240  }
25241  
25242 -static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
25243 +static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
25244                           struct iw_param *vwrq, char *extra)
25245  {
25246 -       wlan_private *priv = dev->priv;
25247 -       wlan_adapter *adapter = priv->adapter;
25248 +       struct lbs_private *priv = dev->priv;
25249         int ret = 0;
25250  
25251         lbs_deb_enter(LBS_DEB_WEXT);
25252  
25253 -       adapter->txretrycount = 0;
25254 -       ret = libertas_prepare_and_send_command(priv,
25255 -                                   cmd_802_11_snmp_mib,
25256 -                                   cmd_act_get, cmd_option_waitforrsp,
25257 +       priv->txretrycount = 0;
25258 +       ret = lbs_prepare_and_send_command(priv,
25259 +                                   CMD_802_11_SNMP_MIB,
25260 +                                   CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
25261                                     OID_802_11_TX_RETRYCOUNT, NULL);
25262         if (ret)
25263                 goto out;
25264 @@ -618,7 +503,7 @@ static int wlan_get_retry(struct net_dev
25265         if (!vwrq->flags) {
25266                 vwrq->flags = IW_RETRY_LIMIT;
25267                 /* Subtract 1 to convert try count to retry count */
25268 -               vwrq->value = adapter->txretrycount - 1;
25269 +               vwrq->value = priv->txretrycount - 1;
25270         }
25271  
25272  out:
25273 @@ -665,15 +550,14 @@ static inline void sort_channels(struct 
25274   *  @param extra               A pointer to extra data buf
25275   *  @return                    0 --success, otherwise fail
25276   */
25277 -static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
25278 +static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
25279                           struct iw_point *dwrq, char *extra)
25280  {
25281         int i, j;
25282 -       wlan_private *priv = dev->priv;
25283 -       wlan_adapter *adapter = priv->adapter;
25284 +       struct lbs_private *priv = dev->priv;
25285         struct iw_range *range = (struct iw_range *)extra;
25286         struct chan_freq_power *cfp;
25287 -       u8 rates[WLAN_SUPPORTED_RATES];
25288 +       u8 rates[MAX_RATES + 1];
25289  
25290         u8 flag = 0;
25291  
25292 @@ -686,24 +570,23 @@ static int wlan_get_range(struct net_dev
25293         range->max_nwid = 0;
25294  
25295         memset(rates, 0, sizeof(rates));
25296 -       range->num_bitrates = get_active_data_rates(adapter, rates);
25297 -
25298 -       for (i = 0; i < min_t(__u8, range->num_bitrates, IW_MAX_BITRATES) && rates[i];
25299 -            i++) {
25300 -               range->bitrate[i] = (rates[i] & 0x7f) * 500000;
25301 -       }
25302 +       copy_active_data_rates(priv, rates);
25303 +       range->num_bitrates = strnlen(rates, IW_MAX_BITRATES);
25304 +       for (i = 0; i < range->num_bitrates; i++)
25305 +               range->bitrate[i] = rates[i] * 500000;
25306         range->num_bitrates = i;
25307         lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,
25308                range->num_bitrates);
25309  
25310         range->num_frequency = 0;
25311 -       if (priv->adapter->enable11d &&
25312 -           adapter->connect_status == libertas_connected) {
25313 +       if (priv->enable11d &&
25314 +           (priv->connect_status == LBS_CONNECTED ||
25315 +           priv->mesh_connect_status == LBS_CONNECTED)) {
25316                 u8 chan_no;
25317                 u8 band;
25318  
25319                 struct parsed_region_chan_11d *parsed_region_chan =
25320 -                   &adapter->parsed_region_chan;
25321 +                   &priv->parsed_region_chan;
25322  
25323                 if (parsed_region_chan == NULL) {
25324                         lbs_deb_wext("11d: parsed_region_chan is NULL\n");
25325 @@ -719,7 +602,7 @@ static int wlan_get_range(struct net_dev
25326                         lbs_deb_wext("chan_no %d\n", chan_no);
25327                         range->freq[range->num_frequency].i = (long)chan_no;
25328                         range->freq[range->num_frequency].m =
25329 -                           (long)libertas_chan_2_freq(chan_no, band) * 100000;
25330 +                           (long)lbs_chan_2_freq(chan_no, band) * 100000;
25331                         range->freq[range->num_frequency].e = 1;
25332                         range->num_frequency++;
25333                 }
25334 @@ -727,13 +610,12 @@ static int wlan_get_range(struct net_dev
25335         }
25336         if (!flag) {
25337                 for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
25338 -                    && (j < sizeof(adapter->region_channel)
25339 -                        / sizeof(adapter->region_channel[0])); j++) {
25340 -                       cfp = adapter->region_channel[j].CFP;
25341 +                    && (j < ARRAY_SIZE(priv->region_channel)); j++) {
25342 +                       cfp = priv->region_channel[j].CFP;
25343                         for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
25344 -                            && adapter->region_channel[j].valid
25345 +                            && priv->region_channel[j].valid
25346                              && cfp
25347 -                            && (i < adapter->region_channel[j].nrcfp); i++) {
25348 +                            && (i < priv->region_channel[j].nrcfp); i++) {
25349                                 range->freq[range->num_frequency].i =
25350                                     (long)cfp->channel;
25351                                 range->freq[range->num_frequency].m =
25352 @@ -833,7 +715,7 @@ static int wlan_get_range(struct net_dev
25353                                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
25354         range->event_capa[1] = IW_EVENT_CAPA_K_1;
25355  
25356 -       if (adapter->fwcapinfo & FW_CAPINFO_WPA) {
25357 +       if (priv->fwcapinfo & FW_CAPINFO_WPA) {
25358                 range->enc_capa =   IW_ENC_CAPA_WPA
25359                                   | IW_ENC_CAPA_WPA2
25360                                   | IW_ENC_CAPA_CIPHER_TKIP
25361 @@ -845,22 +727,28 @@ out:
25362         return 0;
25363  }
25364  
25365 -static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
25366 +static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
25367                           struct iw_param *vwrq, char *extra)
25368  {
25369 -       wlan_private *priv = dev->priv;
25370 -       wlan_adapter *adapter = priv->adapter;
25371 +       struct lbs_private *priv = dev->priv;
25372  
25373         lbs_deb_enter(LBS_DEB_WEXT);
25374  
25375 +       if (!priv->ps_supported) {
25376 +               if (vwrq->disabled)
25377 +                       return 0;
25378 +               else
25379 +                       return -EINVAL;
25380 +       }
25381 +
25382         /* PS is currently supported only in Infrastructure mode
25383          * Remove this check if it is to be supported in IBSS mode also
25384          */
25385  
25386         if (vwrq->disabled) {
25387 -               adapter->psmode = wlan802_11powermodecam;
25388 -               if (adapter->psstate != PS_STATE_FULL_POWER) {
25389 -                       libertas_ps_wakeup(priv, cmd_option_waitforrsp);
25390 +               priv->psmode = LBS802_11POWERMODECAM;
25391 +               if (priv->psstate != PS_STATE_FULL_POWER) {
25392 +                       lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
25393                 }
25394  
25395                 return 0;
25396 @@ -875,33 +763,32 @@ static int wlan_set_power(struct net_dev
25397                 return -EINVAL;
25398         }
25399  
25400 -       if (adapter->psmode != wlan802_11powermodecam) {
25401 +       if (priv->psmode != LBS802_11POWERMODECAM) {
25402                 return 0;
25403         }
25404  
25405 -       adapter->psmode = wlan802_11powermodemax_psp;
25406 +       priv->psmode = LBS802_11POWERMODEMAX_PSP;
25407  
25408 -       if (adapter->connect_status == libertas_connected) {
25409 -               libertas_ps_sleep(priv, cmd_option_waitforrsp);
25410 +       if (priv->connect_status == LBS_CONNECTED) {
25411 +               lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP);
25412         }
25413  
25414         lbs_deb_leave(LBS_DEB_WEXT);
25415         return 0;
25416  }
25417  
25418 -static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,
25419 +static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
25420                           struct iw_param *vwrq, char *extra)
25421  {
25422 -       wlan_private *priv = dev->priv;
25423 -       wlan_adapter *adapter = priv->adapter;
25424 +       struct lbs_private *priv = dev->priv;
25425         int mode;
25426  
25427         lbs_deb_enter(LBS_DEB_WEXT);
25428  
25429 -       mode = adapter->psmode;
25430 +       mode = priv->psmode;
25431  
25432 -       if ((vwrq->disabled = (mode == wlan802_11powermodecam))
25433 -           || adapter->connect_status == libertas_disconnected)
25434 +       if ((vwrq->disabled = (mode == LBS802_11POWERMODECAM))
25435 +           || priv->connect_status == LBS_DISCONNECTED)
25436         {
25437                 goto out;
25438         }
25439 @@ -913,7 +800,7 @@ out:
25440         return 0;
25441  }
25442  
25443 -static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
25444 +static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
25445  {
25446         enum {
25447                 POOR = 30,
25448 @@ -923,8 +810,7 @@ static struct iw_statistics *wlan_get_wi
25449                 EXCELLENT = 95,
25450                 PERFECT = 100
25451         };
25452 -       wlan_private *priv = dev->priv;
25453 -       wlan_adapter *adapter = priv->adapter;
25454 +       struct lbs_private *priv = dev->priv;
25455         u32 rssi_qual;
25456         u32 tx_qual;
25457         u32 quality = 0;
25458 @@ -934,22 +820,23 @@ static struct iw_statistics *wlan_get_wi
25459  
25460         lbs_deb_enter(LBS_DEB_WEXT);
25461  
25462 -       priv->wstats.status = adapter->mode;
25463 +       priv->wstats.status = priv->mode;
25464  
25465         /* If we're not associated, all quality values are meaningless */
25466 -       if (adapter->connect_status != libertas_connected)
25467 +       if ((priv->connect_status != LBS_CONNECTED) &&
25468 +           (priv->mesh_connect_status != LBS_CONNECTED))
25469                 goto out;
25470  
25471         /* Quality by RSSI */
25472         priv->wstats.qual.level =
25473 -           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
25474 -            adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
25475 +           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
25476 +            priv->NF[TYPE_BEACON][TYPE_NOAVG]);
25477  
25478 -       if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
25479 +       if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
25480                 priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
25481         } else {
25482                 priv->wstats.qual.noise =
25483 -                   CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
25484 +                   CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
25485         }
25486  
25487         lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
25488 @@ -973,7 +860,7 @@ static struct iw_statistics *wlan_get_wi
25489         /* Quality by TX errors */
25490         priv->wstats.discard.retries = priv->stats.tx_errors;
25491  
25492 -       tx_retries = le32_to_cpu(adapter->logmsg.retry);
25493 +       tx_retries = le32_to_cpu(priv->logmsg.retry);
25494  
25495         if (tx_retries > 75)
25496                 tx_qual = (90 - tx_retries) * POOR / 15;
25497 @@ -989,20 +876,20 @@ static struct iw_statistics *wlan_get_wi
25498                     (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
25499         quality = min(quality, tx_qual);
25500  
25501 -       priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable);
25502 -       priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag);
25503 +       priv->wstats.discard.code = le32_to_cpu(priv->logmsg.wepundecryptable);
25504 +       priv->wstats.discard.fragment = le32_to_cpu(priv->logmsg.rxfrag);
25505         priv->wstats.discard.retries = tx_retries;
25506 -       priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure);
25507 +       priv->wstats.discard.misc = le32_to_cpu(priv->logmsg.ackfailure);
25508  
25509         /* Calculate quality */
25510 -       priv->wstats.qual.qual = max(quality, (u32)100);
25511 +       priv->wstats.qual.qual = min_t(u8, quality, 100);
25512         priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
25513         stats_valid = 1;
25514  
25515         /* update stats asynchronously for future calls */
25516 -       libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
25517 +       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
25518                                         0, 0, NULL);
25519 -       libertas_prepare_and_send_command(priv, cmd_802_11_get_log, 0,
25520 +       lbs_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0,
25521                                         0, 0, NULL);
25522  out:
25523         if (!stats_valid) {
25524 @@ -1022,19 +909,18 @@ out:
25525  
25526  }
25527  
25528 -static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
25529 +static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
25530                   struct iw_freq *fwrq, char *extra)
25531  {
25532         int ret = -EINVAL;
25533 -       wlan_private *priv = dev->priv;
25534 -       wlan_adapter *adapter = priv->adapter;
25535 +       struct lbs_private *priv = dev->priv;
25536         struct chan_freq_power *cfp;
25537         struct assoc_request * assoc_req;
25538  
25539         lbs_deb_enter(LBS_DEB_WEXT);
25540  
25541 -       mutex_lock(&adapter->lock);
25542 -       assoc_req = wlan_get_association_request(adapter);
25543 +       mutex_lock(&priv->lock);
25544 +       assoc_req = lbs_get_association_request(priv);
25545         if (!assoc_req) {
25546                 ret = -ENOMEM;
25547                 goto out;
25548 @@ -1044,7 +930,7 @@ static int wlan_set_freq(struct net_devi
25549         if (fwrq->e == 1) {
25550                 long f = fwrq->m / 100000;
25551  
25552 -               cfp = find_cfp_by_band_and_freq(adapter, 0, f);
25553 +               cfp = find_cfp_by_band_and_freq(priv, 0, f);
25554                 if (!cfp) {
25555                         lbs_deb_wext("invalid freq %ld\n", f);
25556                         goto out;
25557 @@ -1059,7 +945,7 @@ static int wlan_set_freq(struct net_devi
25558                 goto out;
25559         }
25560  
25561 -       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
25562 +       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
25563         if (!cfp) {
25564                 goto out;
25565         }
25566 @@ -1070,128 +956,134 @@ static int wlan_set_freq(struct net_devi
25567  out:
25568         if (ret == 0) {
25569                 set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
25570 -               wlan_postpone_association_work(priv);
25571 +               lbs_postpone_association_work(priv);
25572         } else {
25573 -               wlan_cancel_association_work(priv);
25574 +               lbs_cancel_association_work(priv);
25575         }
25576 -       mutex_unlock(&adapter->lock);
25577 +       mutex_unlock(&priv->lock);
25578  
25579         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25580         return ret;
25581  }
25582  
25583 -/**
25584 - *  @brief use index to get the data rate
25585 - *
25586 - *  @param index                The index of data rate
25587 - *  @return                    data rate or 0
25588 - */
25589 -u32 libertas_index_to_data_rate(u8 index)
25590 +static int lbs_mesh_set_freq(struct net_device *dev,
25591 +                            struct iw_request_info *info,
25592 +                            struct iw_freq *fwrq, char *extra)
25593  {
25594 -       if (index >= sizeof(libertas_wlan_data_rates))
25595 -               index = 0;
25596 +       struct lbs_private *priv = dev->priv;
25597 +       struct chan_freq_power *cfp;
25598 +       int ret = -EINVAL;
25599  
25600 -       return libertas_wlan_data_rates[index];
25601 -}
25602 +       lbs_deb_enter(LBS_DEB_WEXT);
25603  
25604 -/**
25605 - *  @brief use rate to get the index
25606 - *
25607 - *  @param rate                 data rate
25608 - *  @return                    index or 0
25609 - */
25610 -u8 libertas_data_rate_to_index(u32 rate)
25611 -{
25612 -       u8 *ptr;
25613 +       /* If setting by frequency, convert to a channel */
25614 +       if (fwrq->e == 1) {
25615 +               long f = fwrq->m / 100000;
25616 +
25617 +               cfp = find_cfp_by_band_and_freq(priv, 0, f);
25618 +               if (!cfp) {
25619 +                       lbs_deb_wext("invalid freq %ld\n", f);
25620 +                       goto out;
25621 +               }
25622  
25623 -       if (rate)
25624 -               if ((ptr = memchr(libertas_wlan_data_rates, (u8) rate,
25625 -                                 sizeof(libertas_wlan_data_rates))))
25626 -                       return (ptr - libertas_wlan_data_rates);
25627 +               fwrq->e = 0;
25628 +               fwrq->m = (int) cfp->channel;
25629 +       }
25630  
25631 -       return 0;
25632 +       /* Setting by channel number */
25633 +       if (fwrq->m > 1000 || fwrq->e > 0) {
25634 +               goto out;
25635 +       }
25636 +
25637 +       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
25638 +       if (!cfp) {
25639 +               goto out;
25640 +       }
25641 +
25642 +       if (fwrq->m != priv->curbssparams.channel) {
25643 +               lbs_deb_wext("mesh channel change forces eth disconnect\n");
25644 +               if (priv->mode == IW_MODE_INFRA)
25645 +                       lbs_send_deauthentication(priv);
25646 +               else if (priv->mode == IW_MODE_ADHOC)
25647 +                       lbs_stop_adhoc_network(priv);
25648 +       }
25649 +       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
25650 +       lbs_update_channel(priv);
25651 +       ret = 0;
25652 +
25653 +out:
25654 +       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25655 +       return ret;
25656  }
25657  
25658 -static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
25659 +static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
25660                   struct iw_param *vwrq, char *extra)
25661  {
25662 -       wlan_private *priv = dev->priv;
25663 -       wlan_adapter *adapter = priv->adapter;
25664 -       u32 data_rate;
25665 -       u16 action;
25666 -       int ret = 0;
25667 -       u8 rates[WLAN_SUPPORTED_RATES];
25668 -       u8 *rate;
25669 +       struct lbs_private *priv = dev->priv;
25670 +       u8 new_rate = 0;
25671 +       int ret = -EINVAL;
25672 +       u8 rates[MAX_RATES + 1];
25673  
25674         lbs_deb_enter(LBS_DEB_WEXT);
25675 -
25676         lbs_deb_wext("vwrq->value %d\n", vwrq->value);
25677  
25678 +       /* Auto rate? */
25679         if (vwrq->value == -1) {
25680 -               action = cmd_act_set_tx_auto;   // Auto
25681 -               adapter->is_datarate_auto = 1;
25682 -               adapter->datarate = 0;
25683 +               priv->auto_rate = 1;
25684 +               priv->cur_rate = 0;
25685         } else {
25686 -               if (vwrq->value % 100000) {
25687 -                       return -EINVAL;
25688 -               }
25689 -
25690 -               data_rate = vwrq->value / 500000;
25691 +               if (vwrq->value % 100000)
25692 +                       goto out;
25693  
25694                 memset(rates, 0, sizeof(rates));
25695 -               get_active_data_rates(adapter, rates);
25696 -               rate = rates;
25697 -               while (*rate) {
25698 -                       lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate,
25699 -                              data_rate);
25700 -                       if ((*rate & 0x7f) == (data_rate & 0x7f))
25701 -                               break;
25702 -                       rate++;
25703 -               }
25704 -               if (!*rate) {
25705 -                       lbs_pr_alert("fixed data rate 0x%X out "
25706 -                              "of range\n", data_rate);
25707 -                       return -EINVAL;
25708 +               copy_active_data_rates(priv, rates);
25709 +               new_rate = vwrq->value / 500000;
25710 +               if (!memchr(rates, new_rate, sizeof(rates))) {
25711 +                       lbs_pr_alert("fixed data rate 0x%X out of range\n",
25712 +                               new_rate);
25713 +                       goto out;
25714                 }
25715  
25716 -               adapter->datarate = data_rate;
25717 -               action = cmd_act_set_tx_fix_rate;
25718 -               adapter->is_datarate_auto = 0;
25719 +               priv->cur_rate = new_rate;
25720 +               priv->auto_rate = 0;
25721         }
25722  
25723 -       ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
25724 -                                   action, cmd_option_waitforrsp, 0, NULL);
25725 +       ret = lbs_set_data_rate(priv, new_rate);
25726  
25727 +out:
25728         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25729         return ret;
25730  }
25731  
25732 -static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
25733 +static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
25734                   struct iw_param *vwrq, char *extra)
25735  {
25736 -       wlan_private *priv = dev->priv;
25737 -       wlan_adapter *adapter = priv->adapter;
25738 +       struct lbs_private *priv = dev->priv;
25739  
25740         lbs_deb_enter(LBS_DEB_WEXT);
25741  
25742 -       if (adapter->is_datarate_auto) {
25743 -               vwrq->fixed = 0;
25744 +       if (priv->connect_status == LBS_CONNECTED) {
25745 +               vwrq->value = priv->cur_rate * 500000;
25746 +
25747 +               if (priv->auto_rate)
25748 +                       vwrq->fixed = 0;
25749 +               else
25750 +                       vwrq->fixed = 1;
25751 +
25752         } else {
25753 -               vwrq->fixed = 1;
25754 +               vwrq->fixed = 0;
25755 +               vwrq->value = 0;
25756         }
25757  
25758 -       vwrq->value = adapter->datarate * 500000;
25759 -
25760         lbs_deb_leave(LBS_DEB_WEXT);
25761         return 0;
25762  }
25763  
25764 -static int wlan_set_mode(struct net_device *dev,
25765 +static int lbs_set_mode(struct net_device *dev,
25766                   struct iw_request_info *info, u32 * uwrq, char *extra)
25767  {
25768         int ret = 0;
25769 -       wlan_private *priv = dev->priv;
25770 -       wlan_adapter *adapter = priv->adapter;
25771 +       struct lbs_private *priv = dev->priv;
25772         struct assoc_request * assoc_req;
25773  
25774         lbs_deb_enter(LBS_DEB_WEXT);
25775 @@ -1204,18 +1096,18 @@ static int wlan_set_mode(struct net_devi
25776                 goto out;
25777         }
25778  
25779 -       mutex_lock(&adapter->lock);
25780 -       assoc_req = wlan_get_association_request(adapter);
25781 +       mutex_lock(&priv->lock);
25782 +       assoc_req = lbs_get_association_request(priv);
25783         if (!assoc_req) {
25784                 ret = -ENOMEM;
25785 -               wlan_cancel_association_work(priv);
25786 +               lbs_cancel_association_work(priv);
25787         } else {
25788                 assoc_req->mode = *uwrq;
25789                 set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
25790 -               wlan_postpone_association_work(priv);
25791 +               lbs_postpone_association_work(priv);
25792                 lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
25793         }
25794 -       mutex_unlock(&adapter->lock);
25795 +       mutex_unlock(&priv->lock);
25796  
25797  out:
25798         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25799 @@ -1232,23 +1124,22 @@ out:
25800   *  @param extra               A pointer to extra data buf
25801   *  @return                    0 --success, otherwise fail
25802   */
25803 -static int wlan_get_encode(struct net_device *dev,
25804 +static int lbs_get_encode(struct net_device *dev,
25805                            struct iw_request_info *info,
25806                            struct iw_point *dwrq, u8 * extra)
25807  {
25808 -       wlan_private *priv = dev->priv;
25809 -       wlan_adapter *adapter = priv->adapter;
25810 +       struct lbs_private *priv = dev->priv;
25811         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
25812  
25813         lbs_deb_enter(LBS_DEB_WEXT);
25814  
25815         lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n",
25816 -              dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx);
25817 +              dwrq->flags, index, dwrq->length, priv->wep_tx_keyidx);
25818  
25819         dwrq->flags = 0;
25820  
25821         /* Authentication method */
25822 -       switch (adapter->secinfo.auth_mode) {
25823 +       switch (priv->secinfo.auth_mode) {
25824         case IW_AUTH_ALG_OPEN_SYSTEM:
25825                 dwrq->flags = IW_ENCODE_OPEN;
25826                 break;
25827 @@ -1262,43 +1153,34 @@ static int wlan_get_encode(struct net_de
25828                 break;
25829         }
25830  
25831 -       if (   adapter->secinfo.wep_enabled
25832 -           || adapter->secinfo.WPAenabled
25833 -           || adapter->secinfo.WPA2enabled) {
25834 -               dwrq->flags &= ~IW_ENCODE_DISABLED;
25835 -       } else {
25836 -               dwrq->flags |= IW_ENCODE_DISABLED;
25837 -       }
25838 -
25839         memset(extra, 0, 16);
25840  
25841 -       mutex_lock(&adapter->lock);
25842 +       mutex_lock(&priv->lock);
25843  
25844         /* Default to returning current transmit key */
25845         if (index < 0)
25846 -               index = adapter->wep_tx_keyidx;
25847 +               index = priv->wep_tx_keyidx;
25848  
25849 -       if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) {
25850 -               memcpy(extra, adapter->wep_keys[index].key,
25851 -                      adapter->wep_keys[index].len);
25852 -               dwrq->length = adapter->wep_keys[index].len;
25853 +       if ((priv->wep_keys[index].len) && priv->secinfo.wep_enabled) {
25854 +               memcpy(extra, priv->wep_keys[index].key,
25855 +                      priv->wep_keys[index].len);
25856 +               dwrq->length = priv->wep_keys[index].len;
25857  
25858                 dwrq->flags |= (index + 1);
25859                 /* Return WEP enabled */
25860                 dwrq->flags &= ~IW_ENCODE_DISABLED;
25861 -       } else if ((adapter->secinfo.WPAenabled)
25862 -                  || (adapter->secinfo.WPA2enabled)) {
25863 +       } else if ((priv->secinfo.WPAenabled)
25864 +                  || (priv->secinfo.WPA2enabled)) {
25865                 /* return WPA enabled */
25866                 dwrq->flags &= ~IW_ENCODE_DISABLED;
25867 +               dwrq->flags |= IW_ENCODE_NOKEY;
25868         } else {
25869                 dwrq->flags |= IW_ENCODE_DISABLED;
25870         }
25871  
25872 -       mutex_unlock(&adapter->lock);
25873 +       mutex_unlock(&priv->lock);
25874  
25875 -       dwrq->flags |= IW_ENCODE_NOKEY;
25876 -
25877 -       lbs_deb_wext("key: " MAC_FMT ", keylen %d\n",
25878 +       lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n",
25879                extra[0], extra[1], extra[2],
25880                extra[3], extra[4], extra[5], dwrq->length);
25881  
25882 @@ -1318,14 +1200,14 @@ static int wlan_get_encode(struct net_de
25883   *  @param set_tx_key          Force set TX key (1 = yes, 0 = no)
25884   *  @return                    0 --success, otherwise fail
25885   */
25886 -static int wlan_set_wep_key(struct assoc_request *assoc_req,
25887 +static int lbs_set_wep_key(struct assoc_request *assoc_req,
25888                             const char *key_material,
25889                             u16 key_length,
25890                             u16 index,
25891                             int set_tx_key)
25892  {
25893         int ret = 0;
25894 -       struct WLAN_802_11_KEY *pkey;
25895 +       struct enc_key *pkey;
25896  
25897         lbs_deb_enter(LBS_DEB_WEXT);
25898  
25899 @@ -1344,7 +1226,7 @@ static int wlan_set_wep_key(struct assoc
25900         pkey = &assoc_req->wep_keys[index];
25901  
25902         if (key_length > 0) {
25903 -               memset(pkey, 0, sizeof(struct WLAN_802_11_KEY));
25904 +               memset(pkey, 0, sizeof(struct enc_key));
25905                 pkey->type = KEY_TYPE_ID_WEP;
25906  
25907                 /* Standardize the key length */
25908 @@ -1412,11 +1294,11 @@ static void disable_wpa(struct assoc_req
25909  {
25910         lbs_deb_enter(LBS_DEB_WEXT);
25911  
25912 -       memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY));
25913 +       memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_key));
25914         assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
25915         set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
25916  
25917 -       memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY));
25918 +       memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key));
25919         assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
25920         set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
25921  
25922 @@ -1436,20 +1318,19 @@ static void disable_wpa(struct assoc_req
25923   *  @param extra               A pointer to extra data buf
25924   *  @return                    0 --success, otherwise fail
25925   */
25926 -static int wlan_set_encode(struct net_device *dev,
25927 +static int lbs_set_encode(struct net_device *dev,
25928                     struct iw_request_info *info,
25929                     struct iw_point *dwrq, char *extra)
25930  {
25931         int ret = 0;
25932 -       wlan_private *priv = dev->priv;
25933 -       wlan_adapter *adapter = priv->adapter;
25934 +       struct lbs_private *priv = dev->priv;
25935         struct assoc_request * assoc_req;
25936         u16 is_default = 0, index = 0, set_tx_key = 0;
25937  
25938         lbs_deb_enter(LBS_DEB_WEXT);
25939  
25940 -       mutex_lock(&adapter->lock);
25941 -       assoc_req = wlan_get_association_request(adapter);
25942 +       mutex_lock(&priv->lock);
25943 +       assoc_req = lbs_get_association_request(priv);
25944         if (!assoc_req) {
25945                 ret = -ENOMEM;
25946                 goto out;
25947 @@ -1475,7 +1356,7 @@ static int wlan_set_encode(struct net_de
25948         if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
25949                 set_tx_key = 1;
25950  
25951 -       ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
25952 +       ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
25953         if (ret)
25954                 goto out;
25955  
25956 @@ -1493,11 +1374,11 @@ static int wlan_set_encode(struct net_de
25957  out:
25958         if (ret == 0) {
25959                 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
25960 -               wlan_postpone_association_work(priv);
25961 +               lbs_postpone_association_work(priv);
25962         } else {
25963 -               wlan_cancel_association_work(priv);
25964 +               lbs_cancel_association_work(priv);
25965         }
25966 -       mutex_unlock(&adapter->lock);
25967 +       mutex_unlock(&priv->lock);
25968  
25969         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
25970         return ret;
25971 @@ -1512,14 +1393,13 @@ out:
25972   *  @param extra               A pointer to extra data buf
25973   *  @return                    0 on success, otherwise failure
25974   */
25975 -static int wlan_get_encodeext(struct net_device *dev,
25976 +static int lbs_get_encodeext(struct net_device *dev,
25977                               struct iw_request_info *info,
25978                               struct iw_point *dwrq,
25979                               char *extra)
25980  {
25981         int ret = -EINVAL;
25982 -       wlan_private *priv = dev->priv;
25983 -       wlan_adapter *adapter = priv->adapter;
25984 +       struct lbs_private *priv = dev->priv;
25985         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
25986         int index, max_key_len;
25987  
25988 @@ -1535,46 +1415,46 @@ static int wlan_get_encodeext(struct net
25989                         goto out;
25990                 index--;
25991         } else {
25992 -               index = adapter->wep_tx_keyidx;
25993 +               index = priv->wep_tx_keyidx;
25994         }
25995  
25996 -       if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
25997 +       if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
25998             ext->alg != IW_ENCODE_ALG_WEP) {
25999 -               if (index != 0 || adapter->mode != IW_MODE_INFRA)
26000 +               if (index != 0 || priv->mode != IW_MODE_INFRA)
26001                         goto out;
26002         }
26003  
26004         dwrq->flags = index + 1;
26005         memset(ext, 0, sizeof(*ext));
26006  
26007 -       if (   !adapter->secinfo.wep_enabled
26008 -           && !adapter->secinfo.WPAenabled
26009 -           && !adapter->secinfo.WPA2enabled) {
26010 +       if (   !priv->secinfo.wep_enabled
26011 +           && !priv->secinfo.WPAenabled
26012 +           && !priv->secinfo.WPA2enabled) {
26013                 ext->alg = IW_ENCODE_ALG_NONE;
26014                 ext->key_len = 0;
26015                 dwrq->flags |= IW_ENCODE_DISABLED;
26016         } else {
26017                 u8 *key = NULL;
26018  
26019 -               if (   adapter->secinfo.wep_enabled
26020 -                   && !adapter->secinfo.WPAenabled
26021 -                   && !adapter->secinfo.WPA2enabled) {
26022 +               if (   priv->secinfo.wep_enabled
26023 +                   && !priv->secinfo.WPAenabled
26024 +                   && !priv->secinfo.WPA2enabled) {
26025                         /* WEP */
26026                         ext->alg = IW_ENCODE_ALG_WEP;
26027 -                       ext->key_len = adapter->wep_keys[index].len;
26028 -                       key = &adapter->wep_keys[index].key[0];
26029 -               } else if (   !adapter->secinfo.wep_enabled
26030 -                          && (adapter->secinfo.WPAenabled ||
26031 -                              adapter->secinfo.WPA2enabled)) {
26032 +                       ext->key_len = priv->wep_keys[index].len;
26033 +                       key = &priv->wep_keys[index].key[0];
26034 +               } else if (   !priv->secinfo.wep_enabled
26035 +                          && (priv->secinfo.WPAenabled ||
26036 +                              priv->secinfo.WPA2enabled)) {
26037                         /* WPA */
26038 -                       struct WLAN_802_11_KEY * pkey = NULL;
26039 +                       struct enc_key * pkey = NULL;
26040  
26041 -                       if (   adapter->wpa_mcast_key.len
26042 -                           && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
26043 -                               pkey = &adapter->wpa_mcast_key;
26044 -                       else if (   adapter->wpa_unicast_key.len
26045 -                                && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
26046 -                               pkey = &adapter->wpa_unicast_key;
26047 +                       if (   priv->wpa_mcast_key.len
26048 +                           && (priv->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
26049 +                               pkey = &priv->wpa_mcast_key;
26050 +                       else if (   priv->wpa_unicast_key.len
26051 +                                && (priv->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
26052 +                               pkey = &priv->wpa_unicast_key;
26053  
26054                         if (pkey) {
26055                                 if (pkey->type == KEY_TYPE_ID_AES) {
26056 @@ -1619,22 +1499,21 @@ out:
26057   *  @param extra               A pointer to extra data buf
26058   *  @return                    0 --success, otherwise fail
26059   */
26060 -static int wlan_set_encodeext(struct net_device *dev,
26061 +static int lbs_set_encodeext(struct net_device *dev,
26062                               struct iw_request_info *info,
26063                               struct iw_point *dwrq,
26064                               char *extra)
26065  {
26066         int ret = 0;
26067 -       wlan_private *priv = dev->priv;
26068 -       wlan_adapter *adapter = priv->adapter;
26069 +       struct lbs_private *priv = dev->priv;
26070         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
26071         int alg = ext->alg;
26072         struct assoc_request * assoc_req;
26073  
26074         lbs_deb_enter(LBS_DEB_WEXT);
26075  
26076 -       mutex_lock(&adapter->lock);
26077 -       assoc_req = wlan_get_association_request(adapter);
26078 +       mutex_lock(&priv->lock);
26079 +       assoc_req = lbs_get_association_request(priv);
26080         if (!assoc_req) {
26081                 ret = -ENOMEM;
26082                 goto out;
26083 @@ -1661,7 +1540,7 @@ static int wlan_set_encodeext(struct net
26084                         set_tx_key = 1;
26085  
26086                 /* Copy key to driver */
26087 -               ret = wlan_set_wep_key (assoc_req, ext->key, ext->key_len, index,
26088 +               ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index,
26089                                         set_tx_key);
26090                 if (ret)
26091                         goto out;
26092 @@ -1679,14 +1558,14 @@ static int wlan_set_encodeext(struct net
26093                 if (set_tx_key)
26094                         set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
26095         } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
26096 -               struct WLAN_802_11_KEY * pkey;
26097 +               struct enc_key * pkey;
26098  
26099                 /* validate key length */
26100                 if (((alg == IW_ENCODE_ALG_TKIP)
26101                         && (ext->key_len != KEY_LEN_WPA_TKIP))
26102                     || ((alg == IW_ENCODE_ALG_CCMP)
26103                         && (ext->key_len != KEY_LEN_WPA_AES))) {
26104 -                               lbs_deb_wext("invalid size %d for key of alg"
26105 +                               lbs_deb_wext("invalid size %d for key of alg "
26106                                        "type %d\n",
26107                                        ext->key_len,
26108                                        alg);
26109 @@ -1702,7 +1581,7 @@ static int wlan_set_encodeext(struct net
26110                         set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
26111                 }
26112  
26113 -               memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
26114 +               memset(pkey, 0, sizeof (struct enc_key));
26115                 memcpy(pkey->key, ext->key, ext->key_len);
26116                 pkey->len = ext->key_len;
26117                 if (pkey->len)
26118 @@ -1719,9 +1598,6 @@ static int wlan_set_encodeext(struct net
26119                         pkey->type = KEY_TYPE_ID_TKIP;
26120                 } else if (alg == IW_ENCODE_ALG_CCMP) {
26121                         pkey->type = KEY_TYPE_ID_AES;
26122 -               } else {
26123 -                       ret = -EINVAL;
26124 -                       goto out;
26125                 }
26126  
26127                 /* If WPA isn't enabled yet, do that now */
26128 @@ -1737,31 +1613,30 @@ static int wlan_set_encodeext(struct net
26129  
26130  out:
26131         if (ret == 0) {
26132 -               wlan_postpone_association_work(priv);
26133 +               lbs_postpone_association_work(priv);
26134         } else {
26135 -               wlan_cancel_association_work(priv);
26136 +               lbs_cancel_association_work(priv);
26137         }
26138 -       mutex_unlock(&adapter->lock);
26139 +       mutex_unlock(&priv->lock);
26140  
26141         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26142         return ret;
26143  }
26144  
26145  
26146 -static int wlan_set_genie(struct net_device *dev,
26147 +static int lbs_set_genie(struct net_device *dev,
26148                           struct iw_request_info *info,
26149                           struct iw_point *dwrq,
26150                           char *extra)
26151  {
26152 -       wlan_private *priv = dev->priv;
26153 -       wlan_adapter *adapter = priv->adapter;
26154 +       struct lbs_private *priv = dev->priv;
26155         int ret = 0;
26156         struct assoc_request * assoc_req;
26157  
26158         lbs_deb_enter(LBS_DEB_WEXT);
26159  
26160 -       mutex_lock(&adapter->lock);
26161 -       assoc_req = wlan_get_association_request(adapter);
26162 +       mutex_lock(&priv->lock);
26163 +       assoc_req = lbs_get_association_request(priv);
26164         if (!assoc_req) {
26165                 ret = -ENOMEM;
26166                 goto out;
26167 @@ -1777,46 +1652,45 @@ static int wlan_set_genie(struct net_dev
26168                 memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length);
26169                 assoc_req->wpa_ie_len = dwrq->length;
26170         } else {
26171 -               memset(&assoc_req->wpa_ie[0], 0, sizeof(adapter->wpa_ie));
26172 +               memset(&assoc_req->wpa_ie[0], 0, sizeof(priv->wpa_ie));
26173                 assoc_req->wpa_ie_len = 0;
26174         }
26175  
26176  out:
26177         if (ret == 0) {
26178                 set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags);
26179 -               wlan_postpone_association_work(priv);
26180 +               lbs_postpone_association_work(priv);
26181         } else {
26182 -               wlan_cancel_association_work(priv);
26183 +               lbs_cancel_association_work(priv);
26184         }
26185 -       mutex_unlock(&adapter->lock);
26186 +       mutex_unlock(&priv->lock);
26187  
26188         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26189         return ret;
26190  }
26191  
26192 -static int wlan_get_genie(struct net_device *dev,
26193 +static int lbs_get_genie(struct net_device *dev,
26194                           struct iw_request_info *info,
26195                           struct iw_point *dwrq,
26196                           char *extra)
26197  {
26198         int ret = 0;
26199 -       wlan_private *priv = dev->priv;
26200 -       wlan_adapter *adapter = priv->adapter;
26201 +       struct lbs_private *priv = dev->priv;
26202  
26203         lbs_deb_enter(LBS_DEB_WEXT);
26204  
26205 -       if (adapter->wpa_ie_len == 0) {
26206 +       if (priv->wpa_ie_len == 0) {
26207                 dwrq->length = 0;
26208                 goto out;
26209         }
26210  
26211 -       if (dwrq->length < adapter->wpa_ie_len) {
26212 +       if (dwrq->length < priv->wpa_ie_len) {
26213                 ret = -E2BIG;
26214                 goto out;
26215         }
26216  
26217 -       dwrq->length = adapter->wpa_ie_len;
26218 -       memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len);
26219 +       dwrq->length = priv->wpa_ie_len;
26220 +       memcpy(extra, &priv->wpa_ie[0], priv->wpa_ie_len);
26221  
26222  out:
26223         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26224 @@ -1824,21 +1698,20 @@ out:
26225  }
26226  
26227  
26228 -static int wlan_set_auth(struct net_device *dev,
26229 +static int lbs_set_auth(struct net_device *dev,
26230                          struct iw_request_info *info,
26231                          struct iw_param *dwrq,
26232                          char *extra)
26233  {
26234 -       wlan_private *priv = dev->priv;
26235 -       wlan_adapter *adapter = priv->adapter;
26236 +       struct lbs_private *priv = dev->priv;
26237         struct assoc_request * assoc_req;
26238         int ret = 0;
26239         int updated = 0;
26240  
26241         lbs_deb_enter(LBS_DEB_WEXT);
26242  
26243 -       mutex_lock(&adapter->lock);
26244 -       assoc_req = wlan_get_association_request(adapter);
26245 +       mutex_lock(&priv->lock);
26246 +       assoc_req = lbs_get_association_request(priv);
26247         if (!assoc_req) {
26248                 ret = -ENOMEM;
26249                 goto out;
26250 @@ -1913,44 +1786,43 @@ out:
26251         if (ret == 0) {
26252                 if (updated)
26253                         set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
26254 -               wlan_postpone_association_work(priv);
26255 +               lbs_postpone_association_work(priv);
26256         } else if (ret != -EOPNOTSUPP) {
26257 -               wlan_cancel_association_work(priv);
26258 +               lbs_cancel_association_work(priv);
26259         }
26260 -       mutex_unlock(&adapter->lock);
26261 +       mutex_unlock(&priv->lock);
26262  
26263         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26264         return ret;
26265  }
26266  
26267 -static int wlan_get_auth(struct net_device *dev,
26268 +static int lbs_get_auth(struct net_device *dev,
26269                          struct iw_request_info *info,
26270                          struct iw_param *dwrq,
26271                          char *extra)
26272  {
26273         int ret = 0;
26274 -       wlan_private *priv = dev->priv;
26275 -       wlan_adapter *adapter = priv->adapter;
26276 +       struct lbs_private *priv = dev->priv;
26277  
26278         lbs_deb_enter(LBS_DEB_WEXT);
26279  
26280         switch (dwrq->flags & IW_AUTH_INDEX) {
26281         case IW_AUTH_WPA_VERSION:
26282                 dwrq->value = 0;
26283 -               if (adapter->secinfo.WPAenabled)
26284 +               if (priv->secinfo.WPAenabled)
26285                         dwrq->value |= IW_AUTH_WPA_VERSION_WPA;
26286 -               if (adapter->secinfo.WPA2enabled)
26287 +               if (priv->secinfo.WPA2enabled)
26288                         dwrq->value |= IW_AUTH_WPA_VERSION_WPA2;
26289                 if (!dwrq->value)
26290                         dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
26291                 break;
26292  
26293         case IW_AUTH_80211_AUTH_ALG:
26294 -               dwrq->value = adapter->secinfo.auth_mode;
26295 +               dwrq->value = priv->secinfo.auth_mode;
26296                 break;
26297  
26298         case IW_AUTH_WPA_ENABLED:
26299 -               if (adapter->secinfo.WPAenabled && adapter->secinfo.WPA2enabled)
26300 +               if (priv->secinfo.WPAenabled && priv->secinfo.WPA2enabled)
26301                         dwrq->value = 1;
26302                 break;
26303  
26304 @@ -1963,28 +1835,29 @@ static int wlan_get_auth(struct net_devi
26305  }
26306  
26307  
26308 -static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
26309 +static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
26310                    struct iw_param *vwrq, char *extra)
26311  {
26312         int ret = 0;
26313 -       wlan_private *priv = dev->priv;
26314 -       wlan_adapter *adapter = priv->adapter;
26315 +       struct lbs_private *priv = dev->priv;
26316  
26317         u16 dbm;
26318  
26319         lbs_deb_enter(LBS_DEB_WEXT);
26320  
26321         if (vwrq->disabled) {
26322 -               wlan_radio_ioctl(priv, RADIO_OFF);
26323 +               lbs_radio_ioctl(priv, RADIO_OFF);
26324                 return 0;
26325         }
26326  
26327 -       adapter->preamble = cmd_type_auto_preamble;
26328 +       priv->preamble = CMD_TYPE_AUTO_PREAMBLE;
26329  
26330 -       wlan_radio_ioctl(priv, RADIO_ON);
26331 +       lbs_radio_ioctl(priv, RADIO_ON);
26332  
26333 +       /* Userspace check in iwrange if it should use dBm or mW,
26334 +        * therefore this should never happen... Jean II */
26335         if ((vwrq->flags & IW_TXPOW_TYPE) == IW_TXPOW_MWATT) {
26336 -               dbm = (u16) mw_to_dbm(vwrq->value);
26337 +               return -EOPNOTSUPP;
26338         } else
26339                 dbm = (u16) vwrq->value;
26340  
26341 @@ -1995,20 +1868,19 @@ static int wlan_set_txpow(struct net_dev
26342  
26343         lbs_deb_wext("txpower set %d dbm\n", dbm);
26344  
26345 -       ret = libertas_prepare_and_send_command(priv,
26346 -                                   cmd_802_11_rf_tx_power,
26347 -                                   cmd_act_tx_power_opt_set_low,
26348 -                                   cmd_option_waitforrsp, 0, (void *)&dbm);
26349 +       ret = lbs_prepare_and_send_command(priv,
26350 +                                   CMD_802_11_RF_TX_POWER,
26351 +                                   CMD_ACT_TX_POWER_OPT_SET_LOW,
26352 +                                   CMD_OPTION_WAITFORRSP, 0, (void *)&dbm);
26353  
26354         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26355         return ret;
26356  }
26357  
26358 -static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
26359 +static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
26360                    struct iw_point *dwrq, char *extra)
26361  {
26362 -       wlan_private *priv = dev->priv;
26363 -       wlan_adapter *adapter = priv->adapter;
26364 +       struct lbs_private *priv = dev->priv;
26365  
26366         lbs_deb_enter(LBS_DEB_WEXT);
26367  
26368 @@ -2020,24 +1892,19 @@ static int wlan_get_essid(struct net_dev
26369         /*
26370          * Get the current SSID
26371          */
26372 -       if (adapter->connect_status == libertas_connected) {
26373 -               memcpy(extra, adapter->curbssparams.ssid,
26374 -                      adapter->curbssparams.ssid_len);
26375 -               extra[adapter->curbssparams.ssid_len] = '\0';
26376 +       if (priv->connect_status == LBS_CONNECTED) {
26377 +               memcpy(extra, priv->curbssparams.ssid,
26378 +                      priv->curbssparams.ssid_len);
26379 +               extra[priv->curbssparams.ssid_len] = '\0';
26380         } else {
26381                 memset(extra, 0, 32);
26382 -               extra[adapter->curbssparams.ssid_len] = '\0';
26383 +               extra[priv->curbssparams.ssid_len] = '\0';
26384         }
26385         /*
26386          * If none, we may want to get the one that was set
26387          */
26388  
26389 -       /* To make the driver backward compatible with WPA supplicant v0.2.4 */
26390 -       if (dwrq->length == 32) /* check with WPA supplicant buffer size */
26391 -               dwrq->length = min_t(size_t, adapter->curbssparams.ssid_len,
26392 -                                  IW_ESSID_MAX_SIZE);
26393 -       else
26394 -               dwrq->length = adapter->curbssparams.ssid_len + 1;
26395 +       dwrq->length = priv->curbssparams.ssid_len;
26396  
26397         dwrq->flags = 1;        /* active */
26398  
26399 @@ -2045,11 +1912,10 @@ static int wlan_get_essid(struct net_dev
26400         return 0;
26401  }
26402  
26403 -static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
26404 +static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
26405                    struct iw_point *dwrq, char *extra)
26406  {
26407 -       wlan_private *priv = dev->priv;
26408 -       wlan_adapter *adapter = priv->adapter;
26409 +       struct lbs_private *priv = dev->priv;
26410         int ret = 0;
26411         u8 ssid[IW_ESSID_MAX_SIZE];
26412         u8 ssid_len = 0;
26413 @@ -2058,14 +1924,6 @@ static int wlan_set_essid(struct net_dev
26414  
26415         lbs_deb_enter(LBS_DEB_WEXT);
26416  
26417 -       /*
26418 -        * WE-20 and earlier NULL pad the end of the SSID and increment
26419 -        * SSID length so it can be used like a string.  WE-21 and later don't,
26420 -        * but some userspace tools aren't able to cope with the change.
26421 -        */
26422 -       if ((in_ssid_len > 0) && (extra[in_ssid_len - 1] == '\0'))
26423 -               in_ssid_len--;
26424 -
26425         /* Check the size of the string */
26426         if (in_ssid_len > IW_ESSID_MAX_SIZE) {
26427                 ret = -E2BIG;
26428 @@ -2090,10 +1948,10 @@ static int wlan_set_essid(struct net_dev
26429         }
26430  
26431  out:
26432 -       mutex_lock(&adapter->lock);
26433 +       mutex_lock(&priv->lock);
26434         if (ret == 0) {
26435                 /* Get or create the current association request */
26436 -               assoc_req = wlan_get_association_request(adapter);
26437 +               assoc_req = lbs_get_association_request(priv);
26438                 if (!assoc_req) {
26439                         ret = -ENOMEM;
26440                 } else {
26441 @@ -2101,17 +1959,66 @@ out:
26442                         memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
26443                         assoc_req->ssid_len = ssid_len;
26444                         set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
26445 -                       wlan_postpone_association_work(priv);
26446 +                       lbs_postpone_association_work(priv);
26447                 }
26448         }
26449  
26450         /* Cancel the association request if there was an error */
26451         if (ret != 0) {
26452 -               wlan_cancel_association_work(priv);
26453 +               lbs_cancel_association_work(priv);
26454 +       }
26455 +
26456 +       mutex_unlock(&priv->lock);
26457 +
26458 +       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26459 +       return ret;
26460 +}
26461 +
26462 +static int lbs_mesh_get_essid(struct net_device *dev,
26463 +                             struct iw_request_info *info,
26464 +                             struct iw_point *dwrq, char *extra)
26465 +{
26466 +       struct lbs_private *priv = dev->priv;
26467 +
26468 +       lbs_deb_enter(LBS_DEB_WEXT);
26469 +
26470 +       memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
26471 +
26472 +       dwrq->length = priv->mesh_ssid_len;
26473 +
26474 +       dwrq->flags = 1;        /* active */
26475 +
26476 +       lbs_deb_leave(LBS_DEB_WEXT);
26477 +       return 0;
26478 +}
26479 +
26480 +static int lbs_mesh_set_essid(struct net_device *dev,
26481 +                             struct iw_request_info *info,
26482 +                             struct iw_point *dwrq, char *extra)
26483 +{
26484 +       struct lbs_private *priv = dev->priv;
26485 +       int ret = 0;
26486 +
26487 +       lbs_deb_enter(LBS_DEB_WEXT);
26488 +
26489 +       /* Check the size of the string */
26490 +       if (dwrq->length > IW_ESSID_MAX_SIZE) {
26491 +               ret = -E2BIG;
26492 +               goto out;
26493         }
26494  
26495 -       mutex_unlock(&adapter->lock);
26496 +       if (!dwrq->flags || !dwrq->length) {
26497 +               ret = -EINVAL;
26498 +               goto out;
26499 +       } else {
26500 +               /* Specific SSID requested */
26501 +               memcpy(priv->mesh_ssid, extra, dwrq->length);
26502 +               priv->mesh_ssid_len = dwrq->length;
26503 +       }
26504  
26505 +       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
26506 +                       priv->curbssparams.channel);
26507 + out:
26508         lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
26509         return ret;
26510  }
26511 @@ -2125,59 +2032,59 @@ out:
26512   *  @param extra        A pointer to extra data buf
26513   *  @return             0 --success, otherwise fail
26514   */
26515 -static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
26516 +static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
26517                  struct sockaddr *awrq, char *extra)
26518  {
26519 -       wlan_private *priv = dev->priv;
26520 -       wlan_adapter *adapter = priv->adapter;
26521 +       struct lbs_private *priv = dev->priv;
26522         struct assoc_request * assoc_req;
26523         int ret = 0;
26524 +       DECLARE_MAC_BUF(mac);
26525  
26526         lbs_deb_enter(LBS_DEB_WEXT);
26527  
26528         if (awrq->sa_family != ARPHRD_ETHER)
26529                 return -EINVAL;
26530  
26531 -       lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
26532 +       lbs_deb_wext("ASSOC: WAP: sa_data %s\n", print_mac(mac, awrq->sa_data));
26533  
26534 -       mutex_lock(&adapter->lock);
26535 +       mutex_lock(&priv->lock);
26536  
26537         /* Get or create the current association request */
26538 -       assoc_req = wlan_get_association_request(adapter);
26539 +       assoc_req = lbs_get_association_request(priv);
26540         if (!assoc_req) {
26541 -               wlan_cancel_association_work(priv);
26542 +               lbs_cancel_association_work(priv);
26543                 ret = -ENOMEM;
26544         } else {
26545                 /* Copy the BSSID to the association request */
26546                 memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN);
26547                 set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags);
26548 -               wlan_postpone_association_work(priv);
26549 +               lbs_postpone_association_work(priv);
26550         }
26551  
26552 -       mutex_unlock(&adapter->lock);
26553 +       mutex_unlock(&priv->lock);
26554  
26555         return ret;
26556  }
26557  
26558 -void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
26559 +void lbs_get_fwversion(struct lbs_private *priv, char *fwversion, int maxlen)
26560  {
26561         char fwver[32];
26562  
26563 -       mutex_lock(&adapter->lock);
26564 +       mutex_lock(&priv->lock);
26565  
26566 -       if (adapter->fwreleasenumber[3] == 0)
26567 +       if (priv->fwreleasenumber[3] == 0)
26568                 sprintf(fwver, "%u.%u.%u",
26569 -                       adapter->fwreleasenumber[2],
26570 -                       adapter->fwreleasenumber[1],
26571 -                       adapter->fwreleasenumber[0]);
26572 +                       priv->fwreleasenumber[2],
26573 +                       priv->fwreleasenumber[1],
26574 +                       priv->fwreleasenumber[0]);
26575         else
26576                 sprintf(fwver, "%u.%u.%u.p%u",
26577 -                       adapter->fwreleasenumber[2],
26578 -                       adapter->fwreleasenumber[1],
26579 -                       adapter->fwreleasenumber[0],
26580 -                       adapter->fwreleasenumber[3]);
26581 +                       priv->fwreleasenumber[2],
26582 +                       priv->fwreleasenumber[1],
26583 +                       priv->fwreleasenumber[0],
26584 +                       priv->fwreleasenumber[3]);
26585  
26586 -       mutex_unlock(&adapter->lock);
26587 +       mutex_unlock(&priv->lock);
26588         snprintf(fwversion, maxlen, fwver);
26589  }
26590  
26591 @@ -2185,19 +2092,19 @@ void libertas_get_fwversion(wlan_adapter
26592  /*
26593   * iwconfig settable callbacks
26594   */
26595 -static const iw_handler wlan_handler[] = {
26596 +static const iw_handler lbs_handler[] = {
26597         (iw_handler) NULL,      /* SIOCSIWCOMMIT */
26598 -       (iw_handler) wlan_get_name,     /* SIOCGIWNAME */
26599 +       (iw_handler) lbs_get_name,      /* SIOCGIWNAME */
26600         (iw_handler) NULL,      /* SIOCSIWNWID */
26601         (iw_handler) NULL,      /* SIOCGIWNWID */
26602 -       (iw_handler) wlan_set_freq,     /* SIOCSIWFREQ */
26603 -       (iw_handler) wlan_get_freq,     /* SIOCGIWFREQ */
26604 -       (iw_handler) wlan_set_mode,     /* SIOCSIWMODE */
26605 -       (iw_handler) wlan_get_mode,     /* SIOCGIWMODE */
26606 +       (iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
26607 +       (iw_handler) lbs_get_freq,      /* SIOCGIWFREQ */
26608 +       (iw_handler) lbs_set_mode,      /* SIOCSIWMODE */
26609 +       (iw_handler) lbs_get_mode,      /* SIOCGIWMODE */
26610         (iw_handler) NULL,      /* SIOCSIWSENS */
26611         (iw_handler) NULL,      /* SIOCGIWSENS */
26612         (iw_handler) NULL,      /* SIOCSIWRANGE */
26613 -       (iw_handler) wlan_get_range,    /* SIOCGIWRANGE */
26614 +       (iw_handler) lbs_get_range,     /* SIOCGIWRANGE */
26615         (iw_handler) NULL,      /* SIOCSIWPRIV */
26616         (iw_handler) NULL,      /* SIOCGIWPRIV */
26617         (iw_handler) NULL,      /* SIOCSIWSTATS */
26618 @@ -2206,56 +2113,56 @@ static const iw_handler wlan_handler[] =
26619         iw_handler_get_spy,     /* SIOCGIWSPY */
26620         iw_handler_set_thrspy,  /* SIOCSIWTHRSPY */
26621         iw_handler_get_thrspy,  /* SIOCGIWTHRSPY */
26622 -       (iw_handler) wlan_set_wap,      /* SIOCSIWAP */
26623 -       (iw_handler) wlan_get_wap,      /* SIOCGIWAP */
26624 +       (iw_handler) lbs_set_wap,       /* SIOCSIWAP */
26625 +       (iw_handler) lbs_get_wap,       /* SIOCGIWAP */
26626         (iw_handler) NULL,      /* SIOCSIWMLME */
26627         (iw_handler) NULL,      /* SIOCGIWAPLIST - deprecated */
26628 -       (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
26629 -       (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
26630 -       (iw_handler) wlan_set_essid,    /* SIOCSIWESSID */
26631 -       (iw_handler) wlan_get_essid,    /* SIOCGIWESSID */
26632 -       (iw_handler) wlan_set_nick,     /* SIOCSIWNICKN */
26633 -       (iw_handler) wlan_get_nick,     /* SIOCGIWNICKN */
26634 +       (iw_handler) lbs_set_scan,      /* SIOCSIWSCAN */
26635 +       (iw_handler) lbs_get_scan,      /* SIOCGIWSCAN */
26636 +       (iw_handler) lbs_set_essid,     /* SIOCSIWESSID */
26637 +       (iw_handler) lbs_get_essid,     /* SIOCGIWESSID */
26638 +       (iw_handler) lbs_set_nick,      /* SIOCSIWNICKN */
26639 +       (iw_handler) lbs_get_nick,      /* SIOCGIWNICKN */
26640         (iw_handler) NULL,      /* -- hole -- */
26641         (iw_handler) NULL,      /* -- hole -- */
26642 -       (iw_handler) wlan_set_rate,     /* SIOCSIWRATE */
26643 -       (iw_handler) wlan_get_rate,     /* SIOCGIWRATE */
26644 -       (iw_handler) wlan_set_rts,      /* SIOCSIWRTS */
26645 -       (iw_handler) wlan_get_rts,      /* SIOCGIWRTS */
26646 -       (iw_handler) wlan_set_frag,     /* SIOCSIWFRAG */
26647 -       (iw_handler) wlan_get_frag,     /* SIOCGIWFRAG */
26648 -       (iw_handler) wlan_set_txpow,    /* SIOCSIWTXPOW */
26649 -       (iw_handler) wlan_get_txpow,    /* SIOCGIWTXPOW */
26650 -       (iw_handler) wlan_set_retry,    /* SIOCSIWRETRY */
26651 -       (iw_handler) wlan_get_retry,    /* SIOCGIWRETRY */
26652 -       (iw_handler) wlan_set_encode,   /* SIOCSIWENCODE */
26653 -       (iw_handler) wlan_get_encode,   /* SIOCGIWENCODE */
26654 -       (iw_handler) wlan_set_power,    /* SIOCSIWPOWER */
26655 -       (iw_handler) wlan_get_power,    /* SIOCGIWPOWER */
26656 +       (iw_handler) lbs_set_rate,      /* SIOCSIWRATE */
26657 +       (iw_handler) lbs_get_rate,      /* SIOCGIWRATE */
26658 +       (iw_handler) lbs_set_rts,       /* SIOCSIWRTS */
26659 +       (iw_handler) lbs_get_rts,       /* SIOCGIWRTS */
26660 +       (iw_handler) lbs_set_frag,      /* SIOCSIWFRAG */
26661 +       (iw_handler) lbs_get_frag,      /* SIOCGIWFRAG */
26662 +       (iw_handler) lbs_set_txpow,     /* SIOCSIWTXPOW */
26663 +       (iw_handler) lbs_get_txpow,     /* SIOCGIWTXPOW */
26664 +       (iw_handler) lbs_set_retry,     /* SIOCSIWRETRY */
26665 +       (iw_handler) lbs_get_retry,     /* SIOCGIWRETRY */
26666 +       (iw_handler) lbs_set_encode,    /* SIOCSIWENCODE */
26667 +       (iw_handler) lbs_get_encode,    /* SIOCGIWENCODE */
26668 +       (iw_handler) lbs_set_power,     /* SIOCSIWPOWER */
26669 +       (iw_handler) lbs_get_power,     /* SIOCGIWPOWER */
26670         (iw_handler) NULL,      /* -- hole -- */
26671         (iw_handler) NULL,      /* -- hole -- */
26672 -       (iw_handler) wlan_set_genie,    /* SIOCSIWGENIE */
26673 -       (iw_handler) wlan_get_genie,    /* SIOCGIWGENIE */
26674 -       (iw_handler) wlan_set_auth,     /* SIOCSIWAUTH */
26675 -       (iw_handler) wlan_get_auth,     /* SIOCGIWAUTH */
26676 -       (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
26677 -       (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
26678 +       (iw_handler) lbs_set_genie,     /* SIOCSIWGENIE */
26679 +       (iw_handler) lbs_get_genie,     /* SIOCGIWGENIE */
26680 +       (iw_handler) lbs_set_auth,      /* SIOCSIWAUTH */
26681 +       (iw_handler) lbs_get_auth,      /* SIOCGIWAUTH */
26682 +       (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
26683 +       (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
26684         (iw_handler) NULL,              /* SIOCSIWPMKSA */
26685  };
26686  
26687  static const iw_handler mesh_wlan_handler[] = {
26688         (iw_handler) NULL,      /* SIOCSIWCOMMIT */
26689 -       (iw_handler) wlan_get_name,     /* SIOCGIWNAME */
26690 +       (iw_handler) lbs_get_name,      /* SIOCGIWNAME */
26691         (iw_handler) NULL,      /* SIOCSIWNWID */
26692         (iw_handler) NULL,      /* SIOCGIWNWID */
26693 -       (iw_handler) wlan_set_freq,     /* SIOCSIWFREQ */
26694 -       (iw_handler) wlan_get_freq,     /* SIOCGIWFREQ */
26695 +       (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
26696 +       (iw_handler) lbs_get_freq,      /* SIOCGIWFREQ */
26697         (iw_handler) NULL,              /* SIOCSIWMODE */
26698         (iw_handler) mesh_wlan_get_mode,        /* SIOCGIWMODE */
26699         (iw_handler) NULL,      /* SIOCSIWSENS */
26700         (iw_handler) NULL,      /* SIOCGIWSENS */
26701         (iw_handler) NULL,      /* SIOCSIWRANGE */
26702 -       (iw_handler) wlan_get_range,    /* SIOCGIWRANGE */
26703 +       (iw_handler) lbs_get_range,     /* SIOCGIWRANGE */
26704         (iw_handler) NULL,      /* SIOCSIWPRIV */
26705         (iw_handler) NULL,      /* SIOCGIWPRIV */
26706         (iw_handler) NULL,      /* SIOCSIWSTATS */
26707 @@ -2268,46 +2175,97 @@ static const iw_handler mesh_wlan_handle
26708         (iw_handler) NULL,      /* SIOCGIWAP */
26709         (iw_handler) NULL,      /* SIOCSIWMLME */
26710         (iw_handler) NULL,      /* SIOCGIWAPLIST - deprecated */
26711 -       (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
26712 -       (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
26713 -       (iw_handler) NULL,              /* SIOCSIWESSID */
26714 -       (iw_handler) NULL,              /* SIOCGIWESSID */
26715 +       (iw_handler) lbs_set_scan,      /* SIOCSIWSCAN */
26716 +       (iw_handler) lbs_get_scan,      /* SIOCGIWSCAN */
26717 +       (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
26718 +       (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
26719         (iw_handler) NULL,              /* SIOCSIWNICKN */
26720         (iw_handler) mesh_get_nick,     /* SIOCGIWNICKN */
26721         (iw_handler) NULL,      /* -- hole -- */
26722         (iw_handler) NULL,      /* -- hole -- */
26723 -       (iw_handler) wlan_set_rate,     /* SIOCSIWRATE */
26724 -       (iw_handler) wlan_get_rate,     /* SIOCGIWRATE */
26725 -       (iw_handler) wlan_set_rts,      /* SIOCSIWRTS */
26726 -       (iw_handler) wlan_get_rts,      /* SIOCGIWRTS */
26727 -       (iw_handler) wlan_set_frag,     /* SIOCSIWFRAG */
26728 -       (iw_handler) wlan_get_frag,     /* SIOCGIWFRAG */
26729 -       (iw_handler) wlan_set_txpow,    /* SIOCSIWTXPOW */
26730 -       (iw_handler) wlan_get_txpow,    /* SIOCGIWTXPOW */
26731 -       (iw_handler) wlan_set_retry,    /* SIOCSIWRETRY */
26732 -       (iw_handler) wlan_get_retry,    /* SIOCGIWRETRY */
26733 -       (iw_handler) wlan_set_encode,   /* SIOCSIWENCODE */
26734 -       (iw_handler) wlan_get_encode,   /* SIOCGIWENCODE */
26735 -       (iw_handler) wlan_set_power,    /* SIOCSIWPOWER */
26736 -       (iw_handler) wlan_get_power,    /* SIOCGIWPOWER */
26737 +       (iw_handler) lbs_set_rate,      /* SIOCSIWRATE */
26738 +       (iw_handler) lbs_get_rate,      /* SIOCGIWRATE */
26739 +       (iw_handler) lbs_set_rts,       /* SIOCSIWRTS */
26740 +       (iw_handler) lbs_get_rts,       /* SIOCGIWRTS */
26741 +       (iw_handler) lbs_set_frag,      /* SIOCSIWFRAG */
26742 +       (iw_handler) lbs_get_frag,      /* SIOCGIWFRAG */
26743 +       (iw_handler) lbs_set_txpow,     /* SIOCSIWTXPOW */
26744 +       (iw_handler) lbs_get_txpow,     /* SIOCGIWTXPOW */
26745 +       (iw_handler) lbs_set_retry,     /* SIOCSIWRETRY */
26746 +       (iw_handler) lbs_get_retry,     /* SIOCGIWRETRY */
26747 +       (iw_handler) lbs_set_encode,    /* SIOCSIWENCODE */
26748 +       (iw_handler) lbs_get_encode,    /* SIOCGIWENCODE */
26749 +       (iw_handler) lbs_set_power,     /* SIOCSIWPOWER */
26750 +       (iw_handler) lbs_get_power,     /* SIOCGIWPOWER */
26751         (iw_handler) NULL,      /* -- hole -- */
26752         (iw_handler) NULL,      /* -- hole -- */
26753 -       (iw_handler) wlan_set_genie,    /* SIOCSIWGENIE */
26754 -       (iw_handler) wlan_get_genie,    /* SIOCGIWGENIE */
26755 -       (iw_handler) wlan_set_auth,     /* SIOCSIWAUTH */
26756 -       (iw_handler) wlan_get_auth,     /* SIOCGIWAUTH */
26757 -       (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
26758 -       (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
26759 +       (iw_handler) lbs_set_genie,     /* SIOCSIWGENIE */
26760 +       (iw_handler) lbs_get_genie,     /* SIOCGIWGENIE */
26761 +       (iw_handler) lbs_set_auth,      /* SIOCSIWAUTH */
26762 +       (iw_handler) lbs_get_auth,      /* SIOCGIWAUTH */
26763 +       (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
26764 +       (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
26765         (iw_handler) NULL,              /* SIOCSIWPMKSA */
26766  };
26767 -struct iw_handler_def libertas_handler_def = {
26768 -       .num_standard   = sizeof(wlan_handler) / sizeof(iw_handler),
26769 -       .standard       = (iw_handler *) wlan_handler,
26770 -       .get_wireless_stats = wlan_get_wireless_stats,
26771 +
26772 +#define INT_PARAM              (IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1)
26773 +#define INT16_PARAM            (IW_PRIV_TYPE_INT | 16)
26774 +#define CHAR128_PARAM          (IW_PRIV_TYPE_CHAR | 128)
26775 +
26776 +static const struct iw_priv_args lbs_private_args[] = {
26777 +       /* { cmd, set_args, get_args, name } */
26778 +       { LBS_SETNONE_GETNONE, 0, 0, "" },
26779 +           { LBS_SUBCMD_FWT_RESET, 0, 0, "fwt_reset"},
26780 +           { LBS_SUBCMD_BT_RESET, 0, 0, "bt_reset"},
26781 +       { LBS_SETNONE_GETONEINT, 0, INT_PARAM, ""},
26782 +           { LBS_SUBCMD_GET_REGION, 0, INT_PARAM, "getregioncode"},
26783 +           { LBS_SUBCMD_FWT_CLEANUP, 0, INT_PARAM, "fwt_cleanup"},
26784 +           { LBS_SUBCMD_FWT_TIME, 0, INT_PARAM, "fwt_time"},
26785 +           { LBS_SUBCMD_MESH_GET_TTL, 0, INT_PARAM, "mesh_get_ttl"},
26786 +           { LBS_SUBCMD_BT_GET_INVERT, 0, INT_PARAM, "bt_get_invert"},
26787 +           { LBS_SUBCMD_MESH_GET_BCAST_RATE, 0, INT_PARAM, "mesh_get_bcastr"},
26788 +           { LBS_SUBCMD_MESH_GET_RREQ_DELAY, 0, INT_PARAM, "get_rreq_delay"},
26789 +           { LBS_SUBCMD_MESH_GET_ROUTE_EXP, 0, INT_PARAM, "get_route_exp"},
26790 +       { LBS_SETONEINT_GETNONE, INT_PARAM, 0, ""},
26791 +           { LBS_SUBCMD_SET_REGION, INT_PARAM, 0, "setregioncode"},
26792 +           { LBS_SUBCMD_MESH_SET_TTL, INT_PARAM, 0, "mesh_set_ttl"},
26793 +           { LBS_SUBCMD_BT_SET_INVERT, INT_PARAM, 0, "bt_set_invert"},
26794 +           { LBS_SUBCMD_MESH_SET_BCAST_RATE, INT_PARAM, 0, "mesh_set_bcastr"},
26795 +           { LBS_SUBCMD_MESH_SET_RREQ_DELAY, INT_PARAM, 0, "set_rreq_delay"},
26796 +           { LBS_SUBCMD_MESH_SET_ROUTE_EXP, INT_PARAM, 0, "set_route_exp"},
26797 +           { LBS_SUBCMD_MESH_SET_PRB_RSP_RETRY_LIMIT, INT_PARAM, 0,
26798 +                                                       "setprspretrylt"},
26799 +       { LBS_SET128CHAR_GET128CHAR, CHAR128_PARAM, CHAR128_PARAM, ""},
26800 +           { LBS_SUBCMD_BT_ADD, CHAR128_PARAM, CHAR128_PARAM, "bt_add"},
26801 +           { LBS_SUBCMD_BT_DEL, CHAR128_PARAM, CHAR128_PARAM, "bt_del"},
26802 +           { LBS_SUBCMD_BT_LIST, CHAR128_PARAM, CHAR128_PARAM, "bt_list"},
26803 +           { LBS_SUBCMD_FWT_ADD, CHAR128_PARAM, CHAR128_PARAM, "fwt_add"},
26804 +           { LBS_SUBCMD_FWT_DEL, CHAR128_PARAM, CHAR128_PARAM, "fwt_del"},
26805 +           { LBS_SUBCMD_FWT_LOOKUP, CHAR128_PARAM, CHAR128_PARAM, "fwt_lookup"},
26806 +           { LBS_SUBCMD_FWT_LIST_NEIGHBOR, CHAR128_PARAM, CHAR128_PARAM, "fwt_list_neigh"},
26807 +           { LBS_SUBCMD_FWT_LIST, CHAR128_PARAM, CHAR128_PARAM, "fwt_list"},
26808 +           { LBS_SUBCMD_FWT_LIST_ROUTE, CHAR128_PARAM, CHAR128_PARAM, "fwt_list_route"},
26809 +           { LBS_SUBCMD_MESH_SET_LINK_COSTS, CHAR128_PARAM, CHAR128_PARAM, "set_link_costs"},
26810 +           { LBS_SUBCMD_MESH_GET_LINK_COSTS, CHAR128_PARAM, CHAR128_PARAM, "get_link_costs"},
26811 +       { LBS_SET_GET_SIXTEEN_INT, INT16_PARAM, INT16_PARAM, ""},
26812 +           { LBS_LED_GPIO_CTRL, INT16_PARAM, INT16_PARAM, "ledgpio"},
26813 +           { LBS_BCN_CTRL, INT16_PARAM, INT16_PARAM, "bcn_control"},
26814 +           { LBS_LED_BEHAVIOR_CTRL, INT16_PARAM, INT16_PARAM, "ledbhv"},
26815 +};
26816 +
26817 +
26818 +struct iw_handler_def lbs_handler_def = {
26819 +       .num_standard   = ARRAY_SIZE(lbs_handler),
26820 +       .standard       = (iw_handler *) lbs_handler,
26821 +       .get_wireless_stats = lbs_get_wireless_stats,
26822 +       .num_private_args = ARRAY_SIZE(lbs_private_args),
26823 +       .private_args   = lbs_private_args,
26824  };
26825  
26826  struct iw_handler_def mesh_handler_def = {
26827 -       .num_standard   = sizeof(mesh_wlan_handler) / sizeof(iw_handler),
26828 +       .num_standard   = ARRAY_SIZE(mesh_wlan_handler),
26829         .standard       = (iw_handler *) mesh_wlan_handler,
26830 -       .get_wireless_stats = wlan_get_wireless_stats,
26831 +       .get_wireless_stats = lbs_get_wireless_stats,
26832 +       .num_private_args = ARRAY_SIZE(lbs_private_args),
26833 +       .private_args   = lbs_private_args,
26834  };
26835 diff -Nurp linux-2.6.22-250/drivers/net/wireless/libertas/wext.h linux-2.6.22-300/drivers/net/wireless/libertas/wext.h
26836 --- linux-2.6.22-250/drivers/net/wireless/libertas/wext.h       2007-07-08 19:32:17.000000000 -0400
26837 +++ linux-2.6.22-300/drivers/net/wireless/libertas/wext.h       2008-06-05 18:10:06.000000000 -0400
26838 @@ -1,14 +1,11 @@
26839  /**
26840    * This file contains definition for IOCTL call.
26841    */
26842 -#ifndef        _WLAN_WEXT_H_
26843 -#define        _WLAN_WEXT_H_
26844 +#ifndef        _LBS_WEXT_H_
26845 +#define        _LBS_WEXT_H_
26846  
26847 -#define SUBCMD_OFFSET                  4
26848 -#define SUBCMD_DATA(x)                 *((int *)(x->u.name + SUBCMD_OFFSET))
26849 -
26850 -/** wlan_ioctl_regrdwr */
26851 -struct wlan_ioctl_regrdwr {
26852 +/** lbs_ioctl_regrdwr */
26853 +struct lbs_ioctl_regrdwr {
26854         /** Which register to access */
26855         u16 whichreg;
26856         /** Read or Write */
26857 @@ -18,13 +15,9 @@ struct wlan_ioctl_regrdwr {
26858         u32 value;
26859  };
26860  
26861 -#define WLAN_LINKMODE_802_3                    0
26862 -#define WLAN_LINKMODE_802_11                   2
26863 -#define WLAN_RADIOMODE_NONE                    0
26864 -#define WLAN_RADIOMODE_RADIOTAP                        2
26865 +#define LBS_MONITOR_OFF                        0
26866  
26867 -extern struct iw_handler_def libertas_handler_def;
26868 +extern struct iw_handler_def lbs_handler_def;
26869  extern struct iw_handler_def mesh_handler_def;
26870 -int wlan_radio_ioctl(wlan_private * priv, u8 option);
26871  
26872 -#endif                         /* _WLAN_WEXT_H_ */
26873 +#endif