aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/join.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-08-02 11:40:45 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:48 -0400
commit8c5127657549d055ac9d709cdea73902a6ef392c (patch)
tree33e72a0b55165d51652a002ab6929857f0e2facc /drivers/net/wireless/libertas/join.c
parente52414728b930f0adcbc38c6498dd03b3568fe99 (diff)
[PATCH] libertas: simplify and clean up data rate handling
Remove unused/duplicated fields and consolidate static data rate arrays, for example the libertas_supported_rates[] and datarates[] arrays in the bss_descriptor structure, and the libertas_supported_rates field in the wlan_adapter structure. Introduce libertas_fw_index_to_data_rate and libertas_data_rate_to_fw_index functions and use them everywhere firmware requires a rate index rather than a rate array. The firmware requires the 4 basic rates to have the MSB set, but most other stuff doesn't, like WEXT and mesh ioctls. Therefore, only set the MSB on basic rates when pushing rate arrays to firmware instead of doing a ton of (rate & 0x7f) everywhere. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/join.c')
-rw-r--r--drivers/net/wireless/libertas/join.c203
1 files changed, 105 insertions, 98 deletions
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index 381739d6ed96..78e398d6f5f3 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -17,8 +17,12 @@
17#include "dev.h" 17#include "dev.h"
18#include "assoc.h" 18#include "assoc.h"
19 19
20/* Supported rates for ad-hoc B mode */
21u8 adhoc_rates_b[5] = { 0x02, 0x04, 0x0b, 0x16, 0x00 };
22
23
20/** 24/**
21 * @brief This function finds out the common rates between rate1 and rate2. 25 * @brief This function finds common rates between rate1 and card rates.
22 * 26 *
23 * It will fill common rates in rate1 as output if found. 27 * It will fill common rates in rate1 as output if found.
24 * 28 *
@@ -27,61 +31,87 @@
27 * 31 *
28 * @param adapter A pointer to wlan_adapter structure 32 * @param adapter A pointer to wlan_adapter structure
29 * @param rate1 the buffer which keeps input and output 33 * @param rate1 the buffer which keeps input and output
30 * @param rate1_size the size of rate1 buffer 34 * @param rate1_size the size of rate1 buffer; new size of buffer on return
31 * @param rate2 the buffer which keeps rate2
32 * @param rate2_size the size of rate2 buffer.
33 * 35 *
34 * @return 0 or -1 36 * @return 0 or -1
35 */ 37 */
36static int get_common_rates(wlan_adapter * adapter, u8 * rate1, 38static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size)
37 int rate1_size, u8 * rate2, int rate2_size)
38{ 39{
39 u8 *ptr = rate1; 40 u8 *card_rates = libertas_bg_rates;
40 int ret = 0; 41 size_t num_card_rates = sizeof(libertas_bg_rates);
42 int ret = 0, i, j;
41 u8 tmp[30]; 43 u8 tmp[30];
42 int i; 44 size_t tmp_size = 0;
43 45
44 memset(&tmp, 0, sizeof(tmp)); 46 /* For each rate in card_rates that exists in rate1, copy to tmp */
45 memcpy(&tmp, rate1, min_t(size_t, rate1_size, sizeof(tmp))); 47 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
46 memset(rate1, 0, rate1_size); 48 for (j = 0; rates[j] && (j < *rates_size); j++) {
47 49 if (rates[j] == card_rates[i])
48 /* Mask the top bit of the original values */ 50 tmp[tmp_size++] = card_rates[i];
49 for (i = 0; tmp[i] && i < sizeof(tmp); i++)
50 tmp[i] &= 0x7F;
51
52 for (i = 0; rate2[i] && i < rate2_size; i++) {
53 /* Check for Card Rate in tmp, excluding the top bit */
54 if (strchr(tmp, rate2[i] & 0x7F)) {
55 /* values match, so copy the Card Rate to rate1 */
56 *rate1++ = rate2[i];
57 } 51 }
58 } 52 }
59 53
60 lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp)); 54 lbs_dbg_hex("rate1 (AP) rates:", rates, *rates_size);
61 lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size); 55 lbs_dbg_hex("rate2 (Card) rates:", card_rates, num_card_rates);
62 lbs_dbg_hex("Common rates:", ptr, rate1_size); 56 lbs_dbg_hex("Common rates:", tmp, tmp_size);
63 lbs_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate); 57 lbs_deb_join("Tx datarate is currently 0x%X\n", adapter->cur_rate);
64 58
65 if (!adapter->is_datarate_auto) { 59 if (!adapter->auto_rate) {
66 while (*ptr) { 60 for (i = 0; i < tmp_size; i++) {
67 if ((*ptr & 0x7f) == adapter->datarate) { 61 if (tmp[i] == adapter->cur_rate)
68 ret = 0;
69 goto done; 62 goto done;
70 }
71 ptr++;
72 } 63 }
73 lbs_pr_alert( "Previously set fixed data rate %#x isn't " 64 lbs_pr_alert("Previously set fixed data rate %#x isn't "
74 "compatible with the network.\n", adapter->datarate); 65 "compatible with the network.\n", adapter->cur_rate);
75
76 ret = -1; 66 ret = -1;
77 goto done; 67 goto done;
78 } 68 }
79
80 ret = 0; 69 ret = 0;
70
81done: 71done:
72 memset(rates, 0, *rates_size);
73 *rates_size = min_t(int, tmp_size, *rates_size);
74 memcpy(rates, tmp, *rates_size);
82 return ret; 75 return ret;
83} 76}
84 77
78
79/**
80 * @brief Sets the MSB on basic rates as the firmware requires
81 *
82 * Scan through an array and set the MSB for basic data rates.
83 *
84 * @param rates buffer of data rates
85 * @param len size of buffer
86 */
87static void libertas_set_basic_rate_flags(u8 * rates, size_t len)
88{
89 int i;
90
91 for (i = 0; i < len; i++) {
92 if (rates[i] == 0x02 || rates[i] == 0x04 ||
93 rates[i] == 0x0b || rates[i] == 0x16)
94 rates[i] |= 0x80;
95 }
96}
97
98/**
99 * @brief Unsets the MSB on basic rates
100 *
101 * Scan through an array and unset the MSB for basic data rates.
102 *
103 * @param rates buffer of data rates
104 * @param len size of buffer
105 */
106void libertas_unset_basic_rate_flags(u8 * rates, size_t len)
107{
108 int i;
109
110 for (i = 0; i < len; i++)
111 rates[i] &= 0x7f;
112}
113
114
85int libertas_send_deauth(wlan_private * priv) 115int libertas_send_deauth(wlan_private * priv)
86{ 116{
87 wlan_adapter *adapter = priv->adapter; 117 wlan_adapter *adapter = priv->adapter;
@@ -330,9 +360,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
330 int ret = 0; 360 int ret = 0;
331 struct assoc_request * assoc_req = pdata_buf; 361 struct assoc_request * assoc_req = pdata_buf;
332 struct bss_descriptor * bss = &assoc_req->bss; 362 struct bss_descriptor * bss = &assoc_req->bss;
333 u8 *card_rates;
334 u8 *pos; 363 u8 *pos;
335 int card_rates_size;
336 u16 tmpcap, tmplen; 364 u16 tmpcap, tmplen;
337 struct mrvlietypes_ssidparamset *ssid; 365 struct mrvlietypes_ssidparamset *ssid;
338 struct mrvlietypes_phyparamset *phy; 366 struct mrvlietypes_phyparamset *phy;
@@ -386,23 +414,24 @@ int libertas_cmd_80211_associate(wlan_private * priv,
386 414
387 rates = (struct mrvlietypes_ratesparamset *) pos; 415 rates = (struct mrvlietypes_ratesparamset *) pos;
388 rates->header.type = cpu_to_le16(TLV_TYPE_RATES); 416 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
389 417 memcpy(&rates->rates, &bss->rates, MAX_RATES);
390 memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES); 418 tmplen = MAX_RATES;
391 419 if (get_common_rates(adapter, rates->rates, &tmplen)) {
392 card_rates = libertas_supported_rates;
393 card_rates_size = sizeof(libertas_supported_rates);
394
395 if (get_common_rates(adapter, rates->rates, WLAN_SUPPORTED_RATES,
396 card_rates, card_rates_size)) {
397 ret = -1; 420 ret = -1;
398 goto done; 421 goto done;
399 } 422 }
400
401 tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
402 adapter->curbssparams.numofrates = tmplen;
403
404 pos += sizeof(rates->header) + tmplen; 423 pos += sizeof(rates->header) + tmplen;
405 rates->header.len = cpu_to_le16(tmplen); 424 rates->header.len = cpu_to_le16(tmplen);
425 lbs_deb_join("ASSOC_CMD: num rates = %u\n", tmplen);
426
427 /* Copy the infra. association rates into Current BSS state structure */
428 memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
429 memcpy(&adapter->curbssparams.rates, &rates->rates, tmplen);
430
431 /* Set MSB on basic rates as the firmware requires, but _after_
432 * copying to current bss rates.
433 */
434 libertas_set_basic_rate_flags(rates->rates, tmplen);
406 435
407 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { 436 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
408 rsn = (struct mrvlietypes_rsnparamset *) pos; 437 rsn = (struct mrvlietypes_rsnparamset *) pos;
@@ -419,14 +448,6 @@ int libertas_cmd_80211_associate(wlan_private * priv,
419 /* update curbssparams */ 448 /* update curbssparams */
420 adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan; 449 adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
421 450
422 /* Copy the infra. association rates into Current BSS state structure */
423 memcpy(&adapter->curbssparams.datarates, &rates->rates,
424 min_t(size_t, sizeof(adapter->curbssparams.datarates),
425 cpu_to_le16(rates->header.len)));
426
427 lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n",
428 cpu_to_le16(rates->header.len));
429
430 if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { 451 if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
431 ret = -1; 452 ret = -1;
432 goto done; 453 goto done;
@@ -454,9 +475,9 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
454 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; 475 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
455 int ret = 0; 476 int ret = 0;
456 int cmdappendsize = 0; 477 int cmdappendsize = 0;
457 int i;
458 struct assoc_request * assoc_req = pdata_buf; 478 struct assoc_request * assoc_req = pdata_buf;
459 u16 tmpcap = 0; 479 u16 tmpcap = 0;
480 size_t ratesize = 0;
460 481
461 lbs_deb_enter(LBS_DEB_JOIN); 482 lbs_deb_enter(LBS_DEB_JOIN);
462 483
@@ -526,28 +547,26 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
526 /* probedelay */ 547 /* probedelay */
527 adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 548 adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
528 549
529 memset(adhs->datarate, 0, sizeof(adhs->datarate)); 550 memset(adhs->rates, 0, sizeof(adhs->rates));
530
531 if (adapter->adhoc_grate_enabled) { 551 if (adapter->adhoc_grate_enabled) {
532 memcpy(adhs->datarate, libertas_adhoc_rates_g, 552 ratesize = min(sizeof(adhs->rates), sizeof(libertas_bg_rates));
533 min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_g))); 553 memcpy(adhs->rates, libertas_bg_rates, ratesize);
534 } else { 554 } else {
535 memcpy(adhs->datarate, libertas_adhoc_rates_b, 555 ratesize = min(sizeof(adhs->rates), sizeof(adhoc_rates_b));
536 min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_b))); 556 memcpy(adhs->rates, adhoc_rates_b, ratesize);
537 } 557 }
538 558
539 /* Find the last non zero */
540 for (i = 0; i < sizeof(adhs->datarate) && adhs->datarate[i]; i++) ;
541
542 adapter->curbssparams.numofrates = i;
543
544 /* Copy the ad-hoc creating rates into Current BSS state structure */ 559 /* Copy the ad-hoc creating rates into Current BSS state structure */
545 memcpy(&adapter->curbssparams.datarates, 560 memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
546 &adhs->datarate, adapter->curbssparams.numofrates); 561 memcpy(&adapter->curbssparams.rates, &adhs->rates, ratesize);
562
563 /* Set MSB on basic rates as the firmware requires, but _after_
564 * copying to current bss rates.
565 */
566 libertas_set_basic_rate_flags(adhs->rates, ratesize);
547 567
548 lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n", 568 lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
549 adhs->datarate[0], adhs->datarate[1], 569 adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
550 adhs->datarate[2], adhs->datarate[3]);
551 570
552 lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n"); 571 lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
553 572
@@ -584,9 +603,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
584 struct bss_descriptor *bss = &assoc_req->bss; 603 struct bss_descriptor *bss = &assoc_req->bss;
585 int cmdappendsize = 0; 604 int cmdappendsize = 0;
586 int ret = 0; 605 int ret = 0;
587 u8 *card_rates; 606 u16 ratesize = 0;
588 int card_rates_size;
589 int i;
590 607
591 lbs_deb_enter(LBS_DEB_JOIN); 608 lbs_deb_enter(LBS_DEB_JOIN);
592 609
@@ -619,36 +636,26 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
619 /* probedelay */ 636 /* probedelay */
620 join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 637 join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
621 638
622 /* Copy Data rates from the rates recorded in scan response */
623 memset(join_cmd->bss.datarates, 0, sizeof(join_cmd->bss.datarates));
624 memcpy(join_cmd->bss.datarates, bss->datarates,
625 min(sizeof(join_cmd->bss.datarates), sizeof(bss->datarates)));
626
627 card_rates = libertas_supported_rates;
628 card_rates_size = sizeof(libertas_supported_rates);
629
630 adapter->curbssparams.channel = bss->channel; 639 adapter->curbssparams.channel = bss->channel;
631 640
632 if (get_common_rates(adapter, join_cmd->bss.datarates, 641 /* Copy Data rates from the rates recorded in scan response */
633 sizeof(join_cmd->bss.datarates), 642 memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
634 card_rates, card_rates_size)) { 643 ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
644 memcpy(join_cmd->bss.rates, bss->rates, ratesize);
645 if (get_common_rates(adapter, join_cmd->bss.rates, &ratesize)) {
635 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n"); 646 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
636 ret = -1; 647 ret = -1;
637 goto done; 648 goto done;
638 } 649 }
639 650
640 /* Find the last non zero */ 651 /* Copy the ad-hoc creating rates into Current BSS state structure */
641 for (i = 0; i < sizeof(join_cmd->bss.datarates) 652 memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
642 && join_cmd->bss.datarates[i]; i++) ; 653 memcpy(&adapter->curbssparams.rates, join_cmd->bss.rates, ratesize);
643
644 adapter->curbssparams.numofrates = i;
645 654
646 /* 655 /* Set MSB on basic rates as the firmware requires, but _after_
647 * Copy the adhoc joining rates to Current BSS State structure 656 * copying to current bss rates.
648 */ 657 */
649 memcpy(adapter->curbssparams.datarates, 658 libertas_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
650 join_cmd->bss.datarates,
651 adapter->curbssparams.numofrates);
652 659
653 join_cmd->bss.ssparamset.ibssparamset.atimwindow = 660 join_cmd->bss.ssparamset.ibssparamset.atimwindow =
654 cpu_to_le16(bss->atimwindow); 661 cpu_to_le16(bss->atimwindow);