diff options
author | Dan Williams <dcbw@redhat.com> | 2007-08-02 11:40:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:49:48 -0400 |
commit | 8c5127657549d055ac9d709cdea73902a6ef392c (patch) | |
tree | 33e72a0b55165d51652a002ab6929857f0e2facc /drivers/net/wireless/libertas/join.c | |
parent | e52414728b930f0adcbc38c6498dd03b3568fe99 (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.c | 203 |
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 */ | ||
21 | u8 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 | */ |
36 | static int get_common_rates(wlan_adapter * adapter, u8 * rate1, | 38 | static 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 | |||
81 | done: | 71 | done: |
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 | */ | ||
87 | static 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 | */ | ||
106 | void 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 | |||
85 | int libertas_send_deauth(wlan_private * priv) | 115 | int 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); |