struct rhash_head rhash_addr;
};
-struct ath12k_reoq_buf {
- void *vaddr;
- dma_addr_t paddr_aligned;
- u32 size;
-};
-
struct ath12k_sta {
struct ath12k_vif *ahvif;
enum hal_pn_type pn_type;
u8 num_peer;
enum ieee80211_sta_state state;
-
- struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1];
};
#define ATH12K_HALF_20MHZ_BW 10
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n",
addr, vdev_id);
spin_unlock_bh(&dp->dp_lock);
}
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
- crypto_free_shash(peer->tfm_mmic);
- peer->dp_setup_done = false;
+ crypto_free_shash(peer->dp_peer->tfm_mmic);
+ peer->dp_peer->dp_setup_done = false;
spin_unlock_bh(&dp->dp_lock);
}
}
rcu_read_lock();
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, usr_stats->peer_id);
+ peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, usr_stats->peer_id);
if (!peer || !peer->sta) {
- spin_unlock_bh(&dp->dp_lock);
rcu_read_unlock();
return;
}
arsta = ath12k_dp_link_peer_to_link_sta(ab, peer);
if (!arsta) {
- spin_unlock_bh(&dp->dp_lock);
rcu_read_unlock();
return;
}
HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
}
- spin_unlock_bh(&dp->dp_lock);
rcu_read_unlock();
}
ppdu_info->delay_ba) {
for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) {
peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
- if (!peer) {
- spin_unlock_bh(&dp->dp_lock);
+ peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id);
+ if (!peer)
continue;
- }
usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
if (usr_stats->delay_ba)
ath12k_copy_to_delay_stats(peer, usr_stats);
- spin_unlock_bh(&dp->dp_lock);
}
}
(ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) {
for (i = 0; i < ppdu_info->bar_num_users; i++) {
peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
- if (!peer) {
- spin_unlock_bh(&dp->dp_lock);
+ peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id);
+ if (!peer)
continue;
- }
usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
if (peer->delayba_flag)
ath12k_copy_to_bar(peer, usr_stats);
- spin_unlock_bh(&dp->dp_lock);
}
}
bool is_mcbc = rxcb->is_mcbc;
bool is_eapol_tkip = rxcb->is_eapol;
struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
+ u8 addr[ETH_ALEN] = {};
status->link_valid = 0;
ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc);
+ rcu_read_lock();
spin_lock_bh(&dp->dp_lock);
rx_info.addr2_present = false;
- peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, &rx_info);
+ peer = ath12k_dp_rx_h_find_link_peer(dp_pdev, msdu, &rx_info);
if (peer && peer->sta) {
pubsta = peer->sta;
+ memcpy(addr, peer->addr, ETH_ALEN);
if (pubsta->valid_links) {
status->link_valid = 1;
status->link_id = peer->link_id;
}
spin_unlock_bh(&dp->dp_lock);
+ rcu_read_unlock();
ath12k_dbg(ab, ATH12K_DBG_DATA,
"rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
msdu,
msdu->len,
- peer ? peer->addr : NULL,
+ addr,
rxcb->tid,
(is_mcbc) ? "mcast" : "ucast",
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
goto free_skb;
rcu_read_lock();
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, ppdu_info->peer_id);
+ peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id);
if (!peer || !peer->sta) {
ath12k_dbg(ab, ATH12K_DBG_DATA,
"failed to find the peer with monitor peer_id %d\n",
if (!arsta) {
ath12k_warn(ab, "link sta not found on peer %pM id %d\n",
peer->addr, peer->peer_id);
- spin_unlock_bh(&dp->dp_lock);
rcu_read_unlock();
dev_kfree_skb_any(skb);
continue;
}
next_skb:
- spin_unlock_bh(&dp->dp_lock);
rcu_read_unlock();
free_skb:
dev_kfree_skb_any(skb);
return NULL;
}
-struct ath12k_dp_link_peer *
-ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id)
+static struct ath12k_dp_link_peer *
+ath12k_dp_link_peer_search_by_id(struct ath12k_dp *dp, int peer_id)
{
struct ath12k_dp_link_peer *peer;
spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
+ peer = ath12k_dp_link_peer_search_by_id(dp, peer_id);
if (!peer) {
ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n",
peer_id);
((dp->device_id << ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT) | peer_id);
}
+struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev,
+ u16 peer_id)
+{
+ u16 index;
+ struct ath12k_dp *dp = dp_pdev->dp;
+
+ RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
+ "ath12k dp peer find by peerid index called without rcu lock");
+
+ if (!peer_id || peer_id >= ATH12K_DP_PEER_ID_INVALID)
+ return NULL;
+
+ index = ath12k_dp_peer_get_peerid_index(dp, peer_id);
+
+ return rcu_dereference(dp_pdev->dp_hw->dp_peers[index]);
+}
+
+struct ath12k_dp_link_peer *
+ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id)
+{
+ struct ath12k_dp_peer *dp_peer = NULL;
+ u8 link_id;
+
+ RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
+ "ath12k dp link peer find by peerid index called without rcu lock");
+
+ if (dp_pdev->hw_link_id >= ATH12K_GROUP_MAX_RADIO)
+ return NULL;
+
+ dp_peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id);
+ if (!dp_peer)
+ return NULL;
+
+ link_id = dp_peer->hw_links[dp_pdev->hw_link_id];
+
+ return rcu_dereference(dp_peer->link_peers[link_id]);
+}
+
int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr,
struct ath12k_dp_peer_create_params *params)
{
dp_peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
dp_peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
+ dp_peer->ucast_ra_only = params->ucast_ra_only;
spin_lock_bh(&dp_hw->peer_lock);
u8 pdev_idx;
u16 hw_peer_id;
- /* protected by ab->data_lock */
- struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
- struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
-
- /* Info used in MMIC verification of
- * RX fragments
- */
- struct crypto_shash *tfm_mmic;
- u8 mcast_keyidx;
- u8 ucast_keyidx;
- u16 sec_type;
- u16 sec_type_grp;
struct ppdu_user_delayba ppdu_stats_delayba;
bool delayba_flag;
bool is_authorized;
bool mlo;
/* protected by ab->data_lock */
- bool dp_setup_done;
u16 ml_id;
/* for reference to ath12k_link_sta */
u8 link_id;
- bool ucast_ra_only;
/* peer addr based rhashtable list pointer */
struct rhash_head rhash_addr;
u8 hw_link_id;
+ u32 rx_tid_active_bitmask;
};
void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id);
struct ath12k_dp_peer {
struct list_head list;
- struct ieee80211_sta *sta;
- int peer_id;
- u8 addr[ETH_ALEN];
bool is_mlo;
+ bool dp_setup_done;
- struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS];
-
- u16 sec_type;
- u16 sec_type_grp;
+ u8 ucast_keyidx;
+ u8 addr[ETH_ALEN];
+ u8 mcast_keyidx;
bool ucast_ra_only;
+ int peer_id;
+ struct ieee80211_sta *sta;
+
u8 hw_links[ATH12K_GROUP_MAX_RADIO];
+
+ u16 sec_type_grp;
+ u16 sec_type;
+
+ /* Info used in MMIC verification of * RX fragments */
+ struct crypto_shash *tfm_mmic;
+ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
+ struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS];
+ struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1];
+ struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
};
struct ath12k_dp_link_peer *
int vdev_id, const u8 *addr);
struct ath12k_dp_link_peer *
ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr);
-struct ath12k_dp_link_peer *
-ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id);
bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id);
struct ath12k_dp_link_peer *
ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash);
u8 *addr,
struct ieee80211_sta *sta);
u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id);
+struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev,
+ u16 peer_id);
+struct ath12k_dp_link_peer *
+ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id);
#endif
lockdep_assert_held(&dp->dp_lock);
+ if (!peer->primary_link)
+ return;
+
for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
- rx_tid = &peer->rx_tid[i];
+ rx_tid = &peer->dp_peer->rx_tid[i];
ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i);
ath12k_dp_rx_frags_cleanup(rx_tid, true);
struct ath12k_base *ab = ar->ab;
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
struct ath12k_dp_link_peer *peer;
- struct ath12k_sta *ahsta;
struct ath12k_dp_rx_tid *rx_tid;
dma_addr_t paddr_aligned;
int ret;
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
ath12k_warn(ab, "failed to find the peer to set up rx tid\n");
return -ENOENT;
return -EINVAL;
}
- rx_tid = &peer->rx_tid[tid];
+ rx_tid = &peer->dp_peer->rx_tid[tid];
/* Update the tid queue if it is already setup */
- if (rx_tid->active) {
+ if (peer->rx_tid_active_bitmask & (1 << tid)) {
ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid,
ba_win_sz, ssn, true);
spin_unlock_bh(&dp->dp_lock);
rx_tid->ba_win_sz = ba_win_sz;
- ahsta = ath12k_sta_to_ahsta(peer->sta);
- ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type);
+ ret = ath12k_wifi7_dp_rx_assign_reoq(ab, peer->dp_peer, rx_tid, ssn, pn_type);
if (ret) {
spin_unlock_bh(&dp->dp_lock);
ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid);
return ret;
}
+ peer->rx_tid_active_bitmask |= (1 << tid);
+
paddr_aligned = rx_tid->qbuf.paddr_aligned;
if (ab->hw_params->reoq_lut_support) {
/* Update the REO queue LUT at the corresponding peer id
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, arsta->addr);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n");
return -ENOENT;
}
- active = peer->rx_tid[params->tid].active;
+ if (ab->hw_params->dp_primary_link_only &&
+ !peer->primary_link) {
+ spin_unlock_bh(&dp->dp_lock);
+ return 0;
+ }
+ active = peer->rx_tid_active_bitmask & (1 << params->tid);
if (!active) {
spin_unlock_bh(&dp->dp_lock);
return 0;
}
- ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false);
+ ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->dp_peer->rx_tid,
+ 1, 0, false);
spin_unlock_bh(&dp->dp_lock);
if (ret) {
ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n",
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id,
peer_addr);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n",
peer_addr);
}
for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
- rx_tid = &peer->rx_tid[tid];
- if (!rx_tid->active)
+ if (!(peer->rx_tid_active_bitmask & (1 << tid)))
continue;
+ rx_tid = &peer->dp_peer->rx_tid[tid];
+
ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher,
key_cmd);
ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid,
}
struct ath12k_dp_link_peer *
-ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu,
+ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
struct hal_rx_desc_data *rx_info)
{
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
struct ath12k_dp_link_peer *peer = NULL;
+ struct ath12k_dp *dp = dp_pdev->dp;
lockdep_assert_held(&dp->dp_lock);
if (rxcb->peer_id)
- peer = ath12k_dp_link_peer_find_by_id(dp, rxcb->peer_id);
+ peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, rxcb->peer_id);
if (peer)
return peer;
struct ath12k_base *ab = dp->ab;
struct ieee80211_rx_status *rx_status;
struct ieee80211_sta *pubsta;
- struct ath12k_dp_link_peer *peer;
+ struct ath12k_dp_peer *peer;
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
struct ieee80211_rx_status *status = rx_info->rx_status;
u8 decap = rx_info->decap_type;
bool is_mcbc = rxcb->is_mcbc;
bool is_eapol = rxcb->is_eapol;
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id);
pubsta = peer ? peer->sta : NULL;
if (pubsta && pubsta->valid_links) {
status->link_valid = 1;
- status->link_id = peer->link_id;
+ status->link_id = peer->hw_links[rxcb->hw_link_id];
}
- spin_unlock_bh(&dp->dp_lock);
-
ath12k_dbg(ab, ATH12K_DBG_DATA,
"rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
msdu,
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
crypto_free_shash(tfm);
ath12k_warn(ab, "failed to find the peer to set up fragment info\n");
}
for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
- rx_tid = &peer->rx_tid[i];
+ rx_tid = &peer->dp_peer->rx_tid[i];
rx_tid->dp = dp;
timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0);
skb_queue_head_init(&rx_tid->rx_frags);
}
- peer->tfm_mmic = tfm;
- peer->dp_setup_done = true;
+ peer->dp_peer->tfm_mmic = tfm;
+ peer->dp_peer->dp_setup_done = true;
spin_unlock_bh(&dp->dp_lock);
return 0;
#define DP_MAX_NWIFI_HDR_LEN 30
+struct ath12k_reoq_buf {
+ void *vaddr;
+ dma_addr_t paddr_aligned;
+ u32 size;
+};
+
struct ath12k_dp_rx_tid {
u8 tid;
u32 ba_win_sz;
- bool active;
struct ath12k_reoq_buf qbuf;
/* Info related to rx fragments */
u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
struct hal_rx_desc *desc);
struct ath12k_dp_link_peer *
-ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu,
+ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
struct hal_rx_desc_data *rx_info);
u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
struct hal_rx_desc *desc);
spin_lock_bh(&dp->dp_lock);
list_for_each_entry_safe(peer, tmp, &dp->peers, list) {
/* Skip Rx TID cleanup for self peer */
- if (peer->sta)
+ if (peer->sta && peer->dp_peer)
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
/* cleanup dp peer */
struct ath12k_dp_link_peer *peer;
int first_errno = 0;
int ret;
- int i;
+ int i, len;
u32 flags = 0;
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
+ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1] = {};
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, addr);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
return -ENOENT;
}
+ len = ARRAY_SIZE(peer->dp_peer->keys);
+ for (i = 0; i < len; i++) {
+ if (!peer->dp_peer->keys[i])
+ continue;
+
+ keys[i] = peer->dp_peer->keys[i];
+ peer->dp_peer->keys[i] = NULL;
+ }
+
spin_unlock_bh(&dp->dp_lock);
- for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
- if (!peer->keys[i])
+ for (i = 0; i < len; i++) {
+ if (!keys[i])
continue;
/* key flags are not required to delete the key */
- ret = ath12k_install_key(arvif, peer->keys[i],
+ ret = ath12k_install_key(arvif, keys[i],
DISABLE_KEY, addr, flags);
if (ret < 0 && first_errno == 0)
first_errno = ret;
if (ret < 0)
ath12k_warn(ab, "failed to remove peer key %d: %d\n",
i, ret);
-
- spin_lock_bh(&dp->dp_lock);
- peer->keys[i] = NULL;
- spin_unlock_bh(&dp->dp_lock);
}
return first_errno;
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id,
peer_addr);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
if (cmd == SET_KEY) {
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id,
peer_addr);
- if (peer && cmd == SET_KEY) {
- peer->keys[key->keyidx] = key;
+ if (peer && peer->dp_peer && cmd == SET_KEY) {
+ peer->dp_peer->keys[key->keyidx] = key;
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
- peer->ucast_keyidx = key->keyidx;
- peer->sec_type = ath12k_dp_tx_get_encrypt_type(key->cipher);
+ peer->dp_peer->ucast_keyidx = key->keyidx;
+ peer->dp_peer->sec_type =
+ ath12k_dp_tx_get_encrypt_type(key->cipher);
} else {
- peer->mcast_keyidx = key->keyidx;
- peer->sec_type_grp = ath12k_dp_tx_get_encrypt_type(key->cipher);
+ peer->dp_peer->mcast_keyidx = key->keyidx;
+ peer->dp_peer->sec_type_grp =
+ ath12k_dp_tx_get_encrypt_type(key->cipher);
}
- } else if (peer && cmd == DISABLE_KEY) {
- peer->keys[key->keyidx] = NULL;
+ } else if (peer && peer->dp_peer && cmd == DISABLE_KEY) {
+ peer->dp_peer->keys[key->keyidx] = NULL;
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
- peer->ucast_keyidx = 0;
+ peer->dp_peer->ucast_keyidx = 0;
else
- peer->mcast_keyidx = 0;
+ peer->dp_peer->mcast_keyidx = 0;
} else if (!peer)
/* impossible unless FW goes crazy */
ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr);
spin_lock_bh(&tmp_dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
tmp_arvif->bssid);
- if (!peer) {
+ if (!peer || !peer->dp_peer) {
spin_unlock_bh(&tmp_dp->dp_lock);
ath12k_warn(tmp_ar->ab,
"failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n",
continue;
}
- key = peer->keys[peer->mcast_keyidx];
+ key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx];
if (key) {
skb_cb->cipher = key->cipher;
skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
dp_link_vif->ast_idx = peer->hw_peer_id;
}
- if (vif->type == NL80211_IFTYPE_AP)
- peer->ucast_ra_only = true;
-
if (sta) {
ahsta = ath12k_sta_to_ahsta(sta);
arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
}
}
- peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
- peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
-
ar->num_peers++;
spin_unlock_bh(&dp->dp_lock);
struct ath12k_dp_link_peer *peer, u8 tid)
{
struct ath12k_hal_reo_cmd cmd = {};
- struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid];
+ struct ath12k_dp_rx_tid *rx_tid = &peer->dp_peer->rx_tid[tid];
int ret;
- if (!rx_tid->active)
+ if (!(peer->rx_tid_active_bitmask & (1 << tid)))
return;
cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
else
ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid);
- rx_tid->active = false;
+ peer->rx_tid_active_bitmask &= ~(1 << tid);
}
int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab,
}
}
-int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
+int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer,
struct ath12k_dp_rx_tid *rx_tid,
u16 ssn, enum hal_pn_type pn_type)
{
u32 hw_desc_sz;
int ret;
- buf = &ahsta->reoq_bufs[tid];
+ buf = &dp_peer->reoq_bufs[tid];
if (!buf->vaddr) {
/* TODO: Optimize the memory allocation for qos tid based on
* the actual BA window size in REO tid update path.
}
rx_tid->qbuf = *buf;
- rx_tid->active = true;
return 0;
}
struct hal_rx_desc *rx_desc,
struct hal_rx_desc_data *rx_info)
{
- struct ath12k_dp *dp = dp_pdev->dp;
struct ath12k_skb_rxcb *rxcb;
enum hal_encrypt_type enctype;
bool is_decrypted = false;
struct ieee80211_hdr *hdr;
- struct ath12k_dp_link_peer *peer;
+ struct ath12k_dp_peer *peer;
struct ieee80211_rx_status *rx_status = rx_info->rx_status;
u32 err_bitmap = rx_info->err_bitmap;
if (rxcb->is_mcbc)
rxcb->peer_id = rx_info->peer_id;
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id);
if (peer) {
/* resetting mcbc bit because mcbc packets are unicast
* packets only for AP as STA sends unicast packets.
} else {
enctype = HAL_ENCRYPT_TYPE_OPEN;
}
- spin_unlock_bh(&dp->dp_lock);
if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
is_decrypted = rx_info->is_decrypted;
}
static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev,
- struct ath12k_dp_link_peer *peer,
+ struct ath12k_dp_peer *peer,
enum hal_encrypt_type enctype,
struct sk_buff *msdu,
struct hal_rx_desc_data *rx_info)
}
static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev,
- struct ath12k_dp_link_peer *peer,
+ struct ath12k_dp_peer *peer,
struct ath12k_dp_rx_tid *rx_tid,
struct sk_buff **defrag_skb,
enum hal_encrypt_type enctype,
{
struct ath12k_dp *dp = dp_pdev->dp;
struct ath12k_base *ab = dp->ab;
- struct ath12k_dp_link_peer *peer;
+ struct ath12k_dp_peer *peer;
struct ath12k_dp_rx_tid *rx_tid;
struct sk_buff *defrag_skb = NULL;
u32 peer_id = rx_info->peer_id;
return -EINVAL;
spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id);
if (!peer) {
ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n",
peer_id);
timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id);
if (!peer)
goto err_frags_cleanup;
rxcb->is_last_msdu = err_info.last_msdu;
rxcb->is_continuation = err_info.continuation;
rxcb->rx_desc = msdu_data;
+ rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver,
+ err_info.peer_metadata);
if (err_info.continuation) {
__skb_queue_tail(&scatter_msdu_list, msdu);
void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
struct ath12k_dp_rx_tid *rx_tid,
u32 cipher, enum set_key_cmd key_cmd);
-int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
+int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer,
struct ath12k_dp_rx_tid *rx_tid,
u16 ssn, enum hal_pn_type pn_type);
int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab,
s32 noise_floor;
struct ieee80211_tx_status status = {};
struct ath12k_dp_link_peer *peer;
- struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
+ struct ath12k_pdev_dp *dp_pdev;
skb_cb = ATH12K_SKB_CB(msdu);
info = IEEE80211_SKB_CB(msdu);
ar = skb_cb->ar;
+ dp_pdev = &ar->dp;
ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++;
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
}
}
rcu_read_lock();
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, peer_id);
+ peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id);
if (!peer || !peer->sta) {
ath12k_dbg(ab, ATH12K_DBG_DATA,
"dp_tx: failed to find the peer with peer_id %d\n", peer_id);
- spin_unlock_bh(&dp->dp_lock);
ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
goto exit;
} else {
status.sta = peer->sta;
}
- spin_unlock_bh(&dp->dp_lock);
status.info = info;
status.skb = msdu;
{
struct ath12k_dp *dp = dp_pdev->dp;
struct ath12k_base *ab = dp->ab;
- struct ath12k_dp_link_peer *peer;
+ struct ath12k_dp_peer *peer;
struct ieee80211_sta *sta;
struct ath12k_sta *ahsta;
struct ath12k_link_sta *arsta;
u8 rate_idx = 0;
int ret;
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id);
if (!peer || !peer->sta) {
ath12k_dbg(ab, ATH12K_DBG_DP_TX,
"failed to find the peer by id %u\n", ts->peer_id);
- spin_unlock_bh(&dp->dp_lock);
return;
}
sta = peer->sta;
txrate.nss = arsta->last_txrate.nss;
else
txrate.nss = arsta->peer_nss;
- spin_unlock_bh(&dp->dp_lock);
switch (ts->pkt_type) {
case HAL_TX_RATE_STATS_PKT_TYPE_11A:
s32 noise_floor;
struct ieee80211_tx_status status = {};
struct ieee80211_rate_status status_rate = {};
- struct ath12k_dp_link_peer *peer;
+ struct ath12k_dp_peer *peer;
struct ath12k_link_sta *arsta;
struct ath12k_sta *ahsta;
struct rate_info rate;
ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts);
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id);
+ peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id);
if (!peer || !peer->sta) {
ath12k_err(ab,
"dp_tx: failed to find the peer with peer_id %d\n",
ts->peer_id);
- spin_unlock_bh(&dp->dp_lock);
ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu);
goto exit;
}
ahsta = ath12k_sta_to_ahsta(peer->sta);
arsta = &ahsta->deflink;
- spin_unlock_bh(&dp->dp_lock);
-
status.sta = peer->sta;
status.info = info;
status.skb = msdu;
HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE);
}
+ rel_info->peer_metadata = wbm_desc->info2;
+
return 0;
}
bool continuation;
void *rx_desc;
bool hw_cc_done;
+ __le32 peer_metadata;
};
#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \