From e5fd91f1ef340da553f7a79da9540c3db711c937 Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Tue, 8 Sep 2015 01:01:14 -0300 Subject: Linux-libre 4.2-gnu --- drivers/net/wireless/rt2x00/rt2800lib.c | 92 +++++++++++++-------------------- 1 file changed, 35 insertions(+), 57 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index be2d54f25..9524564f8 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, } EXPORT_SYMBOL_GPL(rt2800_config_shared_key); -static inline int rt2800_find_wcid(struct rt2x00_dev *rt2x00dev) -{ - struct mac_wcid_entry wcid_entry; - int idx; - u32 offset; - - /* - * Search for the first free WCID entry and return the corresponding - * index. - * - * Make sure the WCID starts _after_ the last possible shared key - * entry (>32). - * - * Since parts of the pairwise key table might be shared with - * the beacon frame buffers 6 & 7 we should only write into the - * first 222 entries. - */ - for (idx = 33; idx <= 222; idx++) { - offset = MAC_WCID_ENTRY(idx); - rt2800_register_multiread(rt2x00dev, offset, &wcid_entry, - sizeof(wcid_entry)); - if (is_broadcast_ether_addr(wcid_entry.mac)) - return idx; - } - - /* - * Use -1 to indicate that we don't have any more space in the WCID - * table. - */ - return -1; -} - int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_crypto *crypto, struct ieee80211_key_conf *key) @@ -1425,7 +1393,7 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * Allow key configuration only for STAs that are * known by the hw. */ - if (crypto->wcid < 0) + if (crypto->wcid > WCID_END) return -ENOSPC; key->hw_key_idx = crypto->wcid; @@ -1455,11 +1423,13 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, { int wcid; struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; /* - * Find next free WCID. + * Search for the first free WCID entry and return the corresponding + * index. */ - wcid = rt2800_find_wcid(rt2x00dev); + wcid = find_first_zero_bit(drv_data->sta_ids, STA_IDS_SIZE) + WCID_START; /* * 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, * No space left in the device, however, we can still communicate * with the STA -> No error. */ - if (wcid < 0) + if (wcid > WCID_END) return 0; + __set_bit(wcid - WCID_START, drv_data->sta_ids); + /* * Clean up WCID attributes and write STA address to the device. */ @@ -1487,11 +1459,16 @@ EXPORT_SYMBOL_GPL(rt2800_sta_add); int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + + if (wcid > WCID_END) + return 0; /* * Remove WCID entry, no need to clean the attributes as they will * get renewed when the WCID is reused. */ rt2800_config_wcid(rt2x00dev, NULL, wcid); + __clear_bit(wcid - WCID_START, drv_data->sta_ids); return 0; } @@ -1513,8 +1490,7 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, !(filter_flags & FIF_FCSFAIL)); rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR, !(filter_flags & FIF_PLCPFAIL)); - rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, - !(filter_flags & FIF_PROMISC_IN_BSS)); + rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, 1); rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0); rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1); rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST, @@ -7498,13 +7474,12 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. */ - rt2x00dev->hw->flags = - IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_AMPDU_AGGREGATION | - IEEE80211_HW_REPORTS_TX_ACK_STATUS | - IEEE80211_HW_SUPPORTS_HT_CCK_RATES; + ieee80211_hw_set(rt2x00dev->hw, SUPPORTS_HT_CCK_RATES); + ieee80211_hw_set(rt2x00dev->hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(rt2x00dev->hw, AMPDU_AGGREGATION); + ieee80211_hw_set(rt2x00dev->hw, PS_NULLFUNC_STACK); + ieee80211_hw_set(rt2x00dev->hw, SIGNAL_DBM); + ieee80211_hw_set(rt2x00dev->hw, SUPPORTS_PS); /* * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices @@ -7514,8 +7489,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * infinitly and thus dropping it after some time. */ if (!rt2x00_is_usb(rt2x00dev)) - rt2x00dev->hw->flags |= - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING); SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, @@ -7818,21 +7792,25 @@ EXPORT_SYMBOL_GPL(rt2800_probe_hw); /* * IEEE80211 stack callback functions. */ -void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, - u16 *iv16) +void rt2800_get_key_seq(struct ieee80211_hw *hw, + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { struct rt2x00_dev *rt2x00dev = hw->priv; struct mac_iveiv_entry iveiv_entry; u32 offset; - offset = MAC_IVEIV_ENTRY(hw_key_idx); + if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + return; + + offset = MAC_IVEIV_ENTRY(key->hw_key_idx); rt2800_register_multiread(rt2x00dev, offset, &iveiv_entry, sizeof(iveiv_entry)); - memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); - memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); + memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2); + memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4); } -EXPORT_SYMBOL_GPL(rt2800_get_tkip_seq); +EXPORT_SYMBOL_GPL(rt2800_get_key_seq); int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { @@ -7967,11 +7945,11 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* * Don't allow aggregation for stations the hardware isn't aware * of because tx status reports for frames to an unknown station - * always contain wcid=255 and thus we can't distinguish between - * multiple stations which leads to unwanted situations when the - * hw reorders frames due to aggregation. + * always contain wcid=WCID_END+1 and thus we can't distinguish + * between multiple stations which leads to unwanted situations + * when the hw reorders frames due to aggregation. */ - if (sta_priv->wcid < 0) + if (sta_priv->wcid > WCID_END) return 1; switch (action) { -- cgit v1.2.3-54-g00ecf