mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacmn: RX defragmentation fixes
- Handle WDS case during encapsulation - Drop non-head duplicate fragments from list - Get REO DST ring id from msdu_info of incoming packet Change-Id: I7e4c9c211548aafe9b4ba88fb12890f38aced324 CRs-Fixed: 2174750
This commit is contained in:
parent
ed9697f4aa
commit
7e69eaa303
2 changed files with 126 additions and 21 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -154,9 +154,9 @@ static void dp_rx_defrag_waitlist_remove(struct dp_peer *peer, unsigned tid)
|
|||
*
|
||||
* Build a per-tid, per-sequence fragment list.
|
||||
*
|
||||
* Returns: None
|
||||
* Returns: Success, if inserted
|
||||
*/
|
||||
static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
||||
static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
||||
qdf_nbuf_t *head_addr, qdf_nbuf_t *tail_addr, qdf_nbuf_t frag,
|
||||
uint8_t *all_frag_present)
|
||||
{
|
||||
|
|
@ -168,10 +168,12 @@ static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
|||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
uint8_t *rx_desc_info;
|
||||
|
||||
|
||||
qdf_assert(frag);
|
||||
qdf_assert(head_addr);
|
||||
qdf_assert(tail_addr);
|
||||
|
||||
*all_frag_present = 0;
|
||||
rx_desc_info = qdf_nbuf_data(frag);
|
||||
cur_fragno = dp_rx_frag_get_mpdu_frag_number(rx_desc_info);
|
||||
|
||||
|
|
@ -181,7 +183,7 @@ static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
|||
qdf_nbuf_set_next(*tail_addr, NULL);
|
||||
rx_tid->curr_frag_num = cur_fragno;
|
||||
|
||||
goto end;
|
||||
goto insert_done;
|
||||
}
|
||||
|
||||
/* In sequence fragment */
|
||||
|
|
@ -198,7 +200,7 @@ static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
|||
|
||||
if (cur_fragno == head_fragno) {
|
||||
qdf_nbuf_free(frag);
|
||||
*all_frag_present = 0;
|
||||
goto insert_fail;
|
||||
} else if (head_fragno > cur_fragno) {
|
||||
qdf_nbuf_set_next(frag, cur);
|
||||
cur = frag;
|
||||
|
|
@ -212,6 +214,12 @@ static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
|||
dp_rx_frag_get_mpdu_frag_number(
|
||||
rx_desc_info);
|
||||
}
|
||||
|
||||
if (cur_fragno == head_fragno) {
|
||||
qdf_nbuf_free(frag);
|
||||
goto insert_fail;
|
||||
}
|
||||
|
||||
qdf_nbuf_set_next(prev, frag);
|
||||
qdf_nbuf_set_next(frag, cur);
|
||||
}
|
||||
|
|
@ -239,12 +247,15 @@ static void dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned tid,
|
|||
|
||||
if (!next) {
|
||||
*all_frag_present = 1;
|
||||
return;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
*all_frag_present = 0;
|
||||
insert_done:
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
insert_fail:
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -708,7 +719,7 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
struct llc_snap_hdr_t *llchdr;
|
||||
struct ethernet_hdr_t *eth_hdr;
|
||||
uint8_t ether_type[2];
|
||||
uint16_t fc;
|
||||
uint16_t fc = 0;
|
||||
union dp_align_mac_addr mac_addr;
|
||||
uint8_t *rx_desc_info = qdf_mem_malloc(RX_PKT_TLVS_LEN);
|
||||
|
||||
|
|
@ -773,6 +784,14 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
break;
|
||||
|
||||
case IEEE80211_FC1_DIR_DSTODS:
|
||||
hal_rx_mpdu_get_addr3(rx_desc_info,
|
||||
&mac_addr.raw[0]);
|
||||
qdf_mem_copy(eth_hdr->dest_addr, &mac_addr.raw[0],
|
||||
IEEE80211_ADDR_LEN);
|
||||
hal_rx_mpdu_get_addr4(rx_desc_info,
|
||||
&mac_addr.raw[0]);
|
||||
qdf_mem_copy(eth_hdr->src_addr, &mac_addr.raw[0],
|
||||
IEEE80211_ADDR_LEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -809,7 +828,7 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
void *ent_ring_desc, *ent_mpdu_desc_info, *ent_qdesc_addr;
|
||||
void *dst_mpdu_desc_info, *dst_qdesc_addr;
|
||||
qdf_dma_addr_t paddr;
|
||||
uint32_t nbuf_len, seq_no;
|
||||
uint32_t nbuf_len, seq_no, dst_ind;
|
||||
uint32_t *mpdu_wrd;
|
||||
|
||||
void *dst_ring_desc =
|
||||
|
|
@ -835,6 +854,8 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
msdu_desc_info = (uint8_t *)msdu0 +
|
||||
RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET;
|
||||
|
||||
dst_ind = hal_rx_msdu_reo_dst_ind_get(link_desc_va);
|
||||
|
||||
qdf_mem_zero(msdu_desc_info, sizeof(struct rx_msdu_desc_info));
|
||||
|
||||
HAL_RX_MSDU_DESC_INFO_SET(msdu_desc_info,
|
||||
|
|
@ -844,7 +865,7 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
HAL_RX_MSDU_DESC_INFO_SET(msdu_desc_info,
|
||||
MSDU_CONTINUATION, 0x0);
|
||||
HAL_RX_MSDU_DESC_INFO_SET(msdu_desc_info,
|
||||
REO_DESTINATION_INDICATION, 1);
|
||||
REO_DESTINATION_INDICATION, dst_ind);
|
||||
HAL_RX_MSDU_DESC_INFO_SET(msdu_desc_info,
|
||||
MSDU_LENGTH, nbuf_len);
|
||||
HAL_RX_MSDU_DESC_INFO_SET(msdu_desc_info,
|
||||
|
|
@ -914,9 +935,8 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf)
|
|||
|
||||
qdf_mem_copy(ent_qdesc_addr, dst_qdesc_addr, 8);
|
||||
|
||||
/* dst ind */
|
||||
HAL_RX_FLD_SET(ent_ring_desc, REO_ENTRANCE_RING_5,
|
||||
REO_DESTINATION_INDICATION, 0x1);
|
||||
REO_DESTINATION_INDICATION, dst_ind);
|
||||
|
||||
hal_srng_access_end(soc->hal_soc, hal_srng);
|
||||
|
||||
|
|
@ -1259,7 +1279,7 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
|
|||
* If the earlier sequence was dropped, this will be the fresh start.
|
||||
* Else, continue with next fragment in a given sequence
|
||||
*/
|
||||
dp_rx_defrag_fraglist_insert(peer, tid, &rx_reorder_array_elem->head,
|
||||
status = dp_rx_defrag_fraglist_insert(peer, tid, &rx_reorder_array_elem->head,
|
||||
&rx_reorder_array_elem->tail, frag,
|
||||
&all_frag_present);
|
||||
|
||||
|
|
@ -1269,7 +1289,8 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
|
|||
* have to use the next MSDU link descriptor and chain them together
|
||||
* before reinjection
|
||||
*/
|
||||
if ((fragno == 0) && (rx_reorder_array_elem->head == frag)) {
|
||||
if ((fragno == 0) && (status == QDF_STATUS_SUCCESS) &&
|
||||
(rx_reorder_array_elem->head == frag)) {
|
||||
|
||||
status = dp_rx_defrag_save_info_from_ring_desc(ring_desc,
|
||||
peer, tid);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -359,6 +359,12 @@ enum hal_rx_ret_buf_manager {
|
|||
RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_OFFSET)) & \
|
||||
RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_MASK)
|
||||
|
||||
#define HAL_RX_MSDU_REO_DST_IND_GET(msdu_info_ptr) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \
|
||||
RX_MSDU_DESC_INFO_0_REO_DESTINATION_INDICATION_OFFSET)), \
|
||||
RX_MSDU_DESC_INFO_0_REO_DESTINATION_INDICATION_MASK, \
|
||||
RX_MSDU_DESC_INFO_0_REO_DESTINATION_INDICATION_LSB))
|
||||
|
||||
#define HAL_RX_MSDU_SA_IS_VALID_FLAG_GET(msdu_info_ptr) \
|
||||
((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \
|
||||
RX_MSDU_DESC_INFO_0_SA_IS_VALID_OFFSET)) & \
|
||||
|
|
@ -1557,6 +1563,12 @@ hal_rx_mpdu_get_fr_ds(uint8_t *buf)
|
|||
RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \
|
||||
RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB))
|
||||
|
||||
#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
|
||||
RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \
|
||||
RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \
|
||||
RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB))
|
||||
|
||||
#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
|
||||
RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \
|
||||
|
|
@ -1593,6 +1605,18 @@ hal_rx_mpdu_get_fr_ds(uint8_t *buf)
|
|||
RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \
|
||||
RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB))
|
||||
|
||||
#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
|
||||
RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \
|
||||
RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \
|
||||
RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB))
|
||||
|
||||
#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
|
||||
RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \
|
||||
RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \
|
||||
RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB))
|
||||
|
||||
/*
|
||||
* hal_rx_mpdu_get_addr1(): API to check get address1 of the mpdu
|
||||
*
|
||||
|
|
@ -1674,8 +1698,8 @@ static inline
|
|||
QDF_STATUS hal_rx_mpdu_get_addr3(uint8_t *buf, uint8_t *mac_addr)
|
||||
{
|
||||
struct __attribute__((__packed__)) hal_addr3 {
|
||||
uint16_t ad3_15_0;
|
||||
uint32_t ad3_47_16;
|
||||
uint32_t ad3_31_0;
|
||||
uint16_t ad3_47_32;
|
||||
};
|
||||
|
||||
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||
|
|
@ -1689,8 +1713,43 @@ QDF_STATUS hal_rx_mpdu_get_addr3(uint8_t *buf, uint8_t *mac_addr)
|
|||
mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info);
|
||||
|
||||
if (mac_addr_ad3_valid) {
|
||||
addr->ad3_15_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info);
|
||||
addr->ad3_47_16 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info);
|
||||
addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info);
|
||||
addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* hal_rx_mpdu_get_addr4(): API to get address4 of the mpdu
|
||||
* in the packet
|
||||
*
|
||||
* @buf: pointer to the start of RX PKT TLV header
|
||||
* @mac_addr: pointer to mac address
|
||||
* Return: sucess/failure
|
||||
*/
|
||||
static inline
|
||||
QDF_STATUS hal_rx_mpdu_get_addr4(uint8_t *buf, uint8_t *mac_addr)
|
||||
{
|
||||
struct __attribute__((__packed__)) hal_addr4 {
|
||||
uint32_t ad4_31_0;
|
||||
uint16_t ad4_47_32;
|
||||
};
|
||||
|
||||
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||
struct rx_mpdu_start *mpdu_start =
|
||||
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
|
||||
|
||||
struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
|
||||
struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr;
|
||||
uint32_t mac_addr_ad4_valid;
|
||||
|
||||
mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info);
|
||||
|
||||
if (mac_addr_ad4_valid) {
|
||||
addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info);
|
||||
addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1967,6 +2026,31 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
|
|||
*num_msdus = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_msdu_reo_dst_ind_get: Gets the REO
|
||||
* destination ring ID from the msdu desc info
|
||||
*
|
||||
* @msdu_link_desc : Opaque cookie pointer used by HAL to get to
|
||||
* the current descriptor
|
||||
*
|
||||
* Return: dst_ind (REO destination ring ID)
|
||||
*/
|
||||
static inline uint32_t
|
||||
hal_rx_msdu_reo_dst_ind_get(void *msdu_link_desc)
|
||||
{
|
||||
struct rx_msdu_details *msdu_details;
|
||||
struct rx_msdu_desc_info *msdu_desc_info;
|
||||
struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc;
|
||||
uint32_t dst_ind;
|
||||
|
||||
msdu_details = HAL_RX_LINK_DESC_MSDU0_PTR(msdu_link);
|
||||
|
||||
/* The first msdu in the link should exsist */
|
||||
msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[0]);
|
||||
dst_ind = HAL_RX_MSDU_REO_DST_IND_GET(msdu_desc_info);
|
||||
return dst_ind;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_reo_buf_paddr_get: Gets the physical address and
|
||||
* cookie from the REO destination ring element
|
||||
|
|
@ -3067,7 +3151,7 @@ uint8_t hal_rx_get_rx_more_frag_bit(uint8_t *buf)
|
|||
*
|
||||
*/
|
||||
static inline
|
||||
uint8_t hal_rx_get_frame_ctrl_field(uint8_t *buf)
|
||||
uint16_t hal_rx_get_frame_ctrl_field(uint8_t *buf)
|
||||
{
|
||||
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
|
||||
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
|
||||
|
|
|
|||
Loading…
Reference in a new issue