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 | |
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>
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/decl.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/defs.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/fw.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/hostcmd.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/join.c | 203 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/join.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/rx.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/scan.c | 54 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/scan.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 163 |
14 files changed, 241 insertions, 323 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index c96ced963d69..c3fc074b6e3a 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -607,17 +607,14 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, | |||
607 | 607 | ||
608 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) + | 608 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) + |
609 | S_DS_GEN); | 609 | S_DS_GEN); |
610 | |||
611 | cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE); | 610 | cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE); |
612 | |||
613 | memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate)); | 611 | memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate)); |
614 | |||
615 | pdatarate->action = cpu_to_le16(cmd_action); | 612 | pdatarate->action = cpu_to_le16(cmd_action); |
616 | 613 | ||
617 | if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) { | 614 | if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) { |
618 | pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate); | 615 | pdatarate->rates[0] = libertas_data_rate_to_fw_index(adapter->cur_rate); |
619 | lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n", | 616 | lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n", |
620 | adapter->datarate); | 617 | adapter->cur_rate); |
621 | } else if (cmd_action == CMD_ACT_SET_TX_AUTO) { | 618 | } else if (cmd_action == CMD_ACT_SET_TX_AUTO) { |
622 | lbs_deb_cmd("Setting FW for AUTO rate\n"); | 619 | lbs_deb_cmd("Setting FW for AUTO rate\n"); |
623 | } | 620 | } |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index d90279269e7b..577c434089b0 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -430,21 +430,18 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv, | |||
430 | { | 430 | { |
431 | struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate; | 431 | struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate; |
432 | wlan_adapter *adapter = priv->adapter; | 432 | wlan_adapter *adapter = priv->adapter; |
433 | u8 dot11datarate; | ||
434 | 433 | ||
435 | lbs_deb_enter(LBS_DEB_CMD); | 434 | lbs_deb_enter(LBS_DEB_CMD); |
436 | 435 | ||
437 | lbs_dbg_hex("DATA_RATE_RESP: data_rate- ", | 436 | lbs_dbg_hex("DATA_RATE_RESP: data_rate- ", (u8 *) pdatarate, |
438 | (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate)); | 437 | sizeof(struct cmd_ds_802_11_data_rate)); |
439 | 438 | ||
440 | dot11datarate = pdatarate->datarate[0]; | 439 | /* FIXME: get actual rates FW can do if this command actually returns |
441 | if (pdatarate->action == cpu_to_le16(CMD_ACT_GET_TX_RATE)) { | 440 | * all data rates supported. |
442 | memcpy(adapter->libertas_supported_rates, pdatarate->datarate, | 441 | */ |
443 | sizeof(adapter->libertas_supported_rates)); | 442 | adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]); |
444 | } | ||
445 | adapter->datarate = libertas_index_to_data_rate(dot11datarate); | ||
446 | 443 | ||
447 | lbs_deb_enter(LBS_DEB_CMD); | 444 | lbs_deb_leave(LBS_DEB_CMD); |
448 | return 0; | 445 | return 0; |
449 | } | 446 | } |
450 | 447 | ||
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 846e79a77f67..129b021d35fd 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h | |||
@@ -44,8 +44,8 @@ int libertas_execute_next_command(wlan_private * priv); | |||
44 | int libertas_process_event(wlan_private * priv); | 44 | int libertas_process_event(wlan_private * priv); |
45 | void libertas_interrupt(struct net_device *); | 45 | void libertas_interrupt(struct net_device *); |
46 | int libertas_set_radio_control(wlan_private * priv); | 46 | int libertas_set_radio_control(wlan_private * priv); |
47 | u32 libertas_index_to_data_rate(u8 index); | 47 | u32 libertas_fw_index_to_data_rate(u8 index); |
48 | u8 libertas_data_rate_to_index(u32 rate); | 48 | u8 libertas_data_rate_to_fw_index(u32 rate); |
49 | void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen); | 49 | void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen); |
50 | 50 | ||
51 | void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); | 51 | void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 862292913c2c..a1c6dae1ba46 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h | |||
@@ -246,10 +246,7 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) | |||
246 | ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ | 246 | ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ |
247 | AVG_SCALE)) / N)) | 247 | AVG_SCALE)) / N)) |
248 | 248 | ||
249 | #define B_SUPPORTED_RATES 8 | 249 | #define MAX_RATES 14 |
250 | #define G_SUPPORTED_RATES 14 | ||
251 | |||
252 | #define WLAN_SUPPORTED_RATES 14 | ||
253 | 250 | ||
254 | #define MAX_LEDS 8 | 251 | #define MAX_LEDS 8 |
255 | 252 | ||
@@ -263,11 +260,7 @@ typedef struct _wlan_adapter wlan_adapter; | |||
263 | extern const char libertas_driver_version[]; | 260 | extern const char libertas_driver_version[]; |
264 | extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE]; | 261 | extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE]; |
265 | 262 | ||
266 | extern u8 libertas_supported_rates[G_SUPPORTED_RATES]; | 263 | extern u8 libertas_bg_rates[MAX_RATES]; |
267 | |||
268 | extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES]; | ||
269 | |||
270 | extern u8 libertas_adhoc_rates_b[4]; | ||
271 | 264 | ||
272 | /** ENUM definition*/ | 265 | /** ENUM definition*/ |
273 | /** SNRNF_TYPE */ | 266 | /** SNRNF_TYPE */ |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index c6fb703f665b..6acb8fb8733e 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -72,10 +72,8 @@ struct current_bss_params { | |||
72 | u8 band; | 72 | u8 band; |
73 | /** channel */ | 73 | /** channel */ |
74 | u8 channel; | 74 | u8 channel; |
75 | /** number of rates supported */ | 75 | /** zero-terminated array of supported data rates */ |
76 | int numofrates; | 76 | u8 rates[MAX_RATES + 1]; |
77 | /** supported rates*/ | ||
78 | u8 datarates[WLAN_SUPPORTED_RATES]; | ||
79 | }; | 77 | }; |
80 | 78 | ||
81 | /** sleep_params */ | 79 | /** sleep_params */ |
@@ -296,9 +294,6 @@ struct _wlan_adapter { | |||
296 | u32 fragthsd; | 294 | u32 fragthsd; |
297 | u32 rtsthsd; | 295 | u32 rtsthsd; |
298 | 296 | ||
299 | u32 datarate; | ||
300 | u8 is_datarate_auto; | ||
301 | |||
302 | u16 listeninterval; | 297 | u16 listeninterval; |
303 | u16 prescan; | 298 | u16 prescan; |
304 | u8 txretrycount; | 299 | u8 txretrycount; |
@@ -364,10 +359,9 @@ struct _wlan_adapter { | |||
364 | u8 radioon; | 359 | u8 radioon; |
365 | u32 preamble; | 360 | u32 preamble; |
366 | 361 | ||
367 | /** Multi bands Parameter*/ | 362 | /** data rate stuff */ |
368 | u8 libertas_supported_rates[G_SUPPORTED_RATES]; | 363 | u8 cur_rate; |
369 | 364 | u8 auto_rate; | |
370 | /** Blue Tooth Co-existence Arbitration */ | ||
371 | 365 | ||
372 | /** sleep_params */ | 366 | /** sleep_params */ |
373 | struct sleep_params sp; | 367 | struct sleep_params sp; |
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c index d214692eb209..6c259878da96 100644 --- a/drivers/net/wireless/libertas/fw.c +++ b/drivers/net/wireless/libertas/fw.c | |||
@@ -214,7 +214,10 @@ static void wlan_init_adapter(wlan_private * priv) | |||
214 | adapter->txantenna = RF_ANTENNA_2; | 214 | adapter->txantenna = RF_ANTENNA_2; |
215 | adapter->rxantenna = RF_ANTENNA_AUTO; | 215 | adapter->rxantenna = RF_ANTENNA_AUTO; |
216 | 216 | ||
217 | adapter->is_datarate_auto = 1; | 217 | adapter->auto_rate = 1; |
218 | adapter->cur_rate = 0; | ||
219 | adapter->adhoc_grate_enabled = 0; | ||
220 | |||
218 | adapter->beaconperiod = MRVDRV_BEACON_INTERVAL; | 221 | adapter->beaconperiod = MRVDRV_BEACON_INTERVAL; |
219 | 222 | ||
220 | // set default capabilities | 223 | // set default capabilities |
@@ -229,10 +232,6 @@ static void wlan_init_adapter(wlan_private * priv) | |||
229 | adapter->needtowakeup = 0; | 232 | adapter->needtowakeup = 0; |
230 | adapter->locallisteninterval = 0; /* default value in firmware will be used */ | 233 | adapter->locallisteninterval = 0; /* default value in firmware will be used */ |
231 | 234 | ||
232 | adapter->datarate = 0; // Initially indicate the rate as auto | ||
233 | |||
234 | adapter->adhoc_grate_enabled = 0; | ||
235 | |||
236 | adapter->intcounter = 0; | 235 | adapter->intcounter = 0; |
237 | 236 | ||
238 | adapter->currenttxskb = NULL; | 237 | adapter->currenttxskb = NULL; |
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index 76c5fdeb256a..44cf39c8d1b8 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h | |||
@@ -428,8 +428,8 @@ struct PS_CMD_ConfirmSleep { | |||
428 | 428 | ||
429 | struct cmd_ds_802_11_data_rate { | 429 | struct cmd_ds_802_11_data_rate { |
430 | __le16 action; | 430 | __le16 action; |
431 | __le16 reserverd; | 431 | __le16 reserved; |
432 | u8 datarate[G_SUPPORTED_RATES]; | 432 | u8 rates[MAX_RATES]; |
433 | }; | 433 | }; |
434 | 434 | ||
435 | struct cmd_ds_802_11_rate_adapt_rateset { | 435 | struct cmd_ds_802_11_rate_adapt_rateset { |
@@ -447,7 +447,7 @@ struct cmd_ds_802_11_ad_hoc_start { | |||
447 | union ieeetypes_phyparamset phyparamset; | 447 | union ieeetypes_phyparamset phyparamset; |
448 | __le16 probedelay; | 448 | __le16 probedelay; |
449 | __le16 capability; | 449 | __le16 capability; |
450 | u8 datarate[G_SUPPORTED_RATES]; | 450 | u8 rates[MAX_RATES]; |
451 | u8 tlv_memory_size_pad[100]; | 451 | u8 tlv_memory_size_pad[100]; |
452 | } __attribute__ ((packed)); | 452 | } __attribute__ ((packed)); |
453 | 453 | ||
@@ -462,7 +462,7 @@ struct adhoc_bssdesc { | |||
462 | union ieeetypes_phyparamset phyparamset; | 462 | union ieeetypes_phyparamset phyparamset; |
463 | union IEEEtypes_ssparamset ssparamset; | 463 | union IEEEtypes_ssparamset ssparamset; |
464 | __le16 capability; | 464 | __le16 capability; |
465 | u8 datarates[G_SUPPORTED_RATES]; | 465 | u8 rates[MAX_RATES]; |
466 | 466 | ||
467 | /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the | 467 | /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the |
468 | * Adhoc join command and will cause a binary layout mismatch with | 468 | * Adhoc join command and will cause a binary layout mismatch with |
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); |
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index d522630ff8cf..8ea5ae30f4ab 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h | |||
@@ -53,4 +53,6 @@ extern int libertas_do_adhocstop_ioctl(wlan_private * priv); | |||
53 | 53 | ||
54 | int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); | 54 | int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); |
55 | 55 | ||
56 | void libertas_unset_basic_rate_flags(u8 * rates, size_t len); | ||
57 | |||
56 | #endif | 58 | #endif |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 26948595d952..03217f5537ad 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -150,29 +150,60 @@ static struct region_cfp_table region_cfp_table[] = { | |||
150 | }; | 150 | }; |
151 | 151 | ||
152 | /** | 152 | /** |
153 | * the rates supported | 153 | * the table to keep region code |
154 | */ | 154 | */ |
155 | u8 libertas_supported_rates[G_SUPPORTED_RATES] = | 155 | u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = |
156 | { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, | 156 | { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; |
157 | 0 }; | ||
158 | 157 | ||
159 | /** | 158 | /** |
160 | * the rates supported for ad-hoc G mode | 159 | * 802.11b/g supported bitrates (in 500Kb/s units) |
161 | */ | 160 | */ |
162 | u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] = | 161 | u8 libertas_bg_rates[MAX_RATES] = |
163 | { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, | 162 | { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, |
164 | 0 }; | 163 | 0x00, 0x00 }; |
165 | 164 | ||
166 | /** | 165 | /** |
167 | * the rates supported for ad-hoc B mode | 166 | * FW rate table. FW refers to rates by their index in this table, not by the |
167 | * rate value itself. Values of 0x00 are | ||
168 | * reserved positions. | ||
168 | */ | 169 | */ |
169 | u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 }; | 170 | static u8 fw_data_rates[MAX_RATES] = |
171 | { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, | ||
172 | 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 | ||
173 | }; | ||
170 | 174 | ||
171 | /** | 175 | /** |
172 | * the table to keep region code | 176 | * @brief use index to get the data rate |
177 | * | ||
178 | * @param idx The index of data rate | ||
179 | * @return data rate or 0 | ||
173 | */ | 180 | */ |
174 | u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = | 181 | u32 libertas_fw_index_to_data_rate(u8 idx) |
175 | { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; | 182 | { |
183 | if (idx >= sizeof(fw_data_rates)) | ||
184 | idx = 0; | ||
185 | return fw_data_rates[idx]; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * @brief use rate to get the index | ||
190 | * | ||
191 | * @param rate data rate | ||
192 | * @return index or 0 | ||
193 | */ | ||
194 | u8 libertas_data_rate_to_fw_index(u32 rate) | ||
195 | { | ||
196 | u8 i; | ||
197 | |||
198 | if (!rate) | ||
199 | return 0; | ||
200 | |||
201 | for (i = 0; i < sizeof(fw_data_rates); i++) { | ||
202 | if (rate == fw_data_rates[i]) | ||
203 | return i; | ||
204 | } | ||
205 | return 0; | ||
206 | } | ||
176 | 207 | ||
177 | /** | 208 | /** |
178 | * Attributes exported through sysfs | 209 | * Attributes exported through sysfs |
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 769c86fb9509..e78636d6651a 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -260,8 +260,8 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) | |||
260 | /* Take the data rate from the rxpd structure | 260 | /* Take the data rate from the rxpd structure |
261 | * only if the rate is auto | 261 | * only if the rate is auto |
262 | */ | 262 | */ |
263 | if (adapter->is_datarate_auto) | 263 | if (adapter->auto_rate) |
264 | adapter->datarate = libertas_index_to_data_rate(p_rx_pd->rx_rate); | 264 | adapter->cur_rate = libertas_fw_index_to_data_rate(p_rx_pd->rx_rate); |
265 | 265 | ||
266 | wlan_compute_rssi(priv, p_rx_pd); | 266 | wlan_compute_rssi(priv, p_rx_pd); |
267 | 267 | ||
@@ -424,9 +424,8 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) | |||
424 | /* Take the data rate from the rxpd structure | 424 | /* Take the data rate from the rxpd structure |
425 | * only if the rate is auto | 425 | * only if the rate is auto |
426 | */ | 426 | */ |
427 | if (adapter->is_datarate_auto) { | 427 | if (adapter->auto_rate) |
428 | adapter->datarate = libertas_index_to_data_rate(prxpd->rx_rate); | 428 | adapter->cur_rate = libertas_fw_index_to_data_rate(prxpd->rx_rate); |
429 | } | ||
430 | 429 | ||
431 | wlan_compute_rssi(priv, prxpd); | 430 | wlan_compute_rssi(priv, prxpd); |
432 | 431 | ||
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 2cac47fc4cd9..790e9888ea2b 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "decl.h" | 17 | #include "decl.h" |
18 | #include "dev.h" | 18 | #include "dev.h" |
19 | #include "scan.h" | 19 | #include "scan.h" |
20 | #include "join.h" | ||
20 | 21 | ||
21 | //! Approximate amount of data needed to pass a scan result back to iwlist | 22 | //! Approximate amount of data needed to pass a scan result back to iwlist |
22 | #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ | 23 | #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ |
@@ -904,22 +905,14 @@ static int libertas_process_bss(struct bss_descriptor * bss, | |||
904 | struct ieeetypes_dsparamset *pDS; | 905 | struct ieeetypes_dsparamset *pDS; |
905 | struct ieeetypes_cfparamset *pCF; | 906 | struct ieeetypes_cfparamset *pCF; |
906 | struct ieeetypes_ibssparamset *pibss; | 907 | struct ieeetypes_ibssparamset *pibss; |
907 | u8 *pos, *end; | ||
908 | u8 *pRate; | ||
909 | u8 bytestocopy; | ||
910 | u8 ratesize; | ||
911 | u16 beaconsize; | ||
912 | u8 founddatarateie; | ||
913 | int ret; | ||
914 | |||
915 | struct ieeetypes_countryinfoset *pcountryinfo; | 908 | struct ieeetypes_countryinfoset *pcountryinfo; |
909 | u8 *pos, *end, *p; | ||
910 | u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; | ||
911 | u16 beaconsize = 0; | ||
912 | int ret; | ||
916 | 913 | ||
917 | lbs_deb_enter(LBS_DEB_ASSOC); | 914 | lbs_deb_enter(LBS_DEB_ASSOC); |
918 | 915 | ||
919 | founddatarateie = 0; | ||
920 | ratesize = 0; | ||
921 | beaconsize = 0; | ||
922 | |||
923 | if (*bytesleft >= sizeof(beaconsize)) { | 916 | if (*bytesleft >= sizeof(beaconsize)) { |
924 | /* Extract & convert beacon size from the command buffer */ | 917 | /* Extract & convert beacon size from the command buffer */ |
925 | beaconsize = le16_to_cpup((void *)*pbeaconinfo); | 918 | beaconsize = le16_to_cpup((void *)*pbeaconinfo); |
@@ -1005,11 +998,9 @@ static int libertas_process_bss(struct bss_descriptor * bss, | |||
1005 | break; | 998 | break; |
1006 | 999 | ||
1007 | case MFIE_TYPE_RATES: | 1000 | case MFIE_TYPE_RATES: |
1008 | memcpy(bss->datarates, elem->data, elem->len); | 1001 | n_basic_rates = min_t(u8, MAX_RATES, elem->len); |
1009 | memmove(bss->libertas_supported_rates, elem->data, | 1002 | memcpy(bss->rates, elem->data, n_basic_rates); |
1010 | elem->len); | 1003 | got_basic_rates = 1; |
1011 | ratesize = elem->len; | ||
1012 | founddatarateie = 1; | ||
1013 | break; | 1004 | break; |
1014 | 1005 | ||
1015 | case MFIE_TYPE_FH_SET: | 1006 | case MFIE_TYPE_FH_SET: |
@@ -1070,22 +1061,15 @@ static int libertas_process_bss(struct bss_descriptor * bss, | |||
1070 | * already found. Data rate IE should come before | 1061 | * already found. Data rate IE should come before |
1071 | * extended supported rate IE | 1062 | * extended supported rate IE |
1072 | */ | 1063 | */ |
1073 | if (!founddatarateie) | 1064 | if (!got_basic_rates) |
1074 | break; | 1065 | break; |
1075 | 1066 | ||
1076 | if ((elem->len + ratesize) > WLAN_SUPPORTED_RATES) { | 1067 | n_ex_rates = elem->len; |
1077 | bytestocopy = | 1068 | if (n_basic_rates + n_ex_rates > MAX_RATES) |
1078 | (WLAN_SUPPORTED_RATES - ratesize); | 1069 | n_ex_rates = MAX_RATES - n_basic_rates; |
1079 | } else { | ||
1080 | bytestocopy = elem->len; | ||
1081 | } | ||
1082 | 1070 | ||
1083 | pRate = (u8 *) bss->datarates; | 1071 | p = bss->rates + n_basic_rates; |
1084 | pRate += ratesize; | 1072 | memcpy(p, elem->data, n_ex_rates); |
1085 | memmove(pRate, elem->data, bytestocopy); | ||
1086 | pRate = (u8 *) bss->libertas_supported_rates; | ||
1087 | pRate += ratesize; | ||
1088 | memmove(pRate, elem->data, bytestocopy); | ||
1089 | break; | 1073 | break; |
1090 | 1074 | ||
1091 | case MFIE_TYPE_GENERIC: | 1075 | case MFIE_TYPE_GENERIC: |
@@ -1123,6 +1107,7 @@ static int libertas_process_bss(struct bss_descriptor * bss, | |||
1123 | 1107 | ||
1124 | /* Timestamp */ | 1108 | /* Timestamp */ |
1125 | bss->last_scanned = jiffies; | 1109 | bss->last_scanned = jiffies; |
1110 | libertas_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); | ||
1126 | 1111 | ||
1127 | ret = 0; | 1112 | ret = 0; |
1128 | 1113 | ||
@@ -1530,12 +1515,9 @@ static inline char *libertas_translate_scan(wlan_private *priv, | |||
1530 | iwe.u.bitrate.disabled = 0; | 1515 | iwe.u.bitrate.disabled = 0; |
1531 | iwe.u.bitrate.value = 0; | 1516 | iwe.u.bitrate.value = 0; |
1532 | 1517 | ||
1533 | for (j = 0; j < sizeof(bss->libertas_supported_rates); j++) { | 1518 | for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { |
1534 | u8 rate = bss->libertas_supported_rates[j]; | 1519 | /* Bit rate given in 500 kb/s units */ |
1535 | if (rate == 0) | 1520 | iwe.u.bitrate.value = bss->rates[j] * 500000; |
1536 | break; /* no more rates */ | ||
1537 | /* Bit rate given in 500 kb/s units (+ 0x80) */ | ||
1538 | iwe.u.bitrate.value = (rate & 0x7f) * 500000; | ||
1539 | current_val = iwe_stream_add_value(start, current_val, | 1521 | current_val = iwe_stream_add_value(start, current_val, |
1540 | stop, &iwe, IW_EV_PARAM_LEN); | 1522 | stop, &iwe, IW_EV_PARAM_LEN); |
1541 | } | 1523 | } |
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index 23c539c22634..8c3508b3257f 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h | |||
@@ -152,14 +152,14 @@ struct bss_descriptor { | |||
152 | u32 atimwindow; | 152 | u32 atimwindow; |
153 | 153 | ||
154 | u8 mode; | 154 | u8 mode; |
155 | u8 libertas_supported_rates[WLAN_SUPPORTED_RATES]; | 155 | /* zero-terminated array of supported data rates */ |
156 | u8 rates[MAX_RATES + 1]; | ||
156 | 157 | ||
157 | __le64 timestamp; //!< TSF value included in the beacon/probe response | 158 | __le64 timestamp; //!< TSF value included in the beacon/probe response |
158 | unsigned long last_scanned; | 159 | unsigned long last_scanned; |
159 | 160 | ||
160 | union ieeetypes_phyparamset phyparamset; | 161 | union ieeetypes_phyparamset phyparamset; |
161 | union IEEEtypes_ssparamset ssparamset; | 162 | union IEEEtypes_ssparamset ssparamset; |
162 | u8 datarates[WLAN_SUPPORTED_RATES]; | ||
163 | 163 | ||
164 | u64 networktsf; //!< TSF timestamp from the current firmware TSF | 164 | u64 networktsf; //!< TSF timestamp from the current firmware TSF |
165 | 165 | ||
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 115f02c010a1..0b805e32993a 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -22,14 +22,6 @@ | |||
22 | 22 | ||
23 | 23 | ||
24 | /** | 24 | /** |
25 | * the rates supported by the card | ||
26 | */ | ||
27 | static u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] = | ||
28 | { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, | ||
29 | 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 | ||
30 | }; | ||
31 | |||
32 | /** | ||
33 | * @brief Convert mw value to dbm value | 25 | * @brief Convert mw value to dbm value |
34 | * | 26 | * |
35 | * @param mw the value of mw | 27 | * @param mw the value of mw |
@@ -187,57 +179,21 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option) | |||
187 | } | 179 | } |
188 | 180 | ||
189 | /** | 181 | /** |
190 | * @brief Copy rates | 182 | * @brief Copy active data rates based on adapter mode and status |
191 | * | ||
192 | * @param dest A pointer to Dest Buf | ||
193 | * @param src A pointer to Src Buf | ||
194 | * @param len The len of Src Buf | ||
195 | * @return Number of rates copyed | ||
196 | */ | ||
197 | static inline int copyrates(u8 * dest, int pos, u8 * src, int len) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | for (i = 0; i < len && src[i]; i++, pos++) { | ||
202 | if (pos >= sizeof(u8) * WLAN_SUPPORTED_RATES) | ||
203 | break; | ||
204 | dest[pos] = src[i]; | ||
205 | } | ||
206 | |||
207 | return pos; | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * @brief Get active data rates | ||
212 | * | 183 | * |
213 | * @param adapter A pointer to wlan_adapter structure | 184 | * @param adapter A pointer to wlan_adapter structure |
214 | * @param rate The buf to return the active rates | 185 | * @param rate The buf to return the active rates |
215 | * @return The number of rates | ||
216 | */ | 186 | */ |
217 | static int get_active_data_rates(wlan_adapter * adapter, | 187 | static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates) |
218 | u8* rates) | ||
219 | { | 188 | { |
220 | int k = 0; | ||
221 | |||
222 | lbs_deb_enter(LBS_DEB_WEXT); | 189 | lbs_deb_enter(LBS_DEB_WEXT); |
223 | 190 | ||
224 | if (adapter->connect_status != LIBERTAS_CONNECTED) { | 191 | if (adapter->connect_status != LIBERTAS_CONNECTED) |
225 | if (adapter->mode == IW_MODE_INFRA) { | 192 | memcpy(rates, libertas_bg_rates, MAX_RATES); |
226 | lbs_deb_wext("infra\n"); | 193 | else |
227 | k = copyrates(rates, k, libertas_supported_rates, | 194 | memcpy(rates, adapter->curbssparams.rates, MAX_RATES); |
228 | sizeof(libertas_supported_rates)); | ||
229 | } else { | ||
230 | lbs_deb_wext("Adhoc G\n"); | ||
231 | k = copyrates(rates, k, libertas_adhoc_rates_g, | ||
232 | sizeof(libertas_adhoc_rates_g)); | ||
233 | } | ||
234 | } else { | ||
235 | k = copyrates(rates, 0, adapter->curbssparams.datarates, | ||
236 | adapter->curbssparams.numofrates); | ||
237 | } | ||
238 | 195 | ||
239 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k); | 196 | lbs_deb_leave(LBS_DEB_WEXT); |
240 | return k; | ||
241 | } | 197 | } |
242 | 198 | ||
243 | static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, | 199 | static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, |
@@ -673,7 +629,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, | |||
673 | wlan_adapter *adapter = priv->adapter; | 629 | wlan_adapter *adapter = priv->adapter; |
674 | struct iw_range *range = (struct iw_range *)extra; | 630 | struct iw_range *range = (struct iw_range *)extra; |
675 | struct chan_freq_power *cfp; | 631 | struct chan_freq_power *cfp; |
676 | u8 rates[WLAN_SUPPORTED_RATES]; | 632 | u8 rates[MAX_RATES + 1]; |
677 | 633 | ||
678 | u8 flag = 0; | 634 | u8 flag = 0; |
679 | 635 | ||
@@ -686,12 +642,10 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, | |||
686 | range->max_nwid = 0; | 642 | range->max_nwid = 0; |
687 | 643 | ||
688 | memset(rates, 0, sizeof(rates)); | 644 | memset(rates, 0, sizeof(rates)); |
689 | range->num_bitrates = get_active_data_rates(adapter, rates); | 645 | copy_active_data_rates(adapter, rates); |
690 | 646 | range->num_bitrates = strnlen(rates, IW_MAX_BITRATES); | |
691 | for (i = 0; i < min_t(__u8, range->num_bitrates, IW_MAX_BITRATES) && rates[i]; | 647 | for (i = 0; i < range->num_bitrates; i++) |
692 | i++) { | 648 | range->bitrate[i] = rates[i] * 500000; |
693 | range->bitrate[i] = (rates[i] & 0x7f) * 500000; | ||
694 | } | ||
695 | range->num_bitrates = i; | 649 | range->num_bitrates = i; |
696 | lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, | 650 | lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, |
697 | range->num_bitrates); | 651 | range->num_bitrates); |
@@ -1080,88 +1034,46 @@ out: | |||
1080 | return ret; | 1034 | return ret; |
1081 | } | 1035 | } |
1082 | 1036 | ||
1083 | /** | ||
1084 | * @brief use index to get the data rate | ||
1085 | * | ||
1086 | * @param index The index of data rate | ||
1087 | * @return data rate or 0 | ||
1088 | */ | ||
1089 | u32 libertas_index_to_data_rate(u8 index) | ||
1090 | { | ||
1091 | if (index >= sizeof(libertas_wlan_data_rates)) | ||
1092 | index = 0; | ||
1093 | |||
1094 | return libertas_wlan_data_rates[index]; | ||
1095 | } | ||
1096 | |||
1097 | /** | ||
1098 | * @brief use rate to get the index | ||
1099 | * | ||
1100 | * @param rate data rate | ||
1101 | * @return index or 0 | ||
1102 | */ | ||
1103 | u8 libertas_data_rate_to_index(u32 rate) | ||
1104 | { | ||
1105 | u8 *ptr; | ||
1106 | |||
1107 | if (rate) | ||
1108 | if ((ptr = memchr(libertas_wlan_data_rates, (u8) rate, | ||
1109 | sizeof(libertas_wlan_data_rates)))) | ||
1110 | return (ptr - libertas_wlan_data_rates); | ||
1111 | |||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, | 1037 | static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, |
1116 | struct iw_param *vwrq, char *extra) | 1038 | struct iw_param *vwrq, char *extra) |
1117 | { | 1039 | { |
1118 | wlan_private *priv = dev->priv; | 1040 | wlan_private *priv = dev->priv; |
1119 | wlan_adapter *adapter = priv->adapter; | 1041 | wlan_adapter *adapter = priv->adapter; |
1120 | u32 data_rate; | 1042 | u32 new_rate; |
1121 | u16 action; | 1043 | u16 action; |
1122 | int ret = 0; | 1044 | int ret = -EINVAL; |
1123 | u8 rates[WLAN_SUPPORTED_RATES]; | 1045 | u8 rates[MAX_RATES + 1]; |
1124 | u8 *rate; | ||
1125 | 1046 | ||
1126 | lbs_deb_enter(LBS_DEB_WEXT); | 1047 | lbs_deb_enter(LBS_DEB_WEXT); |
1127 | |||
1128 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); | 1048 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); |
1129 | 1049 | ||
1050 | /* Auto rate? */ | ||
1130 | if (vwrq->value == -1) { | 1051 | if (vwrq->value == -1) { |
1131 | action = CMD_ACT_SET_TX_AUTO; // Auto | 1052 | action = CMD_ACT_SET_TX_AUTO; |
1132 | adapter->is_datarate_auto = 1; | 1053 | adapter->auto_rate = 1; |
1133 | adapter->datarate = 0; | 1054 | adapter->cur_rate = 0; |
1134 | } else { | 1055 | } else { |
1135 | if (vwrq->value % 100000) { | 1056 | if (vwrq->value % 100000) |
1136 | return -EINVAL; | 1057 | goto out; |
1137 | } | ||
1138 | |||
1139 | data_rate = vwrq->value / 500000; | ||
1140 | 1058 | ||
1141 | memset(rates, 0, sizeof(rates)); | 1059 | memset(rates, 0, sizeof(rates)); |
1142 | get_active_data_rates(adapter, rates); | 1060 | copy_active_data_rates(adapter, rates); |
1143 | rate = rates; | 1061 | new_rate = vwrq->value / 500000; |
1144 | while (*rate) { | 1062 | if (!memchr(rates, new_rate, sizeof(rates))) { |
1145 | lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate, | 1063 | lbs_pr_alert("fixed data rate 0x%X out of range\n", |
1146 | data_rate); | 1064 | new_rate); |
1147 | if ((*rate & 0x7f) == (data_rate & 0x7f)) | 1065 | goto out; |
1148 | break; | ||
1149 | rate++; | ||
1150 | } | ||
1151 | if (!*rate) { | ||
1152 | lbs_pr_alert("fixed data rate 0x%X out " | ||
1153 | "of range\n", data_rate); | ||
1154 | return -EINVAL; | ||
1155 | } | 1066 | } |
1156 | 1067 | ||
1157 | adapter->datarate = data_rate; | 1068 | adapter->cur_rate = new_rate; |
1158 | action = CMD_ACT_SET_TX_FIX_RATE; | 1069 | action = CMD_ACT_SET_TX_FIX_RATE; |
1159 | adapter->is_datarate_auto = 0; | 1070 | adapter->auto_rate = 0; |
1160 | } | 1071 | } |
1161 | 1072 | ||
1162 | ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, | 1073 | ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, |
1163 | action, CMD_OPTION_WAITFORRSP, 0, NULL); | 1074 | action, CMD_OPTION_WAITFORRSP, 0, NULL); |
1164 | 1075 | ||
1076 | out: | ||
1165 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | 1077 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); |
1166 | return ret; | 1078 | return ret; |
1167 | } | 1079 | } |
@@ -1174,14 +1086,19 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, | |||
1174 | 1086 | ||
1175 | lbs_deb_enter(LBS_DEB_WEXT); | 1087 | lbs_deb_enter(LBS_DEB_WEXT); |
1176 | 1088 | ||
1177 | if (adapter->is_datarate_auto) { | 1089 | if (adapter->connect_status == LIBERTAS_CONNECTED) { |
1178 | vwrq->fixed = 0; | 1090 | vwrq->value = adapter->cur_rate * 500000; |
1091 | |||
1092 | if (adapter->auto_rate) | ||
1093 | vwrq->fixed = 0; | ||
1094 | else | ||
1095 | vwrq->fixed = 1; | ||
1096 | |||
1179 | } else { | 1097 | } else { |
1180 | vwrq->fixed = 1; | 1098 | vwrq->fixed = 0; |
1099 | vwrq->value = 0; | ||
1181 | } | 1100 | } |
1182 | 1101 | ||
1183 | vwrq->value = adapter->datarate * 500000; | ||
1184 | |||
1185 | lbs_deb_leave(LBS_DEB_WEXT); | 1102 | lbs_deb_leave(LBS_DEB_WEXT); |
1186 | return 0; | 1103 | return 0; |
1187 | } | 1104 | } |