diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 57 |
1 files changed, 17 insertions, 40 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 0bc5ac56f283..9524564f873b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1381,38 +1381,6 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
1381 | } | 1381 | } |
1382 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); | 1382 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); |
1383 | 1383 | ||
1384 | static inline int rt2800_find_wcid(struct rt2x00_dev *rt2x00dev) | ||
1385 | { | ||
1386 | struct mac_wcid_entry wcid_entry; | ||
1387 | int idx; | ||
1388 | u32 offset; | ||
1389 | |||
1390 | /* | ||
1391 | * Search for the first free WCID entry and return the corresponding | ||
1392 | * index. | ||
1393 | * | ||
1394 | * Make sure the WCID starts _after_ the last possible shared key | ||
1395 | * entry (>32). | ||
1396 | * | ||
1397 | * Since parts of the pairwise key table might be shared with | ||
1398 | * the beacon frame buffers 6 & 7 we should only write into the | ||
1399 | * first 222 entries. | ||
1400 | */ | ||
1401 | for (idx = 33; idx <= 222; idx++) { | ||
1402 | offset = MAC_WCID_ENTRY(idx); | ||
1403 | rt2800_register_multiread(rt2x00dev, offset, &wcid_entry, | ||
1404 | sizeof(wcid_entry)); | ||
1405 | if (is_broadcast_ether_addr(wcid_entry.mac)) | ||
1406 | return idx; | ||
1407 | } | ||
1408 | |||
1409 | /* | ||
1410 | * Use -1 to indicate that we don't have any more space in the WCID | ||
1411 | * table. | ||
1412 | */ | ||
1413 | return -1; | ||
1414 | } | ||
1415 | |||
1416 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | 1384 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, |
1417 | struct rt2x00lib_crypto *crypto, | 1385 | struct rt2x00lib_crypto *crypto, |
1418 | struct ieee80211_key_conf *key) | 1386 | struct ieee80211_key_conf *key) |
@@ -1425,7 +1393,7 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
1425 | * Allow key configuration only for STAs that are | 1393 | * Allow key configuration only for STAs that are |
1426 | * known by the hw. | 1394 | * known by the hw. |
1427 | */ | 1395 | */ |
1428 | if (crypto->wcid < 0) | 1396 | if (crypto->wcid > WCID_END) |
1429 | return -ENOSPC; | 1397 | return -ENOSPC; |
1430 | key->hw_key_idx = crypto->wcid; | 1398 | key->hw_key_idx = crypto->wcid; |
1431 | 1399 | ||
@@ -1455,11 +1423,13 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, | |||
1455 | { | 1423 | { |
1456 | int wcid; | 1424 | int wcid; |
1457 | struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); | 1425 | struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); |
1426 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
1458 | 1427 | ||
1459 | /* | 1428 | /* |
1460 | * Find next free WCID. | 1429 | * Search for the first free WCID entry and return the corresponding |
1430 | * index. | ||
1461 | */ | 1431 | */ |
1462 | wcid = rt2800_find_wcid(rt2x00dev); | 1432 | wcid = find_first_zero_bit(drv_data->sta_ids, STA_IDS_SIZE) + WCID_START; |
1463 | 1433 | ||
1464 | /* | 1434 | /* |
1465 | * Store selected wcid even if it is invalid so that we can | 1435 | * Store selected wcid even if it is invalid so that we can |
@@ -1471,9 +1441,11 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, | |||
1471 | * No space left in the device, however, we can still communicate | 1441 | * No space left in the device, however, we can still communicate |
1472 | * with the STA -> No error. | 1442 | * with the STA -> No error. |
1473 | */ | 1443 | */ |
1474 | if (wcid < 0) | 1444 | if (wcid > WCID_END) |
1475 | return 0; | 1445 | return 0; |
1476 | 1446 | ||
1447 | __set_bit(wcid - WCID_START, drv_data->sta_ids); | ||
1448 | |||
1477 | /* | 1449 | /* |
1478 | * Clean up WCID attributes and write STA address to the device. | 1450 | * Clean up WCID attributes and write STA address to the device. |
1479 | */ | 1451 | */ |
@@ -1487,11 +1459,16 @@ EXPORT_SYMBOL_GPL(rt2800_sta_add); | |||
1487 | 1459 | ||
1488 | int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid) | 1460 | int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid) |
1489 | { | 1461 | { |
1462 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
1463 | |||
1464 | if (wcid > WCID_END) | ||
1465 | return 0; | ||
1490 | /* | 1466 | /* |
1491 | * Remove WCID entry, no need to clean the attributes as they will | 1467 | * Remove WCID entry, no need to clean the attributes as they will |
1492 | * get renewed when the WCID is reused. | 1468 | * get renewed when the WCID is reused. |
1493 | */ | 1469 | */ |
1494 | rt2800_config_wcid(rt2x00dev, NULL, wcid); | 1470 | rt2800_config_wcid(rt2x00dev, NULL, wcid); |
1471 | __clear_bit(wcid - WCID_START, drv_data->sta_ids); | ||
1495 | 1472 | ||
1496 | return 0; | 1473 | return 0; |
1497 | } | 1474 | } |
@@ -7968,11 +7945,11 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
7968 | /* | 7945 | /* |
7969 | * Don't allow aggregation for stations the hardware isn't aware | 7946 | * Don't allow aggregation for stations the hardware isn't aware |
7970 | * of because tx status reports for frames to an unknown station | 7947 | * of because tx status reports for frames to an unknown station |
7971 | * always contain wcid=255 and thus we can't distinguish between | 7948 | * always contain wcid=WCID_END+1 and thus we can't distinguish |
7972 | * multiple stations which leads to unwanted situations when the | 7949 | * between multiple stations which leads to unwanted situations |
7973 | * hw reorders frames due to aggregation. | 7950 | * when the hw reorders frames due to aggregation. |
7974 | */ | 7951 | */ |
7975 | if (sta_priv->wcid < 0) | 7952 | if (sta_priv->wcid > WCID_END) |
7976 | return 1; | 7953 | return 1; |
7977 | 7954 | ||
7978 | switch (action) { | 7955 | switch (action) { |