qcacmn: BAR frame handling for 2K-jump and & OOR error
Currently the detection of whether a frame arriving on the rx-error ring is done via the flags in the ring descriptor. For targets which support providing previous PN in the rx-error ring descriptor, the flags indicating BAR frame will not be present in the ring descriptor. Add BAR frame check and handling in the OOR and 2K-jump frame processing handlers. Change-Id: Iaba763559a84f1c1f6a193e01945124f08c506f2 CRs-Fixed: 2965086
Šī revīzija ir iekļauta:

revīziju iesūtīja
Madan Koyyalamudi

vecāks
593a7c6ae2
revīzija
e28d968b5a
@@ -536,6 +536,107 @@ dp_rx_err_nbuf_pn_check(struct dp_soc *soc, hal_ring_desc_t ring_desc,
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
static
|
||||
void dp_rx_err_handle_bar(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint8_t *rx_tlv_hdr;
|
||||
unsigned char type, subtype;
|
||||
uint16_t start_seq_num;
|
||||
uint32_t tid;
|
||||
QDF_STATUS status;
|
||||
struct ieee80211_frame_bar *bar;
|
||||
|
||||
/*
|
||||
* 1. Is this a BAR frame. If not Discard it.
|
||||
* 2. If it is, get the peer id, tid, ssn
|
||||
* 2a Do a tid update
|
||||
*/
|
||||
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + soc->rx_pkt_tlv_size);
|
||||
|
||||
type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
|
||||
subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
|
||||
|
||||
if (!(type == IEEE80211_FC0_TYPE_CTL &&
|
||||
subtype == QDF_IEEE80211_FC0_SUBTYPE_BAR)) {
|
||||
dp_err_rl("Not a BAR frame!");
|
||||
return;
|
||||
}
|
||||
|
||||
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr);
|
||||
qdf_assert_always(tid < DP_MAX_TIDS);
|
||||
|
||||
start_seq_num = le16toh(bar->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
|
||||
|
||||
dp_info_rl("tid %u window_size %u start_seq_num %u",
|
||||
tid, peer->rx_tid[tid].ba_win_size, start_seq_num);
|
||||
|
||||
status = dp_rx_tid_update_wifi3(peer, tid,
|
||||
peer->rx_tid[tid].ba_win_size,
|
||||
start_seq_num);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_err_rl("failed to handle bar frame update rx tid");
|
||||
DP_STATS_INC(soc, rx.err.bar_handle_fail_count, 1);
|
||||
} else {
|
||||
DP_STATS_INC(soc, rx.err.ssn_update_count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _dp_rx_bar_frame_handle(): Core of the BAR frame handling
|
||||
* @soc: Datapath SoC handle
|
||||
* @nbuf: packet being processed
|
||||
* @mpdu_desc_info: mpdu desc info for the current packet
|
||||
* @tid: tid on which the packet arrived
|
||||
* @err_status: Flag to indicate if REO encountered an error while routing this
|
||||
* frame
|
||||
* @error_code: REO error code
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void
|
||||
_dp_rx_bar_frame_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
|
||||
uint32_t tid, uint8_t err_status, uint32_t error_code)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
||||
peer_id = DP_PEER_METADATA_PEER_ID_GET(mpdu_desc_info->peer_meta_data);
|
||||
peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
dp_info("BAR frame: peer = " QDF_MAC_ADDR_FMT
|
||||
" peer_id = %d"
|
||||
" tid = %u"
|
||||
" SSN = %d"
|
||||
" error status = %d",
|
||||
QDF_MAC_ADDR_REF(peer->mac_addr.raw),
|
||||
peer->peer_id,
|
||||
tid,
|
||||
mpdu_desc_info->mpdu_seq,
|
||||
err_status);
|
||||
|
||||
if (err_status == HAL_REO_ERROR_DETECTED) {
|
||||
switch (error_code) {
|
||||
case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
|
||||
/* fallthrough */
|
||||
case HAL_REO_ERR_BAR_FRAME_OOR:
|
||||
dp_rx_err_handle_bar(soc, peer, nbuf);
|
||||
DP_STATS_INC(soc, rx.err.reo_error[error_code], 1);
|
||||
break;
|
||||
default:
|
||||
DP_STATS_INC(soc, rx.bar_frame, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_reo_err_entry_process() - Handles for REO error entry processing
|
||||
*
|
||||
@@ -656,6 +757,12 @@ more_msdu_link_desc:
|
||||
mpdu_desc_info);
|
||||
peer_id = DP_PEER_METADATA_PEER_ID_GET(
|
||||
mpdu_desc_info->peer_meta_data);
|
||||
|
||||
if (mpdu_desc_info->bar_frame)
|
||||
_dp_rx_bar_frame_handle(soc, nbuf,
|
||||
mpdu_desc_info, tid,
|
||||
HAL_REO_ERROR_DETECTED,
|
||||
err_code);
|
||||
}
|
||||
|
||||
switch (err_code) {
|
||||
@@ -830,55 +937,6 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
return mpdu_done;
|
||||
}
|
||||
|
||||
static
|
||||
void dp_rx_err_handle_bar(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint8_t *rx_tlv_hdr;
|
||||
unsigned char type, subtype;
|
||||
uint16_t start_seq_num;
|
||||
uint32_t tid;
|
||||
QDF_STATUS status;
|
||||
struct ieee80211_frame_bar *bar;
|
||||
|
||||
/*
|
||||
* 1. Is this a BAR frame. If not Discard it.
|
||||
* 2. If it is, get the peer id, tid, ssn
|
||||
* 2a Do a tid update
|
||||
*/
|
||||
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + soc->rx_pkt_tlv_size);
|
||||
|
||||
type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
|
||||
subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
|
||||
|
||||
if (!(type == IEEE80211_FC0_TYPE_CTL &&
|
||||
subtype == QDF_IEEE80211_FC0_SUBTYPE_BAR)) {
|
||||
dp_err_rl("Not a BAR frame!");
|
||||
return;
|
||||
}
|
||||
|
||||
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr);
|
||||
qdf_assert_always(tid < DP_MAX_TIDS);
|
||||
|
||||
start_seq_num = le16toh(bar->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
|
||||
|
||||
dp_info_rl("tid %u window_size %u start_seq_num %u",
|
||||
tid, peer->rx_tid[tid].ba_win_size, start_seq_num);
|
||||
|
||||
status = dp_rx_tid_update_wifi3(peer, tid,
|
||||
peer->rx_tid[tid].ba_win_size,
|
||||
start_seq_num);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_err_rl("failed to handle bar frame update rx tid");
|
||||
DP_STATS_INC(soc, rx.err.bar_handle_fail_count, 1);
|
||||
} else {
|
||||
DP_STATS_INC(soc, rx.err.ssn_update_count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_bar_frame_handle() - Function to handle err BAR frames
|
||||
* @soc: core DP main context
|
||||
@@ -904,9 +962,7 @@ dp_rx_bar_frame_handle(struct dp_soc *soc,
|
||||
{
|
||||
qdf_nbuf_t nbuf;
|
||||
struct dp_pdev *pdev;
|
||||
struct dp_peer *peer;
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
uint16_t peer_id;
|
||||
uint8_t *rx_tlv_hdr;
|
||||
uint32_t tid;
|
||||
|
||||
@@ -922,44 +978,12 @@ dp_rx_bar_frame_handle(struct dp_soc *soc,
|
||||
rx_desc->unmapped = 1;
|
||||
dp_ipa_rx_buf_smmu_mapping_unlock(soc);
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
peer_id =
|
||||
hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
|
||||
rx_tlv_hdr);
|
||||
peer = dp_peer_get_ref_by_id(soc, peer_id,
|
||||
DP_MOD_ID_RX_ERR);
|
||||
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
|
||||
rx_tlv_hdr);
|
||||
pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id);
|
||||
|
||||
if (!peer)
|
||||
goto next;
|
||||
|
||||
dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT
|
||||
" peer_id = %d"
|
||||
" tid = %u"
|
||||
" SSN = %d"
|
||||
" error code = %d",
|
||||
QDF_MAC_ADDR_REF(peer->mac_addr.raw),
|
||||
peer->peer_id,
|
||||
tid,
|
||||
mpdu_desc_info->mpdu_seq,
|
||||
err_code);
|
||||
|
||||
if (err_status == HAL_REO_ERROR_DETECTED) {
|
||||
switch (err_code) {
|
||||
case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
|
||||
/* fallthrough */
|
||||
case HAL_REO_ERR_BAR_FRAME_OOR:
|
||||
dp_rx_err_handle_bar(soc, peer, nbuf);
|
||||
DP_STATS_INC(soc, rx.err.reo_error[err_code], 1);
|
||||
break;
|
||||
default:
|
||||
DP_STATS_INC(soc, rx.bar_frame, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
|
||||
next:
|
||||
_dp_rx_bar_frame_handle(soc, nbuf, mpdu_desc_info, tid, err_status,
|
||||
err_code);
|
||||
dp_rx_link_desc_return(soc, ring_desc,
|
||||
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
||||
dp_rx_buffer_pool_nbuf_free(soc, rx_desc->nbuf,
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user