Skip to content

Commit

Permalink
iwlwifi: mvm: use firmware station lookup, combine code
Browse files Browse the repository at this point in the history
In most cases, the firmware will already match the station that
we received a given frame from and tell us the station ID in the
RX status, so we can look up the station from that. This lets us
skip the (more expensive) hash table lookup in mac80211.

Also change the fallback case (no station info from the firmware)
to not attempt to look up a multicast source address.

While at it, also combine all the code using the station into a
single if block.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
  • Loading branch information
Johannes Berg authored and Emmanuel Grumbach committed Dec 1, 2015
1 parent 04b0899 commit a399f98
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
3 changes: 2 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ enum iwl_mvm_rx_status {
RX_MPDU_RES_STATUS_CSUM_DONE = BIT(16),
RX_MPDU_RES_STATUS_CSUM_OK = BIT(17),
RX_MPDU_RES_STATUS_HASH_INDEX_MSK = (0x3F0000),
RX_MPDU_RES_STATUS_STA_ID_MSK = (0x1f000000),
RX_MDPU_RES_STATUS_STA_ID_SHIFT = 24,
RX_MPDU_RES_STATUS_STA_ID_MSK = 0x1f << RX_MDPU_RES_STATUS_STA_ID_SHIFT,
RX_MPDU_RES_STATUS_RRF_KILL = BIT(29),
RX_MPDU_RES_STATUS_FILTERING_MSK = (0xc00000),
RX_MPDU_RES_STATUS2_FILTERING_MSK = (0xc0000000),
Expand Down
43 changes: 27 additions & 16 deletions drivers/net/wireless/intel/iwlwifi/mvm/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include "iwl-trans.h"
#include "mvm.h"
Expand Down Expand Up @@ -262,7 +263,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_rx_phy_info *phy_info;
struct iwl_rx_mpdu_res_start *rx_res;
struct ieee80211_sta *sta;
struct ieee80211_sta *sta = NULL;
struct sk_buff *skb;
u32 len;
u32 ampdu_status;
Expand Down Expand Up @@ -333,22 +334,33 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
(unsigned long long)rx_status->mactime);

rcu_read_lock();
/*
* We have tx blocked stations (with CS bit). If we heard frames from
* a blocked station on a new channel we can TX to it again.
*/
if (unlikely(mvm->csa_tx_block_bcn_timeout)) {
sta = ieee80211_find_sta(
rcu_dereference(mvm->csa_tx_blocked_vif), hdr->addr2);
if (sta)
iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);
if (rx_pkt_status & RX_MPDU_RES_STATUS_SRC_STA_FOUND) {
u32 id = rx_pkt_status & RX_MPDU_RES_STATUS_STA_ID_MSK;

id >>= RX_MDPU_RES_STATUS_STA_ID_SHIFT;

if (!WARN_ON_ONCE(id >= IWL_MVM_STATION_COUNT)) {
sta = rcu_dereference(mvm->fw_id_to_mac_id[id]);
if (IS_ERR(sta))
sta = NULL;
}
} else if (!is_multicast_ether_addr(hdr->addr2)) {
/* This is fine since we prevent two stations with the same
* address from being added.
*/
sta = ieee80211_find_sta_by_ifaddr(mvm->hw, hdr->addr2, NULL);
}

/* This is fine since we don't support multiple AP interfaces */
sta = ieee80211_find_sta_by_ifaddr(mvm->hw, hdr->addr2, NULL);
if (sta) {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);

/* We have tx blocked stations (with CS bit). If we heard
* frames from a blocked station on a new channel we can
* TX to it again.
*/
if (unlikely(mvm->csa_tx_block_bcn_timeout))
iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);

rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status);

if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) &&
Expand All @@ -369,11 +381,10 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
if (trig_check && rx_status->signal < rssi)
iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL);
}
}

if (sta && ieee80211_is_data(hdr->frame_control))
iwl_mvm_rx_csum(sta, skb, rx_pkt_status);

if (ieee80211_is_data(hdr->frame_control))
iwl_mvm_rx_csum(sta, skb, rx_pkt_status);
}
rcu_read_unlock();

/* set the preamble flag if appropriate */
Expand Down

0 comments on commit a399f98

Please sign in to comment.