diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/dp_rx.c')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp_rx.c | 226 |
1 files changed, 169 insertions, 57 deletions
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 791d971784ce..a507c1231a59 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -375,7 +375,13 @@ static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar, idr_destroy(&rx_ring->bufs_idr); spin_unlock_bh(&rx_ring->idr_lock); - rx_ring = &dp->rx_mon_status_refill_ring; + /* if rxdma1_enable is false, mon_status_refill_ring + * isn't setup, so don't clean. + */ + if (!ar->ab->hw_params.rxdma1_enable) + return 0; + + rx_ring = &dp->rx_mon_status_refill_ring[0]; spin_lock_bh(&rx_ring->idr_lock); idr_for_each_entry(&rx_ring->bufs_idr, skb, buf_id) { @@ -390,21 +396,27 @@ static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar, idr_destroy(&rx_ring->bufs_idr); spin_unlock_bh(&rx_ring->idr_lock); + return 0; } static int ath11k_dp_rxdma_pdev_buf_free(struct ath11k *ar) { struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_base *ab = ar->ab; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + int i; ath11k_dp_rxdma_buf_ring_free(ar, rx_ring); rx_ring = &dp->rxdma_mon_buf_ring; ath11k_dp_rxdma_buf_ring_free(ar, rx_ring); - rx_ring = &dp->rx_mon_status_refill_ring; - ath11k_dp_rxdma_buf_ring_free(ar, rx_ring); + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + rx_ring = &dp->rx_mon_status_refill_ring[i]; + ath11k_dp_rxdma_buf_ring_free(ar, rx_ring); + } + return 0; } @@ -416,7 +428,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar, int num_entries; num_entries = rx_ring->refill_buf_ring.size / - ath11k_hal_srng_get_entrysize(ringtype); + ath11k_hal_srng_get_entrysize(ar->ab, ringtype); rx_ring->bufs_max = num_entries; ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, @@ -427,15 +439,21 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar, static int ath11k_dp_rxdma_pdev_buf_setup(struct ath11k *ar) { struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_base *ab = ar->ab; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + int i; ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); - rx_ring = &dp->rxdma_mon_buf_ring; - ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_BUF); + if (ar->ab->hw_params.rxdma1_enable) { + rx_ring = &dp->rxdma_mon_buf_ring; + ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_BUF); + } - rx_ring = &dp->rx_mon_status_refill_ring; - ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_STATUS); + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + rx_ring = &dp->rx_mon_status_refill_ring[i]; + ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_STATUS); + } return 0; } @@ -443,11 +461,21 @@ static int ath11k_dp_rxdma_pdev_buf_setup(struct ath11k *ar) static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar) { struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_base *ab = ar->ab; + int i; + + ath11k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring); + + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + if (ab->hw_params.rx_mac_buf_ring) + ath11k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]); - ath11k_dp_srng_cleanup(ar->ab, &dp->rx_refill_buf_ring.refill_buf_ring); - ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_err_dst_ring); - ath11k_dp_srng_cleanup(ar->ab, &dp->rx_mon_status_refill_ring.refill_buf_ring); - ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_mon_buf_ring.refill_buf_ring); + ath11k_dp_srng_cleanup(ab, &dp->rxdma_err_dst_ring[i]); + ath11k_dp_srng_cleanup(ab, + &dp->rx_mon_status_refill_ring[i].refill_buf_ring); + } + + ath11k_dp_srng_cleanup(ab, &dp->rxdma_mon_buf_ring.refill_buf_ring); } void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab) @@ -486,7 +514,9 @@ err_reo_cleanup: static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar) { struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_base *ab = ar->ab; struct dp_srng *srng = NULL; + int i; int ret; ret = ath11k_dp_srng_setup(ar->ab, @@ -498,24 +528,50 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar) return ret; } - ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring, - HAL_RXDMA_DST, 0, dp->mac_id, - DP_RXDMA_ERR_DST_RING_SIZE); - if (ret) { - ath11k_warn(ar->ab, "failed to setup rxdma_err_dst_ring\n"); - return ret; + if (ar->ab->hw_params.rx_mac_buf_ring) { + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ret = ath11k_dp_srng_setup(ar->ab, + &dp->rx_mac_buf_ring[i], + HAL_RXDMA_BUF, 1, + dp->mac_id + i, 1024); + if (ret) { + ath11k_warn(ar->ab, "failed to setup rx_mac_buf_ring %d\n", + i); + return ret; + } + } } - srng = &dp->rx_mon_status_refill_ring.refill_buf_ring; - ret = ath11k_dp_srng_setup(ar->ab, - srng, - HAL_RXDMA_MONITOR_STATUS, 0, dp->mac_id, - DP_RXDMA_MON_STATUS_RING_SIZE); - if (ret) { - ath11k_warn(ar->ab, - "failed to setup rx_mon_status_refill_ring\n"); - return ret; + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring[i], + HAL_RXDMA_DST, 0, dp->mac_id + i, + DP_RXDMA_ERR_DST_RING_SIZE); + if (ret) { + ath11k_warn(ar->ab, "failed to setup rxdma_err_dst_ring %d\n", i); + return ret; + } } + + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring; + ret = ath11k_dp_srng_setup(ar->ab, + srng, + HAL_RXDMA_MONITOR_STATUS, 0, dp->mac_id + i, + DP_RXDMA_MON_STATUS_RING_SIZE); + if (ret) { + ath11k_warn(ar->ab, + "failed to setup rx_mon_status_refill_ring %d\n", i); + return ret; + } + } + + /* if rxdma1_enable is false, then it doesn't need + * to setup rxdam_mon_buf_ring, rxdma_mon_dst_ring + * and rxdma_mon_desc_ring. + */ + if (!ar->ab->hw_params.rxdma1_enable) + return 0; + ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_mon_buf_ring.refill_buf_ring, HAL_RXDMA_MONITOR_BUF, 0, dp->mac_id, @@ -1577,11 +1633,23 @@ void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, resp->peer_map_ev.info1); ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32, peer_mac_h16, mac_addr); + ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0); + break; + case HTT_T2H_MSG_TYPE_PEER_MAP2: + vdev_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_VDEV_ID, + resp->peer_map_ev.info); + peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_PEER_ID, + resp->peer_map_ev.info); + peer_mac_h16 = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16, + resp->peer_map_ev.info1); + ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32, + peer_mac_h16, mac_addr); ast_hash = FIELD_GET(HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL, resp->peer_map_ev.info2); ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash); break; case HTT_T2H_MSG_TYPE_PEER_UNMAP: + case HTT_T2H_MSG_TYPE_PEER_UNMAP2: peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID, resp->peer_unmap_ev.info); ath11k_peer_unmap_event(ab, peer_id); @@ -2065,8 +2133,6 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, mcast = is_multicast_ether_addr(hdr->addr1); fill_crypto_hdr = mcast; - is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); - spin_lock_bh(&ar->ab->base_lock); peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2); if (peer) { @@ -2080,6 +2146,8 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, spin_unlock_bh(&ar->ab->base_lock); err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); /* Clear per-MPDU flags while leaving per-PPDU flags intact */ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | @@ -2282,6 +2350,9 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap !!(status->flag & RX_FLAG_MMIC_ERROR), !!(status->flag & RX_FLAG_AMSDU_MORE)); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ", + msdu->data, msdu->len); + /* TODO: trace rx packet */ ieee80211_rx_napi(ar->hw, NULL, msdu, napi); @@ -2719,20 +2790,25 @@ fail_desc_get: static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, int *budget, struct sk_buff_head *skb_list) { - struct ath11k *ar = ab->pdevs[mac_id].ar; - struct ath11k_pdev_dp *dp = &ar->dp; - struct dp_rxdma_ring *rx_ring = &dp->rx_mon_status_refill_ring; + struct ath11k *ar; + struct ath11k_pdev_dp *dp; + struct dp_rxdma_ring *rx_ring; struct hal_srng *srng; void *rx_mon_status_desc; struct sk_buff *skb; struct ath11k_skb_rxcb *rxcb; struct hal_tlv_hdr *tlv; u32 cookie; - int buf_id; + int buf_id, srng_id; dma_addr_t paddr; u8 rbm; int num_buffs_reaped = 0; + ar = ab->pdevs[ath11k_hw_mac_id_to_pdev_id(&ab->hw_params, mac_id)].ar; + dp = &ar->dp; + srng_id = ath11k_hw_mac_id_to_srng_id(&ab->hw_params, mac_id); + rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; + srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; spin_lock_bh(&srng->lock); @@ -2813,7 +2889,7 @@ move_next: int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { - struct ath11k *ar = ab->pdevs[mac_id].ar; + struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id); enum hal_rx_mon_status hal_status; struct sk_buff *skb; struct sk_buff_head skb_list; @@ -3709,8 +3785,7 @@ static bool ath11k_dp_rx_h_reo_err(struct ath11k *ar, struct sk_buff *msdu, * instead, it is good to drop such packets in mac80211 * after incrementing the replay counters. */ - - /* fall through */ + fallthrough; default: /* TODO: Review other errors and process them to mac80211 * as appropriate. @@ -3820,7 +3895,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, int total_num_buffs_reaped = 0; int ret, i; - for (i = 0; i < MAX_RADIOS; i++) + for (i = 0; i < ab->num_radios; i++) __skb_queue_head_init(&msdu_list[i]); srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; @@ -3923,9 +3998,9 @@ done: int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget) { - struct ath11k *ar = ab->pdevs[mac_id].ar; - struct dp_srng *err_ring = &ar->dp.rxdma_err_dst_ring; - struct dp_rxdma_ring *rx_ring = &ar->dp.rx_refill_buf_ring; + struct ath11k *ar; + struct dp_srng *err_ring; + struct dp_rxdma_ring *rx_ring; struct dp_link_desc_bank *link_desc_banks = ab->dp.link_desc_banks; struct hal_srng *srng; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; @@ -3944,6 +4019,11 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget) int i; int buf_id; + ar = ab->pdevs[ath11k_hw_mac_id_to_pdev_id(&ab->hw_params, mac_id)].ar; + err_ring = &ar->dp.rxdma_err_dst_ring[ath11k_hw_mac_id_to_srng_id(&ab->hw_params, + mac_id)]; + rx_ring = &ar->dp.rx_refill_buf_ring; + srng = &ab->hal.srng_list[err_ring->ring_id]; spin_lock_bh(&srng->lock); @@ -4097,6 +4177,7 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) struct ath11k *ar = ab->pdevs[mac_id].ar; struct ath11k_pdev_dp *dp = &ar->dp; u32 ring_id; + int i; int ret; ret = ath11k_dp_rx_pdev_srng_alloc(ar); @@ -4119,14 +4200,33 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) return ret; } - ring_id = dp->rxdma_err_dst_ring.ring_id; - ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id, HAL_RXDMA_DST); - if (ret) { - ath11k_warn(ab, "failed to configure rxdma_err_dest_ring %d\n", - ret); - return ret; + if (ab->hw_params.rx_mac_buf_ring) { + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ring_id = dp->rx_mac_buf_ring[i].ring_id; + ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, + mac_id + i, HAL_RXDMA_BUF); + if (ret) { + ath11k_warn(ab, "failed to configure rx_mac_buf_ring%d %d\n", + i, ret); + return ret; + } + } + } + + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ring_id = dp->rxdma_err_dst_ring[i].ring_id; + ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, + mac_id + i, HAL_RXDMA_DST); + if (ret) { + ath11k_warn(ab, "failed to configure rxdma_err_dest_ring%d %d\n", + i, ret); + return ret; + } } + if (!ab->hw_params.rxdma1_enable) + goto config_refill_ring; + ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id, HAL_RXDMA_MONITOR_BUF); @@ -4151,15 +4251,20 @@ int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) ret); return ret; } - ring_id = dp->rx_mon_status_refill_ring.refill_buf_ring.ring_id; - ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id, - HAL_RXDMA_MONITOR_STATUS); - if (ret) { - ath11k_warn(ab, - "failed to configure mon_status_refill_ring %d\n", - ret); - return ret; + +config_refill_ring: + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id + i, + HAL_RXDMA_MONITOR_STATUS); + if (ret) { + ath11k_warn(ab, + "failed to configure mon_status_refill_ring%d %d\n", + i, ret); + return ret; + } } + return 0; } @@ -4777,7 +4882,7 @@ static void ath11k_dp_rx_mon_status_process_tlv(struct ath11k *ar, static int ath11k_dp_mon_process_rx(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { - struct ath11k *ar = ab->pdevs[mac_id].ar; + struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id); struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; int num_buffs_reaped = 0; @@ -4793,7 +4898,7 @@ static int ath11k_dp_mon_process_rx(struct ath11k_base *ab, int mac_id, int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { - struct ath11k *ar = ab->pdevs[mac_id].ar; + struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id); int ret = 0; if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) @@ -4832,9 +4937,15 @@ int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar) return ret; } + /* if rxdma1_enable is false, no need to setup + * rxdma_mon_desc_ring. + */ + if (!ar->ab->hw_params.rxdma1_enable) + return 0; + dp_srng = &dp->rxdma_mon_desc_ring; n_link_desc = dp_srng->size / - ath11k_hal_srng_get_entrysize(HAL_RXDMA_MONITOR_DESC); + ath11k_hal_srng_get_entrysize(ar->ab, HAL_RXDMA_MONITOR_DESC); mon_desc_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_desc_ring.ring_id]; @@ -4848,6 +4959,7 @@ int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar) pmon->mon_last_linkdesc_paddr = 0; pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1; spin_lock_init(&pmon->mon_lock); + return 0; } |