diff options
-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 | } |