aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/libertas/cfg.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index b60f6611506..6b35d057426 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -257,6 +257,29 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
257 return sizeof(rate_tlv->header) + i; 257 return sizeof(rate_tlv->header) + i;
258} 258}
259 259
260/* Add common rates from a TLV and return the new end of the TLV */
261static u8 *
262add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
263{
264 int hw, ap, ap_max = ie[1];
265 u8 hw_rate;
266
267 /* Advance past IE header */
268 ie += 2;
269
270 lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
271
272 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
273 hw_rate = lbs_rates[hw].bitrate / 5;
274 for (ap = 0; ap < ap_max; ap++) {
275 if (hw_rate == (ie[ap] & 0x7f)) {
276 *tlv++ = ie[ap];
277 *nrates = *nrates + 1;
278 }
279 }
280 }
281 return tlv;
282}
260 283
261/* 284/*
262 * Adds a TLV with all rates the hardware *and* BSS supports. 285 * Adds a TLV with all rates the hardware *and* BSS supports.
@@ -264,8 +287,11 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
264static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) 287static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
265{ 288{
266 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; 289 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
267 const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); 290 const u8 *rates_eid, *ext_rates_eid;
268 int n; 291 int n = 0;
292
293 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
294 ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
269 295
270 /* 296 /*
271 * 01 00 TLV_TYPE_RATES 297 * 01 00 TLV_TYPE_RATES
@@ -275,26 +301,21 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
275 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 301 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
276 tlv += sizeof(rate_tlv->header); 302 tlv += sizeof(rate_tlv->header);
277 303
278 if (!rates_eid) { 304 /* Add basic rates */
305 if (rates_eid) {
306 tlv = add_ie_rates(tlv, rates_eid, &n);
307
308 /* Add extended rates, if any */
309 if (ext_rates_eid)
310 tlv = add_ie_rates(tlv, ext_rates_eid, &n);
311 } else {
312 lbs_deb_assoc("assoc: bss had no basic rate IE\n");
279 /* Fallback: add basic 802.11b rates */ 313 /* Fallback: add basic 802.11b rates */
280 *tlv++ = 0x82; 314 *tlv++ = 0x82;
281 *tlv++ = 0x84; 315 *tlv++ = 0x84;
282 *tlv++ = 0x8b; 316 *tlv++ = 0x8b;
283 *tlv++ = 0x96; 317 *tlv++ = 0x96;
284 n = 4; 318 n = 4;
285 } else {
286 int hw, ap;
287 u8 ap_max = rates_eid[1];
288 n = 0;
289 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
290 u8 hw_rate = lbs_rates[hw].bitrate / 5;
291 for (ap = 0; ap < ap_max; ap++) {
292 if (hw_rate == (rates_eid[ap+2] & 0x7f)) {
293 *tlv++ = rates_eid[ap+2];
294 n++;
295 }
296 }
297 }
298 } 319 }
299 320
300 rate_tlv->header.len = cpu_to_le16(n); 321 rate_tlv->header.len = cpu_to_le16(n);
@@ -1008,6 +1029,7 @@ static int lbs_associate(struct lbs_private *priv,
1008 int status; 1029 int status;
1009 int ret; 1030 int ret;
1010 u8 *pos = &(cmd->iebuf[0]); 1031 u8 *pos = &(cmd->iebuf[0]);
1032 u8 *tmp;
1011 1033
1012 lbs_deb_enter(LBS_DEB_CFG80211); 1034 lbs_deb_enter(LBS_DEB_CFG80211);
1013 1035
@@ -1052,7 +1074,9 @@ static int lbs_associate(struct lbs_private *priv,
1052 pos += lbs_add_cf_param_tlv(pos); 1074 pos += lbs_add_cf_param_tlv(pos);
1053 1075
1054 /* add rates TLV */ 1076 /* add rates TLV */
1077 tmp = pos + 4; /* skip Marvell IE header */
1055 pos += lbs_add_common_rates_tlv(pos, bss); 1078 pos += lbs_add_common_rates_tlv(pos, bss);
1079 lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
1056 1080
1057 /* add auth type TLV */ 1081 /* add auth type TLV */
1058 if (priv->fwrelease >= 0x09000000) 1082 if (priv->fwrelease >= 0x09000000)