qcacmn: Datapath RX error handler for WCN7850
Add DP rx error handler changes for WCN7850. Change-Id: I401f1b69eb107818e7aceb0a51279dab7f558b96 CRs-Fixed: 2891021
This commit is contained in:

committed by
Manjunathappa Prakash

orang tua
14794ee689
melakukan
872da9462b
@@ -114,7 +114,7 @@ QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return_buffer_manager = hal_rx_ret_buf_manager_get(ring_desc);
|
return_buffer_manager = hal_rx_ret_buf_manager_get(hal_soc, ring_desc);
|
||||||
if (qdf_unlikely(!(return_buffer_manager == HAL_RX_BUF_RBM_SW1_BM ||
|
if (qdf_unlikely(!(return_buffer_manager == HAL_RX_BUF_RBM_SW1_BM ||
|
||||||
return_buffer_manager == HAL_RX_BUF_RBM_SW3_BM))) {
|
return_buffer_manager == HAL_RX_BUF_RBM_SW3_BM))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -448,7 +448,7 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
|
|||||||
(unsigned long long)(nbuf_frag_info.paddr),
|
(unsigned long long)(nbuf_frag_info.paddr),
|
||||||
(*desc_list)->rx_desc.cookie);
|
(*desc_list)->rx_desc.cookie);
|
||||||
|
|
||||||
hal_rxdma_buff_addr_info_set(rxdma_ring_entry,
|
hal_rxdma_buff_addr_info_set(dp_soc->hal_soc, rxdma_ring_entry,
|
||||||
nbuf_frag_info.paddr,
|
nbuf_frag_info.paddr,
|
||||||
(*desc_list)->rx_desc.cookie,
|
(*desc_list)->rx_desc.cookie,
|
||||||
rx_desc_pool->owner);
|
rx_desc_pool->owner);
|
||||||
|
@@ -324,6 +324,7 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
qdf_nbuf_t *head_addr, qdf_nbuf_t *tail_addr, qdf_nbuf_t frag,
|
qdf_nbuf_t *head_addr, qdf_nbuf_t *tail_addr, qdf_nbuf_t frag,
|
||||||
uint8_t *all_frag_present)
|
uint8_t *all_frag_present)
|
||||||
{
|
{
|
||||||
|
struct dp_soc *soc = peer->vdev->pdev->soc;
|
||||||
qdf_nbuf_t next;
|
qdf_nbuf_t next;
|
||||||
qdf_nbuf_t prev = NULL;
|
qdf_nbuf_t prev = NULL;
|
||||||
qdf_nbuf_t cur;
|
qdf_nbuf_t cur;
|
||||||
@@ -332,14 +333,13 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||||
uint8_t *rx_desc_info;
|
uint8_t *rx_desc_info;
|
||||||
|
|
||||||
|
|
||||||
qdf_assert(frag);
|
qdf_assert(frag);
|
||||||
qdf_assert(head_addr);
|
qdf_assert(head_addr);
|
||||||
qdf_assert(tail_addr);
|
qdf_assert(tail_addr);
|
||||||
|
|
||||||
*all_frag_present = 0;
|
*all_frag_present = 0;
|
||||||
rx_desc_info = qdf_nbuf_data(frag);
|
rx_desc_info = qdf_nbuf_data(frag);
|
||||||
cur_fragno = dp_rx_frag_get_mpdu_frag_number(rx_desc_info);
|
cur_fragno = dp_rx_frag_get_mpdu_frag_number(soc, rx_desc_info);
|
||||||
|
|
||||||
dp_debug("cur_fragno %d\n", cur_fragno);
|
dp_debug("cur_fragno %d\n", cur_fragno);
|
||||||
/* If this is the first fragment */
|
/* If this is the first fragment */
|
||||||
@@ -361,7 +361,8 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
/* Out of sequence fragment */
|
/* Out of sequence fragment */
|
||||||
cur = *head_addr;
|
cur = *head_addr;
|
||||||
rx_desc_info = qdf_nbuf_data(cur);
|
rx_desc_info = qdf_nbuf_data(cur);
|
||||||
head_fragno = dp_rx_frag_get_mpdu_frag_number(rx_desc_info);
|
head_fragno = dp_rx_frag_get_mpdu_frag_number(soc,
|
||||||
|
rx_desc_info);
|
||||||
|
|
||||||
if (cur_fragno == head_fragno) {
|
if (cur_fragno == head_fragno) {
|
||||||
qdf_nbuf_free(frag);
|
qdf_nbuf_free(frag);
|
||||||
@@ -378,6 +379,7 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
rx_desc_info = qdf_nbuf_data(cur);
|
rx_desc_info = qdf_nbuf_data(cur);
|
||||||
head_fragno =
|
head_fragno =
|
||||||
dp_rx_frag_get_mpdu_frag_number(
|
dp_rx_frag_get_mpdu_frag_number(
|
||||||
|
soc,
|
||||||
rx_desc_info);
|
rx_desc_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,7 +397,7 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
next = qdf_nbuf_next(*head_addr);
|
next = qdf_nbuf_next(*head_addr);
|
||||||
|
|
||||||
rx_desc_info = qdf_nbuf_data(*tail_addr);
|
rx_desc_info = qdf_nbuf_data(*tail_addr);
|
||||||
last_morefrag = dp_rx_frag_get_more_frag_bit(rx_desc_info);
|
last_morefrag = dp_rx_frag_get_more_frag_bit(soc, rx_desc_info);
|
||||||
|
|
||||||
/* TODO: optimize the loop */
|
/* TODO: optimize the loop */
|
||||||
if (!last_morefrag) {
|
if (!last_morefrag) {
|
||||||
@@ -403,7 +405,8 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti
|
|||||||
do {
|
do {
|
||||||
rx_desc_info = qdf_nbuf_data(next);
|
rx_desc_info = qdf_nbuf_data(next);
|
||||||
next_fragno =
|
next_fragno =
|
||||||
dp_rx_frag_get_mpdu_frag_number(rx_desc_info);
|
dp_rx_frag_get_mpdu_frag_number(soc,
|
||||||
|
rx_desc_info);
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (next_fragno != count)
|
if (next_fragno != count)
|
||||||
@@ -437,10 +440,12 @@ insert_fail:
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_tkip_decap(qdf_nbuf_t msdu, uint16_t hdrlen)
|
static QDF_STATUS
|
||||||
|
dp_rx_defrag_tkip_decap(struct dp_soc *soc,
|
||||||
|
qdf_nbuf_t msdu, uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
uint8_t *ivp, *orig_hdr;
|
uint8_t *ivp, *orig_hdr;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
/* start of 802.11 header info */
|
/* start of 802.11 header info */
|
||||||
orig_hdr = (uint8_t *)(qdf_nbuf_data(msdu) + rx_desc_len);
|
orig_hdr = (uint8_t *)(qdf_nbuf_data(msdu) + rx_desc_len);
|
||||||
@@ -467,10 +472,11 @@ static QDF_STATUS dp_rx_defrag_tkip_decap(qdf_nbuf_t msdu, uint16_t hdrlen)
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_ccmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
static QDF_STATUS
|
||||||
|
dp_rx_defrag_ccmp_demic(struct dp_soc *soc, qdf_nbuf_t nbuf, uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
uint8_t *ivp, *orig_hdr;
|
uint8_t *ivp, *orig_hdr;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
/* start of the 802.11 header */
|
/* start of the 802.11 header */
|
||||||
orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
|
orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
|
||||||
@@ -494,10 +500,11 @@ static QDF_STATUS dp_rx_defrag_ccmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_ccmp_decap(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
static QDF_STATUS
|
||||||
|
dp_rx_defrag_ccmp_decap(struct dp_soc *soc, qdf_nbuf_t nbuf, uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
uint8_t *ivp, *origHdr;
|
uint8_t *ivp, *origHdr;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
origHdr = (uint8_t *) (qdf_nbuf_data(nbuf) + rx_desc_len);
|
origHdr = (uint8_t *) (qdf_nbuf_data(nbuf) + rx_desc_len);
|
||||||
ivp = origHdr + hdrlen;
|
ivp = origHdr + hdrlen;
|
||||||
@@ -519,10 +526,11 @@ static QDF_STATUS dp_rx_defrag_ccmp_decap(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_wep_decap(qdf_nbuf_t msdu, uint16_t hdrlen)
|
static QDF_STATUS
|
||||||
|
dp_rx_defrag_wep_decap(struct dp_soc *soc, qdf_nbuf_t msdu, uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
uint8_t *origHdr;
|
uint8_t *origHdr;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len);
|
origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len);
|
||||||
qdf_mem_move(origHdr + dp_f_wep.ic_header, origHdr, hdrlen);
|
qdf_mem_move(origHdr + dp_f_wep.ic_header, origHdr, hdrlen);
|
||||||
@@ -555,7 +563,7 @@ static uint16_t dp_rx_defrag_hdrsize(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
|||||||
frm_ctrl_valid =
|
frm_ctrl_valid =
|
||||||
hal_rx_get_mpdu_frame_control_valid(soc->hal_soc,
|
hal_rx_get_mpdu_frame_control_valid(soc->hal_soc,
|
||||||
rx_tlv_hdr);
|
rx_tlv_hdr);
|
||||||
frm_ctrl_field = hal_rx_get_frame_ctrl_field(rx_tlv_hdr);
|
frm_ctrl_field = hal_rx_get_frame_ctrl_field(soc->hal_soc, rx_tlv_hdr);
|
||||||
|
|
||||||
if (to_ds && fr_ds)
|
if (to_ds && fr_ds)
|
||||||
size += QDF_MAC_ADDR_SIZE;
|
size += QDF_MAC_ADDR_SIZE;
|
||||||
@@ -648,14 +656,15 @@ static void dp_rx_defrag_michdr(const struct ieee80211_frame *wh0,
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_mic(const uint8_t *key, qdf_nbuf_t wbuf,
|
static QDF_STATUS dp_rx_defrag_mic(struct dp_soc *soc, const uint8_t *key,
|
||||||
uint16_t off, uint16_t data_len, uint8_t mic[])
|
qdf_nbuf_t wbuf, uint16_t off,
|
||||||
|
uint16_t data_len, uint8_t mic[])
|
||||||
{
|
{
|
||||||
uint8_t hdr[16] = { 0, };
|
uint8_t hdr[16] = { 0, };
|
||||||
uint32_t l, r;
|
uint32_t l, r;
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
uint32_t space;
|
uint32_t space;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
dp_rx_defrag_michdr((struct ieee80211_frame *)(qdf_nbuf_data(wbuf)
|
dp_rx_defrag_michdr((struct ieee80211_frame *)(qdf_nbuf_data(wbuf)
|
||||||
+ rx_desc_len), hdr);
|
+ rx_desc_len), hdr);
|
||||||
@@ -771,8 +780,9 @@ static QDF_STATUS dp_rx_defrag_mic(const uint8_t *key, qdf_nbuf_t wbuf,
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_tkip_demic(const uint8_t *key,
|
static QDF_STATUS dp_rx_defrag_tkip_demic(struct dp_soc *soc,
|
||||||
qdf_nbuf_t msdu, uint16_t hdrlen)
|
const uint8_t *key,
|
||||||
|
qdf_nbuf_t msdu, uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
uint32_t pktlen = 0, prev_data_len;
|
uint32_t pktlen = 0, prev_data_len;
|
||||||
@@ -824,8 +834,8 @@ static QDF_STATUS dp_rx_defrag_tkip_demic(const uint8_t *key,
|
|||||||
qdf_nbuf_set_next(prev0, NULL);
|
qdf_nbuf_set_next(prev0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = dp_rx_defrag_mic(key, msdu, hdrlen,
|
status = dp_rx_defrag_mic(soc, key, msdu, hdrlen,
|
||||||
pktlen, mic);
|
pktlen, mic);
|
||||||
|
|
||||||
if (QDF_IS_STATUS_ERROR(status))
|
if (QDF_IS_STATUS_ERROR(status))
|
||||||
return status;
|
return status;
|
||||||
@@ -845,19 +855,12 @@ static QDF_STATUS dp_rx_defrag_tkip_demic(const uint8_t *key,
|
|||||||
*
|
*
|
||||||
* Returns: None
|
* Returns: None
|
||||||
*/
|
*/
|
||||||
static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf, uint16_t hdrsize)
|
static void dp_rx_frag_pull_hdr(struct dp_soc *soc,
|
||||||
|
qdf_nbuf_t nbuf, uint16_t hdrsize)
|
||||||
{
|
{
|
||||||
struct rx_pkt_tlvs *rx_pkt_tlv =
|
hal_rx_print_pn(soc->hal_soc, qdf_nbuf_data(nbuf));
|
||||||
(struct rx_pkt_tlvs *)qdf_nbuf_data(nbuf);
|
|
||||||
struct rx_mpdu_info *rx_mpdu_info_details =
|
|
||||||
&rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details;
|
|
||||||
|
|
||||||
dp_debug("pn_31_0 0x%x pn_63_32 0x%x pn_95_64 0x%x pn_127_96 0x%x\n",
|
qdf_nbuf_pull_head(nbuf, soc->rx_pkt_tlv_size + hdrsize);
|
||||||
rx_mpdu_info_details->pn_31_0, rx_mpdu_info_details->pn_63_32,
|
|
||||||
rx_mpdu_info_details->pn_95_64,
|
|
||||||
rx_mpdu_info_details->pn_127_96);
|
|
||||||
|
|
||||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + hdrsize);
|
|
||||||
|
|
||||||
dp_debug("final pktlen %d .11len %d",
|
dp_debug("final pktlen %d .11len %d",
|
||||||
(uint32_t)qdf_nbuf_len(nbuf), hdrsize);
|
(uint32_t)qdf_nbuf_len(nbuf), hdrsize);
|
||||||
@@ -871,21 +874,12 @@ static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf, uint16_t hdrsize)
|
|||||||
*
|
*
|
||||||
* Returns: 0 on success, non zero on failure
|
* Returns: 0 on success, non zero on failure
|
||||||
*/
|
*/
|
||||||
static int dp_rx_defrag_pn_check(qdf_nbuf_t msdu,
|
static int dp_rx_defrag_pn_check(struct dp_soc *soc, qdf_nbuf_t msdu,
|
||||||
uint64_t *cur_pn128, uint64_t *prev_pn128)
|
uint64_t *cur_pn128, uint64_t *prev_pn128)
|
||||||
{
|
{
|
||||||
struct rx_pkt_tlvs *rx_pkt_tlv =
|
|
||||||
(struct rx_pkt_tlvs *)qdf_nbuf_data(msdu);
|
|
||||||
struct rx_mpdu_info *rx_mpdu_info_details =
|
|
||||||
&rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details;
|
|
||||||
int out_of_order = 0;
|
int out_of_order = 0;
|
||||||
|
|
||||||
cur_pn128[0] = rx_mpdu_info_details->pn_31_0;
|
hal_rx_tlv_get_pn_num(soc->hal_soc, qdf_nbuf_data(msdu), cur_pn128);
|
||||||
cur_pn128[0] |=
|
|
||||||
((uint64_t)rx_mpdu_info_details->pn_63_32 << 32);
|
|
||||||
cur_pn128[1] = rx_mpdu_info_details->pn_95_64;
|
|
||||||
cur_pn128[1] |=
|
|
||||||
((uint64_t)rx_mpdu_info_details->pn_127_96 << 32);
|
|
||||||
|
|
||||||
if (cur_pn128[1] == prev_pn128[1])
|
if (cur_pn128[1] == prev_pn128[1])
|
||||||
out_of_order = (cur_pn128[0] - prev_pn128[0] != 1);
|
out_of_order = (cur_pn128[0] - prev_pn128[0] != 1);
|
||||||
@@ -909,6 +903,7 @@ static int
|
|||||||
dp_rx_construct_fraglist(struct dp_peer *peer, int tid, qdf_nbuf_t head,
|
dp_rx_construct_fraglist(struct dp_peer *peer, int tid, qdf_nbuf_t head,
|
||||||
uint16_t hdrsize)
|
uint16_t hdrsize)
|
||||||
{
|
{
|
||||||
|
struct dp_soc *soc = peer->vdev->pdev->soc;
|
||||||
qdf_nbuf_t msdu = qdf_nbuf_next(head);
|
qdf_nbuf_t msdu = qdf_nbuf_next(head);
|
||||||
qdf_nbuf_t rx_nbuf = msdu;
|
qdf_nbuf_t rx_nbuf = msdu;
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||||
@@ -921,13 +916,14 @@ dp_rx_construct_fraglist(struct dp_peer *peer, int tid, qdf_nbuf_t head,
|
|||||||
prev_pn128[0] = rx_tid->pn128[0];
|
prev_pn128[0] = rx_tid->pn128[0];
|
||||||
prev_pn128[1] = rx_tid->pn128[1];
|
prev_pn128[1] = rx_tid->pn128[1];
|
||||||
|
|
||||||
index = hal_rx_msdu_is_wlan_mcast(msdu) ? dp_sec_mcast : dp_sec_ucast;
|
index = hal_rx_msdu_is_wlan_mcast(soc->hal_soc, msdu) ? dp_sec_mcast :
|
||||||
|
dp_sec_ucast;
|
||||||
if (qdf_likely(peer->security[index].sec_type != cdp_sec_type_none))
|
if (qdf_likely(peer->security[index].sec_type != cdp_sec_type_none))
|
||||||
needs_pn_check = 1;
|
needs_pn_check = 1;
|
||||||
|
|
||||||
while (msdu) {
|
while (msdu) {
|
||||||
if (qdf_likely(needs_pn_check))
|
if (qdf_likely(needs_pn_check))
|
||||||
out_of_order = dp_rx_defrag_pn_check(msdu,
|
out_of_order = dp_rx_defrag_pn_check(soc, msdu,
|
||||||
&cur_pn128[0],
|
&cur_pn128[0],
|
||||||
&prev_pn128[0]);
|
&prev_pn128[0]);
|
||||||
|
|
||||||
@@ -946,13 +942,13 @@ dp_rx_construct_fraglist(struct dp_peer *peer, int tid, qdf_nbuf_t head,
|
|||||||
* Iterating through all msdus and dropping fragments if even
|
* Iterating through all msdus and dropping fragments if even
|
||||||
* one of them has mcast/bcast destination address.
|
* one of them has mcast/bcast destination address.
|
||||||
*/
|
*/
|
||||||
if (hal_rx_msdu_is_wlan_mcast(msdu)) {
|
if (hal_rx_msdu_is_wlan_mcast(soc->hal_soc, msdu)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"Dropping multicast/broadcast fragments");
|
"Dropping multicast/broadcast fragments");
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dp_rx_frag_pull_hdr(msdu, hdrsize);
|
dp_rx_frag_pull_hdr(soc, msdu, hdrsize);
|
||||||
len += qdf_nbuf_len(msdu);
|
len += qdf_nbuf_len(msdu);
|
||||||
msdu = qdf_nbuf_next(msdu);
|
msdu = qdf_nbuf_next(msdu);
|
||||||
}
|
}
|
||||||
@@ -989,7 +985,7 @@ static void dp_rx_defrag_err(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
|||||||
{
|
{
|
||||||
struct ol_if_ops *tops = NULL;
|
struct ol_if_ops *tops = NULL;
|
||||||
struct dp_pdev *pdev = vdev->pdev;
|
struct dp_pdev *pdev = vdev->pdev;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = pdev->soc->rx_pkt_tlv_size;
|
||||||
uint8_t *orig_hdr;
|
uint8_t *orig_hdr;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct cdp_rx_mic_err_info mic_failure_info;
|
struct cdp_rx_mic_err_info mic_failure_info;
|
||||||
@@ -1035,22 +1031,12 @@ dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc, struct dp_peer *peer, int tid,
|
|||||||
uint8_t ether_type[2];
|
uint8_t ether_type[2];
|
||||||
uint16_t fc = 0;
|
uint16_t fc = 0;
|
||||||
union dp_align_mac_addr mac_addr;
|
union dp_align_mac_addr mac_addr;
|
||||||
uint8_t *rx_desc_info = qdf_mem_malloc(RX_PKT_TLVS_LEN);
|
uint8_t *rx_desc_info = qdf_mem_malloc(soc->rx_pkt_tlv_size);
|
||||||
struct rx_pkt_tlvs *rx_pkt_tlv =
|
|
||||||
(struct rx_pkt_tlvs *)qdf_nbuf_data(nbuf);
|
|
||||||
struct rx_mpdu_info *rx_mpdu_info_details =
|
|
||||||
&rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details;
|
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||||
|
|
||||||
dp_debug("head_nbuf pn_31_0 0x%x pn_63_32 0x%x pn_95_64 0x%x pn_127_96 0x%x\n",
|
hal_rx_tlv_get_pn_num(soc->hal_soc, qdf_nbuf_data(nbuf), rx_tid->pn128);
|
||||||
rx_mpdu_info_details->pn_31_0, rx_mpdu_info_details->pn_63_32,
|
|
||||||
rx_mpdu_info_details->pn_95_64,
|
|
||||||
rx_mpdu_info_details->pn_127_96);
|
|
||||||
|
|
||||||
rx_tid->pn128[0] = rx_mpdu_info_details->pn_31_0;
|
hal_rx_print_pn(soc->hal_soc, qdf_nbuf_data(nbuf));
|
||||||
rx_tid->pn128[0] |= ((uint64_t)rx_mpdu_info_details->pn_63_32 << 32);
|
|
||||||
rx_tid->pn128[1] = rx_mpdu_info_details->pn_95_64;
|
|
||||||
rx_tid->pn128[1] |= ((uint64_t)rx_mpdu_info_details->pn_127_96 << 32);
|
|
||||||
|
|
||||||
if (!rx_desc_info) {
|
if (!rx_desc_info) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -1059,13 +1045,13 @@ dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc, struct dp_peer *peer, int tid,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_mem_copy(rx_desc_info, qdf_nbuf_data(nbuf), RX_PKT_TLVS_LEN);
|
qdf_mem_copy(rx_desc_info, qdf_nbuf_data(nbuf), soc->rx_pkt_tlv_size);
|
||||||
|
|
||||||
llchdr = (struct llc_snap_hdr_t *)(qdf_nbuf_data(nbuf) +
|
llchdr = (struct llc_snap_hdr_t *)(qdf_nbuf_data(nbuf) +
|
||||||
RX_PKT_TLVS_LEN + hdrsize);
|
soc->rx_pkt_tlv_size + hdrsize);
|
||||||
qdf_mem_copy(ether_type, llchdr->ethertype, 2);
|
qdf_mem_copy(ether_type, llchdr->ethertype, 2);
|
||||||
|
|
||||||
qdf_nbuf_pull_head(nbuf, (RX_PKT_TLVS_LEN + hdrsize +
|
qdf_nbuf_pull_head(nbuf, (soc->rx_pkt_tlv_size + hdrsize +
|
||||||
sizeof(struct llc_snap_hdr_t) -
|
sizeof(struct llc_snap_hdr_t) -
|
||||||
sizeof(struct ethernet_hdr_t)));
|
sizeof(struct ethernet_hdr_t)));
|
||||||
|
|
||||||
@@ -1073,7 +1059,7 @@ dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc, struct dp_peer *peer, int tid,
|
|||||||
|
|
||||||
if (hal_rx_get_mpdu_frame_control_valid(soc->hal_soc,
|
if (hal_rx_get_mpdu_frame_control_valid(soc->hal_soc,
|
||||||
rx_desc_info))
|
rx_desc_info))
|
||||||
fc = hal_rx_get_frame_ctrl_field(rx_desc_info);
|
fc = hal_rx_get_frame_ctrl_field(soc->hal_soc, rx_desc_info);
|
||||||
|
|
||||||
dp_debug("Frame control type: 0x%x", fc);
|
dp_debug("Frame control type: 0x%x", fc);
|
||||||
|
|
||||||
@@ -1128,8 +1114,8 @@ dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc, struct dp_peer *peer, int tid,
|
|||||||
qdf_mem_copy(eth_hdr->ethertype, ether_type,
|
qdf_mem_copy(eth_hdr->ethertype, ether_type,
|
||||||
sizeof(ether_type));
|
sizeof(ether_type));
|
||||||
|
|
||||||
qdf_nbuf_push_head(nbuf, RX_PKT_TLVS_LEN);
|
qdf_nbuf_push_head(nbuf, soc->rx_pkt_tlv_size);
|
||||||
qdf_mem_copy(qdf_nbuf_data(nbuf), rx_desc_info, RX_PKT_TLVS_LEN);
|
qdf_mem_copy(qdf_nbuf_data(nbuf), rx_desc_info, soc->rx_pkt_tlv_size);
|
||||||
qdf_mem_free(rx_desc_info);
|
qdf_mem_free(rx_desc_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1156,7 +1142,7 @@ static inline void dp_rx_defrag_deliver(struct dp_peer *peer,
|
|||||||
|
|
||||||
QDF_NBUF_CB_RX_VDEV_ID(head) = vdev->vdev_id;
|
QDF_NBUF_CB_RX_VDEV_ID(head) = vdev->vdev_id;
|
||||||
qdf_nbuf_set_tid_val(head, tid);
|
qdf_nbuf_set_tid_val(head, tid);
|
||||||
qdf_nbuf_pull_head(head, RX_PKT_TLVS_LEN);
|
qdf_nbuf_pull_head(head, soc->rx_pkt_tlv_size);
|
||||||
|
|
||||||
DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail,
|
DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail,
|
||||||
head);
|
head);
|
||||||
@@ -1289,12 +1275,16 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
|
|
||||||
hal_rx_reo_buf_paddr_get(dst_ring_desc, &buf_info);
|
hal_rx_reo_buf_paddr_get(dst_ring_desc, &buf_info);
|
||||||
|
|
||||||
|
/* buffer_addr_info is the first element of ring_desc */
|
||||||
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)dst_ring_desc,
|
||||||
|
&buf_info);
|
||||||
|
|
||||||
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
||||||
|
|
||||||
qdf_assert_always(link_desc_va);
|
qdf_assert_always(link_desc_va);
|
||||||
|
|
||||||
msdu0 = hal_rx_msdu0_buffer_addr_lsb(soc->hal_soc, link_desc_va);
|
msdu0 = hal_rx_msdu0_buffer_addr_lsb(soc->hal_soc, link_desc_va);
|
||||||
nbuf_len = qdf_nbuf_len(head) - RX_PKT_TLVS_LEN;
|
nbuf_len = qdf_nbuf_len(head) - soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
HAL_RX_UNIFORM_HDR_SET(link_desc_va, OWNER, UNI_DESC_OWNER_SW);
|
HAL_RX_UNIFORM_HDR_SET(link_desc_va, OWNER, UNI_DESC_OWNER_SW);
|
||||||
HAL_RX_UNIFORM_HDR_SET(link_desc_va, BUFFER_TYPE,
|
HAL_RX_UNIFORM_HDR_SET(link_desc_va, BUFFER_TYPE,
|
||||||
@@ -1323,8 +1313,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
DA_IS_VALID, 1);
|
DA_IS_VALID, 1);
|
||||||
|
|
||||||
/* change RX TLV's */
|
/* change RX TLV's */
|
||||||
hal_rx_msdu_start_msdu_len_set(
|
hal_rx_tlv_msdu_len_set(soc->hal_soc, qdf_nbuf_data(head), nbuf_len);
|
||||||
qdf_nbuf_data(head), nbuf_len);
|
|
||||||
|
|
||||||
cookie = HAL_RX_BUF_COOKIE_GET(msdu0);
|
cookie = HAL_RX_BUF_COOKIE_GET(msdu0);
|
||||||
rx_desc_pool = &soc->rx_desc_buf[pdev->lmac_id];
|
rx_desc_pool = &soc->rx_desc_buf[pdev->lmac_id];
|
||||||
@@ -1360,7 +1349,8 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hal_rxdma_buff_addr_info_set(msdu0, paddr, cookie, DP_DEFRAG_RBM);
|
hal_rxdma_buff_addr_info_set(soc->hal_osc, msdu0, paddr, cookie,
|
||||||
|
DP_DEFRAG_RBM);
|
||||||
|
|
||||||
/* Lets fill entrance ring now !!! */
|
/* Lets fill entrance ring now !!! */
|
||||||
if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
|
if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
|
||||||
@@ -1374,7 +1364,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
dp_rx_reinject_ring_record_entry(soc, paddr, cookie, DP_DEFRAG_RBM);
|
dp_rx_reinject_ring_record_entry(soc, paddr, cookie, DP_DEFRAG_RBM);
|
||||||
paddr = (uint64_t)buf_info.paddr;
|
paddr = (uint64_t)buf_info.paddr;
|
||||||
/* buf addr */
|
/* buf addr */
|
||||||
hal_rxdma_buff_addr_info_set(ent_ring_desc, paddr,
|
hal_rxdma_buff_addr_info_set(soc->hal_soc, ent_ring_desc, paddr,
|
||||||
buf_info.sw_cookie,
|
buf_info.sw_cookie,
|
||||||
HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST);
|
HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST);
|
||||||
/* mpdu desc info */
|
/* mpdu desc info */
|
||||||
@@ -1427,6 +1417,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_rx_defrag_gcmp_demic(): Remove MIC information from GCMP fragment
|
* dp_rx_defrag_gcmp_demic(): Remove MIC information from GCMP fragment
|
||||||
|
* @soc: Datapath soc structure
|
||||||
* @nbuf: Pointer to the fragment buffer
|
* @nbuf: Pointer to the fragment buffer
|
||||||
* @hdrlen: 802.11 header length
|
* @hdrlen: 802.11 header length
|
||||||
*
|
*
|
||||||
@@ -1434,10 +1425,11 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|||||||
*
|
*
|
||||||
* Returns: QDF_STATUS
|
* Returns: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static QDF_STATUS dp_rx_defrag_gcmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
static QDF_STATUS dp_rx_defrag_gcmp_demic(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||||
|
uint16_t hdrlen)
|
||||||
{
|
{
|
||||||
uint8_t *ivp, *orig_hdr;
|
uint8_t *ivp, *orig_hdr;
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
/* start of the 802.11 header */
|
/* start of the 802.11 header */
|
||||||
orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
|
orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
|
||||||
@@ -1479,7 +1471,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
uint8_t status = 0;
|
uint8_t status = 0;
|
||||||
|
|
||||||
hdr_space = dp_rx_defrag_hdrsize(soc, cur);
|
hdr_space = dp_rx_defrag_hdrsize(soc, cur);
|
||||||
index = hal_rx_msdu_is_wlan_mcast(cur) ?
|
index = hal_rx_msdu_is_wlan_mcast(soc->hal_soc, cur) ?
|
||||||
dp_sec_mcast : dp_sec_ucast;
|
dp_sec_mcast : dp_sec_ucast;
|
||||||
|
|
||||||
/* Remove FCS from all fragments */
|
/* Remove FCS from all fragments */
|
||||||
@@ -1504,7 +1496,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
case cdp_sec_type_tkip_nomic:
|
case cdp_sec_type_tkip_nomic:
|
||||||
while (cur) {
|
while (cur) {
|
||||||
tmp_next = qdf_nbuf_next(cur);
|
tmp_next = qdf_nbuf_next(cur);
|
||||||
if (dp_rx_defrag_tkip_decap(cur, hdr_space)) {
|
if (dp_rx_defrag_tkip_decap(soc, cur, hdr_space)) {
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -1522,7 +1514,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
case cdp_sec_type_aes_ccmp:
|
case cdp_sec_type_aes_ccmp:
|
||||||
while (cur) {
|
while (cur) {
|
||||||
tmp_next = qdf_nbuf_next(cur);
|
tmp_next = qdf_nbuf_next(cur);
|
||||||
if (dp_rx_defrag_ccmp_demic(cur, hdr_space)) {
|
if (dp_rx_defrag_ccmp_demic(soc, cur, hdr_space)) {
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -1530,7 +1522,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
|
|
||||||
return QDF_STATUS_E_DEFRAG_ERROR;
|
return QDF_STATUS_E_DEFRAG_ERROR;
|
||||||
}
|
}
|
||||||
if (dp_rx_defrag_ccmp_decap(cur, hdr_space)) {
|
if (dp_rx_defrag_ccmp_decap(soc, cur, hdr_space)) {
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -1550,7 +1542,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
case cdp_sec_type_wep128:
|
case cdp_sec_type_wep128:
|
||||||
while (cur) {
|
while (cur) {
|
||||||
tmp_next = qdf_nbuf_next(cur);
|
tmp_next = qdf_nbuf_next(cur);
|
||||||
if (dp_rx_defrag_wep_decap(cur, hdr_space)) {
|
if (dp_rx_defrag_wep_decap(soc, cur, hdr_space)) {
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -1568,7 +1560,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
case cdp_sec_type_aes_gcmp_256:
|
case cdp_sec_type_aes_gcmp_256:
|
||||||
while (cur) {
|
while (cur) {
|
||||||
tmp_next = qdf_nbuf_next(cur);
|
tmp_next = qdf_nbuf_next(cur);
|
||||||
if (dp_rx_defrag_gcmp_demic(cur, hdr_space)) {
|
if (dp_rx_defrag_gcmp_demic(soc, cur, hdr_space)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
QDF_TRACE(QDF_MODULE_ID_TXRX,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
"dp_rx_defrag: GCMP demic failed");
|
"dp_rx_defrag: GCMP demic failed");
|
||||||
@@ -1589,8 +1581,8 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|||||||
qdf_mem_copy(key,
|
qdf_mem_copy(key,
|
||||||
&peer->security[index].michael_key[0],
|
&peer->security[index].michael_key[0],
|
||||||
IEEE80211_WEP_MICLEN);
|
IEEE80211_WEP_MICLEN);
|
||||||
status = dp_rx_defrag_tkip_demic(key, msdu,
|
status = dp_rx_defrag_tkip_demic(soc, key, msdu,
|
||||||
RX_PKT_TLVS_LEN +
|
soc->rx_pkt_tlv_size +
|
||||||
hdr_space);
|
hdr_space);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -1725,9 +1717,10 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
|
|||||||
goto err_free_desc;
|
goto err_free_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
msdu_len = hal_rx_msdu_start_msdu_len_get(rx_desc->rx_buf_start);
|
msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc,
|
||||||
|
rx_desc->rx_buf_start);
|
||||||
|
|
||||||
qdf_nbuf_set_pktlen(frag, (msdu_len + RX_PKT_TLVS_LEN));
|
qdf_nbuf_set_pktlen(frag, (msdu_len + soc->rx_pkt_tlv_size));
|
||||||
qdf_nbuf_append_ext_list(frag, NULL, 0);
|
qdf_nbuf_append_ext_list(frag, NULL, 0);
|
||||||
|
|
||||||
/* Check if the packet is from a valid peer */
|
/* Check if the packet is from a valid peer */
|
||||||
@@ -1782,12 +1775,12 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Current mpdu sequence */
|
/* Current mpdu sequence */
|
||||||
more_frag = dp_rx_frag_get_more_frag_bit(rx_desc->rx_buf_start);
|
more_frag = dp_rx_frag_get_more_frag_bit(soc, rx_desc->rx_buf_start);
|
||||||
|
|
||||||
/* HW does not populate the fragment number as of now
|
/* HW does not populate the fragment number as of now
|
||||||
* need to get from the 802.11 header
|
* need to get from the 802.11 header
|
||||||
*/
|
*/
|
||||||
fragno = dp_rx_frag_get_mpdu_frag_number(rx_desc->rx_buf_start);
|
fragno = dp_rx_frag_get_mpdu_frag_number(soc, rx_desc->rx_buf_start);
|
||||||
|
|
||||||
rx_reorder_array_elem = peer->rx_tid[tid].array;
|
rx_reorder_array_elem = peer->rx_tid[tid].array;
|
||||||
if (!rx_reorder_array_elem) {
|
if (!rx_reorder_array_elem) {
|
||||||
@@ -2103,9 +2096,10 @@ QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
msdu_len = hal_rx_msdu_start_msdu_len_get(qdf_nbuf_data(nbuf));
|
msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc,
|
||||||
|
qdf_nbuf_data(nbuf));
|
||||||
|
|
||||||
qdf_nbuf_set_pktlen(nbuf, (msdu_len + RX_PKT_TLVS_LEN));
|
qdf_nbuf_set_pktlen(nbuf, (msdu_len + soc->rx_pkt_tlv_size));
|
||||||
|
|
||||||
status = dp_rx_defrag_fraglist_insert(peer, tid,
|
status = dp_rx_defrag_fraglist_insert(peer, tid,
|
||||||
&rx_reorder_array_elem->head,
|
&rx_reorder_array_elem->head,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -66,10 +66,10 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
|
|||||||
*
|
*
|
||||||
* Returns: pointer to ieee80211_frame
|
* Returns: pointer to ieee80211_frame
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline struct ieee80211_frame *
|
||||||
struct ieee80211_frame *dp_rx_frag_get_mac_hdr(uint8_t *rx_desc_info)
|
dp_rx_frag_get_mac_hdr(struct dp_soc *soc, uint8_t *rx_desc_info)
|
||||||
{
|
{
|
||||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
int rx_desc_len = soc->rx_pkt_tlv_size;
|
||||||
return (struct ieee80211_frame *)(rx_desc_info + rx_desc_len);
|
return (struct ieee80211_frame *)(rx_desc_info + rx_desc_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +80,11 @@ struct ieee80211_frame *dp_rx_frag_get_mac_hdr(uint8_t *rx_desc_info)
|
|||||||
*
|
*
|
||||||
* Returns: uint16_t, rx sequence number
|
* Returns: uint16_t, rx sequence number
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline uint16_t
|
||||||
uint16_t dp_rx_frag_get_mpdu_seq_number(uint8_t *rx_desc_info)
|
dp_rx_frag_get_mpdu_seq_number(struct dp_soc *soc, int8_t *rx_desc_info)
|
||||||
{
|
{
|
||||||
struct ieee80211_frame *mac_hdr;
|
struct ieee80211_frame *mac_hdr;
|
||||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
mac_hdr = dp_rx_frag_get_mac_hdr(soc, rx_desc_info);
|
||||||
|
|
||||||
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) >>
|
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) >>
|
||||||
IEEE80211_SEQ_SEQ_SHIFT;
|
IEEE80211_SEQ_SEQ_SHIFT;
|
||||||
@@ -97,11 +97,11 @@ uint16_t dp_rx_frag_get_mpdu_seq_number(uint8_t *rx_desc_info)
|
|||||||
*
|
*
|
||||||
* Returns: uint8_t, receive fragment number
|
* Returns: uint8_t, receive fragment number
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline uint8_t
|
||||||
uint8_t dp_rx_frag_get_mpdu_frag_number(uint8_t *rx_desc_info)
|
dp_rx_frag_get_mpdu_frag_number(struct dp_soc *soc, uint8_t *rx_desc_info)
|
||||||
{
|
{
|
||||||
struct ieee80211_frame *mac_hdr;
|
struct ieee80211_frame *mac_hdr;
|
||||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
mac_hdr = dp_rx_frag_get_mac_hdr(soc, rx_desc_info);
|
||||||
|
|
||||||
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
|
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
|
||||||
IEEE80211_SEQ_FRAG_MASK;
|
IEEE80211_SEQ_FRAG_MASK;
|
||||||
@@ -115,19 +115,19 @@ uint8_t dp_rx_frag_get_mpdu_frag_number(uint8_t *rx_desc_info)
|
|||||||
* Returns: uint8_t, get more fragment bit
|
* Returns: uint8_t, get more fragment bit
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline
|
||||||
uint8_t dp_rx_frag_get_more_frag_bit(uint8_t *rx_desc_info)
|
uint8_t dp_rx_frag_get_more_frag_bit(struct dp_soc *soc, uint8_t *rx_desc_info)
|
||||||
{
|
{
|
||||||
struct ieee80211_frame *mac_hdr;
|
struct ieee80211_frame *mac_hdr;
|
||||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
mac_hdr = dp_rx_frag_get_mac_hdr(soc, rx_desc_info);
|
||||||
|
|
||||||
return (mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG) >> 2;
|
return (mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG) >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
uint8_t dp_rx_get_pkt_dir(uint8_t *rx_desc_info)
|
uint8_t dp_rx_get_pkt_dir(struct dp_soc *soc, uint8_t *rx_desc_info)
|
||||||
{
|
{
|
||||||
struct ieee80211_frame *mac_hdr;
|
struct ieee80211_frame *mac_hdr;
|
||||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
mac_hdr = dp_rx_frag_get_mac_hdr(soc, rx_desc_info);
|
||||||
|
|
||||||
return mac_hdr->i_fc[1] & IEEE80211_FC1_DIR_MASK;
|
return mac_hdr->i_fc[1] & IEEE80211_FC1_DIR_MASK;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "hal_hw_headers.h"
|
#include "hal_hw_headers.h"
|
||||||
#include "dp_types.h"
|
#include "dp_types.h"
|
||||||
#include "dp_rx.h"
|
#include "dp_rx.h"
|
||||||
|
#include "dp_tx.h"
|
||||||
#include "dp_peer.h"
|
#include "dp_peer.h"
|
||||||
#include "dp_internal.h"
|
#include "dp_internal.h"
|
||||||
#include "hal_api.h"
|
#include "hal_api.h"
|
||||||
@@ -155,6 +156,16 @@ void dp_rx_link_desc_refill_duplicate_check(
|
|||||||
/* do duplicate link desc address check */
|
/* do duplicate link desc address check */
|
||||||
hal_rx_buffer_addr_info_get_paddr(ring_buf_info,
|
hal_rx_buffer_addr_info_get_paddr(ring_buf_info,
|
||||||
¤t_link_desc_buf_info);
|
¤t_link_desc_buf_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO - Check if the hal soc api call can be removed
|
||||||
|
* since the cookie is just used for print.
|
||||||
|
* buffer_addr_info is the first element of ring_desc
|
||||||
|
*/
|
||||||
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc,
|
||||||
|
(uint32_t *)ring_buf_info,
|
||||||
|
¤t_link_desc_buf_info);
|
||||||
|
|
||||||
if (qdf_unlikely(current_link_desc_buf_info.paddr ==
|
if (qdf_unlikely(current_link_desc_buf_info.paddr ==
|
||||||
buf_info->paddr)) {
|
buf_info->paddr)) {
|
||||||
dp_info_rl("duplicate link desc addr: %llu, cookie: 0x%x",
|
dp_info_rl("duplicate link desc addr: %llu, cookie: 0x%x",
|
||||||
@@ -292,6 +303,11 @@ dp_rx_msdus_drop(struct dp_soc *soc, hal_ring_desc_t ring_desc,
|
|||||||
|
|
||||||
hal_rx_reo_buf_paddr_get(ring_desc, &buf_info);
|
hal_rx_reo_buf_paddr_get(ring_desc, &buf_info);
|
||||||
|
|
||||||
|
/* buffer_addr_info is the first element of ring_desc */
|
||||||
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc,
|
||||||
|
(uint32_t *)ring_desc,
|
||||||
|
&buf_info);
|
||||||
|
|
||||||
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
||||||
|
|
||||||
more_msdu_link_desc:
|
more_msdu_link_desc:
|
||||||
@@ -371,6 +387,10 @@ more_msdu_link_desc:
|
|||||||
hal_rx_buffer_addr_info_get_paddr(
|
hal_rx_buffer_addr_info_get_paddr(
|
||||||
&next_link_desc_addr_info,
|
&next_link_desc_addr_info,
|
||||||
&buf_info);
|
&buf_info);
|
||||||
|
/* buffer_addr_info is the first element of ring_desc */
|
||||||
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc,
|
||||||
|
(uint32_t *)&next_link_desc_addr_info,
|
||||||
|
&buf_info);
|
||||||
cur_link_desc_addr_info = next_link_desc_addr_info;
|
cur_link_desc_addr_info = next_link_desc_addr_info;
|
||||||
buf_addr_info = &cur_link_desc_addr_info;
|
buf_addr_info = &cur_link_desc_addr_info;
|
||||||
|
|
||||||
@@ -660,6 +680,10 @@ process_next_msdu:
|
|||||||
hal_rx_buffer_addr_info_get_paddr(
|
hal_rx_buffer_addr_info_get_paddr(
|
||||||
&next_link_desc_addr_info,
|
&next_link_desc_addr_info,
|
||||||
&buf_info);
|
&buf_info);
|
||||||
|
/* buffer_addr_info is the first element of ring_desc */
|
||||||
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc,
|
||||||
|
(uint32_t *)&next_link_desc_addr_info,
|
||||||
|
&buf_info);
|
||||||
link_desc_va =
|
link_desc_va =
|
||||||
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
||||||
cur_link_desc_addr_info = next_link_desc_addr_info;
|
cur_link_desc_addr_info = next_link_desc_addr_info;
|
||||||
@@ -752,8 +776,9 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp_pdev->ppdu_id == hal_rx_attn_phy_ppdu_id_get(rx_tlv_hdr) &&
|
if (dp_pdev->ppdu_id == hal_rx_attn_phy_ppdu_id_get(soc->hal_soc,
|
||||||
hal_rx_attn_msdu_done_get(rx_tlv_hdr)) {
|
rx_tlv_hdr) &&
|
||||||
|
hal_rx_attn_msdu_done_get(soc->hal_soc, rx_tlv_hdr)) {
|
||||||
qdf_nbuf_set_rx_chfrag_end(nbuf, 1);
|
qdf_nbuf_set_rx_chfrag_end(nbuf, 1);
|
||||||
qdf_assert_always(dp_pdev->first_nbuf == true);
|
qdf_assert_always(dp_pdev->first_nbuf == true);
|
||||||
dp_pdev->first_nbuf = false;
|
dp_pdev->first_nbuf = false;
|
||||||
@@ -793,7 +818,7 @@ void dp_rx_err_handle_bar(struct dp_soc *soc,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||||
bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + SIZE_OF_DATA_RX_TLV);
|
bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + soc->rx_pkt_tlv_size);
|
||||||
|
|
||||||
type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
|
type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
|
||||||
subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
|
subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
|
||||||
@@ -877,7 +902,7 @@ dp_rx_bar_frame_handle(struct dp_soc *soc,
|
|||||||
if (!peer)
|
if (!peer)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
reo_err_code = HAL_RX_REO_ERROR_GET(ring_desc);
|
reo_err_code = hal_rx_get_reo_error_code(soc->hal_soc, ring_desc);
|
||||||
dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT
|
dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT
|
||||||
" peer_id = %d"
|
" peer_id = %d"
|
||||||
" tid = %u"
|
" tid = %u"
|
||||||
@@ -1020,7 +1045,7 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc,
|
|||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
struct dp_peer *peer = NULL;
|
struct dp_peer *peer = NULL;
|
||||||
uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr);
|
uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(soc->hal_soc, rx_tlv_hdr);
|
||||||
struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, pool_id);
|
struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, pool_id);
|
||||||
struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr;
|
struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr;
|
||||||
|
|
||||||
@@ -1142,8 +1167,8 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
rx_tlv_hdr));
|
rx_tlv_hdr));
|
||||||
|
|
||||||
hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata);
|
hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata);
|
||||||
msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
|
msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, rx_tlv_hdr);
|
||||||
pkt_len = msdu_len + msdu_metadata.l3_hdr_pad + RX_PKT_TLVS_LEN;
|
pkt_len = msdu_len + msdu_metadata.l3_hdr_pad + soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
if (qdf_likely(!qdf_nbuf_is_frag(nbuf))) {
|
if (qdf_likely(!qdf_nbuf_is_frag(nbuf))) {
|
||||||
if (dp_rx_check_pkt_len(soc, pkt_len))
|
if (dp_rx_check_pkt_len(soc, pkt_len))
|
||||||
@@ -1159,7 +1184,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
* Check if DMA completed -- msdu_done is the last bit
|
* Check if DMA completed -- msdu_done is the last bit
|
||||||
* to be written
|
* to be written
|
||||||
*/
|
*/
|
||||||
if (!hal_rx_attn_msdu_done_get(rx_tlv_hdr)) {
|
if (!hal_rx_attn_msdu_done_get(soc->hal_soc, rx_tlv_hdr)) {
|
||||||
|
|
||||||
dp_err_rl("MSDU DONE failure");
|
dp_err_rl("MSDU DONE failure");
|
||||||
hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr,
|
hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr,
|
||||||
@@ -1220,10 +1245,10 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
* pre-header TLV's
|
* pre-header TLV's
|
||||||
*/
|
*/
|
||||||
if (qdf_nbuf_is_frag(nbuf))
|
if (qdf_nbuf_is_frag(nbuf))
|
||||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
qdf_nbuf_pull_head(nbuf, soc->rx_pkt_tlv_size);
|
||||||
else
|
else
|
||||||
qdf_nbuf_pull_head(nbuf, (msdu_metadata.l3_hdr_pad +
|
qdf_nbuf_pull_head(nbuf, (msdu_metadata.l3_hdr_pad +
|
||||||
RX_PKT_TLVS_LEN));
|
soc->rx_pkt_tlv_size));
|
||||||
|
|
||||||
dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL, 0, 1);
|
dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL, 0, 1);
|
||||||
|
|
||||||
@@ -1352,7 +1377,7 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
* Check if DMA completed -- msdu_done is the last bit
|
* Check if DMA completed -- msdu_done is the last bit
|
||||||
* to be written
|
* to be written
|
||||||
*/
|
*/
|
||||||
if (!hal_rx_attn_msdu_done_get(rx_tlv_hdr)) {
|
if (!hal_rx_attn_msdu_done_get(soc->hal_soc, rx_tlv_hdr)) {
|
||||||
|
|
||||||
dp_err_rl("MSDU DONE failure");
|
dp_err_rl("MSDU DONE failure");
|
||||||
|
|
||||||
@@ -1363,8 +1388,8 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc,
|
l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc,
|
||||||
rx_tlv_hdr);
|
rx_tlv_hdr);
|
||||||
msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
|
msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, rx_tlv_hdr);
|
||||||
pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
|
pkt_len = msdu_len + l2_hdr_offset + soc->rx_pkt_tlv_size;
|
||||||
|
|
||||||
if (dp_rx_check_pkt_len(soc, pkt_len)) {
|
if (dp_rx_check_pkt_len(soc, pkt_len)) {
|
||||||
/* Drop & free packet */
|
/* Drop & free packet */
|
||||||
@@ -1402,7 +1427,7 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
* Advance the packet start pointer by total size of
|
* Advance the packet start pointer by total size of
|
||||||
* pre-header TLV's
|
* pre-header TLV's
|
||||||
*/
|
*/
|
||||||
dp_rx_skip_tlvs(nbuf, l2_hdr_offset);
|
dp_rx_skip_tlvs(soc, nbuf, l2_hdr_offset);
|
||||||
|
|
||||||
if (err_code == HAL_RXDMA_ERR_WIFI_PARSE) {
|
if (err_code == HAL_RXDMA_ERR_WIFI_PARSE) {
|
||||||
uint8_t *pkt_type;
|
uint8_t *pkt_type;
|
||||||
@@ -1533,7 +1558,8 @@ void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
is_raw = HAL_IS_DECAP_FORMAT_RAW(soc->hal_soc, qdf_nbuf_data(nbuf));
|
is_raw = HAL_IS_DECAP_FORMAT_RAW(soc->hal_soc, qdf_nbuf_data(nbuf));
|
||||||
if (is_raw) {
|
if (is_raw) {
|
||||||
fragno = dp_rx_frag_get_mpdu_frag_number(qdf_nbuf_data(nbuf));
|
fragno = dp_rx_frag_get_mpdu_frag_number(soc,
|
||||||
|
qdf_nbuf_data(nbuf));
|
||||||
/* Can get only last fragment */
|
/* Can get only last fragment */
|
||||||
if (fragno) {
|
if (fragno) {
|
||||||
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
|
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
|
||||||
@@ -1671,19 +1697,19 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
|
uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
|
||||||
uint8_t mac_id = 0;
|
uint8_t mac_id = 0;
|
||||||
uint8_t buf_type;
|
uint8_t buf_type;
|
||||||
uint8_t error, rbm;
|
uint8_t error;
|
||||||
struct hal_rx_mpdu_desc_info mpdu_desc_info;
|
struct hal_rx_mpdu_desc_info mpdu_desc_info;
|
||||||
struct hal_buf_info hbi;
|
struct hal_buf_info hbi;
|
||||||
struct dp_pdev *dp_pdev;
|
struct dp_pdev *dp_pdev;
|
||||||
struct dp_srng *dp_rxdma_srng;
|
struct dp_srng *dp_rxdma_srng;
|
||||||
struct rx_desc_pool *rx_desc_pool;
|
struct rx_desc_pool *rx_desc_pool;
|
||||||
uint32_t cookie = 0;
|
|
||||||
void *link_desc_va;
|
void *link_desc_va;
|
||||||
struct hal_rx_msdu_list msdu_list; /* MSDU's per MPDU */
|
struct hal_rx_msdu_list msdu_list; /* MSDU's per MPDU */
|
||||||
uint16_t num_msdus;
|
uint16_t num_msdus;
|
||||||
struct dp_rx_desc *rx_desc = NULL;
|
struct dp_rx_desc *rx_desc = NULL;
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
uint32_t error_code = 0;
|
||||||
|
|
||||||
/* Debug -- Remove later */
|
/* Debug -- Remove later */
|
||||||
qdf_assert(soc && hal_ring_hdl);
|
qdf_assert(soc && hal_ring_hdl);
|
||||||
@@ -1712,12 +1738,12 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
|
|
||||||
DP_STATS_INC(soc, rx.err_ring_pkts, 1);
|
DP_STATS_INC(soc, rx.err_ring_pkts, 1);
|
||||||
|
|
||||||
error = HAL_RX_ERROR_STATUS_GET(ring_desc);
|
error = hal_rx_err_status_get(hal_soc, ring_desc);
|
||||||
|
|
||||||
buf_type = HAL_RX_REO_BUF_TYPE_GET(ring_desc);
|
buf_type = hal_rx_reo_buf_type_get(hal_soc, ring_desc);
|
||||||
|
|
||||||
/* Get the MPDU DESC info */
|
/* Get the MPDU DESC info */
|
||||||
hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
|
hal_rx_mpdu_desc_info_get(hal_soc, ring_desc, &mpdu_desc_info);
|
||||||
|
|
||||||
if (mpdu_desc_info.msdu_count == 0)
|
if (mpdu_desc_info.msdu_count == 0)
|
||||||
goto next_entry;
|
goto next_entry;
|
||||||
@@ -1727,11 +1753,12 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
*/
|
*/
|
||||||
qdf_assert_always(buf_type == HAL_RX_REO_MSDU_LINK_DESC_TYPE);
|
qdf_assert_always(buf_type == HAL_RX_REO_MSDU_LINK_DESC_TYPE);
|
||||||
|
|
||||||
cookie = HAL_RX_REO_BUF_COOKIE_GET(ring_desc);
|
hal_rx_buf_cookie_rbm_get(hal_soc, (uint32_t *)ring_desc,
|
||||||
|
&hbi);
|
||||||
/*
|
/*
|
||||||
* check for the magic number in the sw cookie
|
* check for the magic number in the sw cookie
|
||||||
*/
|
*/
|
||||||
qdf_assert_always((cookie >> LINK_DESC_ID_SHIFT) &
|
qdf_assert_always((hbi.sw_cookie >> LINK_DESC_ID_SHIFT) &
|
||||||
LINK_DESC_ID_START);
|
LINK_DESC_ID_START);
|
||||||
|
|
||||||
status = dp_rx_link_cookie_check(ring_desc);
|
status = dp_rx_link_cookie_check(ring_desc);
|
||||||
@@ -1740,11 +1767,6 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if the buffer is to be processed on this processor
|
|
||||||
*/
|
|
||||||
rbm = hal_rx_ret_buf_manager_get(ring_desc);
|
|
||||||
|
|
||||||
hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
|
hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
|
||||||
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &hbi);
|
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &hbi);
|
||||||
hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
|
hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
|
||||||
@@ -1752,10 +1774,13 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
dp_rx_err_ring_record_entry(soc, msdu_list.paddr[0],
|
dp_rx_err_ring_record_entry(soc, msdu_list.paddr[0],
|
||||||
msdu_list.sw_cookie[0],
|
msdu_list.sw_cookie[0],
|
||||||
msdu_list.rbm[0]);
|
msdu_list.rbm[0]);
|
||||||
if (qdf_unlikely((msdu_list.rbm[0] != DP_WBM2SW_RBM) &&
|
// TODO - BE- Check if the RBM is to be checked for all chips
|
||||||
(msdu_list.rbm[0] !=
|
if (qdf_unlikely((msdu_list.rbm[0] !=
|
||||||
HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST) &&
|
DP_WBM2SW_RBM(soc->wbm_sw0_bm_id)) &&
|
||||||
(msdu_list.rbm[0] != DP_DEFRAG_RBM))) {
|
(msdu_list.rbm[0] !=
|
||||||
|
HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST) &&
|
||||||
|
(msdu_list.rbm[0] !=
|
||||||
|
DP_DEFRAG_RBM(soc->wbm_sw0_bm_id)))) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/* Call appropriate handler */
|
/* Call appropriate handler */
|
||||||
if (!wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) {
|
if (!wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) {
|
||||||
@@ -1842,7 +1867,9 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
*/
|
*/
|
||||||
qdf_assert_always(error == HAL_REO_ERROR_DETECTED);
|
qdf_assert_always(error == HAL_REO_ERROR_DETECTED);
|
||||||
|
|
||||||
if (hal_rx_reo_is_pn_error(ring_desc)) {
|
error_code = hal_rx_get_reo_error_code(hal_soc, ring_desc);
|
||||||
|
|
||||||
|
if (hal_rx_reo_is_pn_error(error_code)) {
|
||||||
/* TOD0 */
|
/* TOD0 */
|
||||||
DP_STATS_INC(soc,
|
DP_STATS_INC(soc,
|
||||||
rx.err.
|
rx.err.
|
||||||
@@ -1861,7 +1888,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
goto next_entry;
|
goto next_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hal_rx_reo_is_2k_jump(ring_desc)) {
|
if (hal_rx_reo_is_2k_jump(error_code)) {
|
||||||
/* TOD0 */
|
/* TOD0 */
|
||||||
DP_STATS_INC(soc,
|
DP_STATS_INC(soc,
|
||||||
rx.err.
|
rx.err.
|
||||||
@@ -1883,7 +1910,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
goto next_entry;
|
goto next_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hal_rx_reo_is_oor_error(ring_desc)) {
|
if (hal_rx_reo_is_oor_error(error_code)) {
|
||||||
DP_STATS_INC(
|
DP_STATS_INC(
|
||||||
soc,
|
soc,
|
||||||
rx.err.
|
rx.err.
|
||||||
@@ -1983,8 +2010,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL };
|
union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL };
|
||||||
uint32_t rx_bufs_used = 0;
|
uint32_t rx_bufs_used = 0;
|
||||||
uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
|
uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
|
||||||
uint8_t buf_type, rbm;
|
uint8_t buf_type;
|
||||||
uint32_t rx_buf_cookie;
|
|
||||||
uint8_t mac_id;
|
uint8_t mac_id;
|
||||||
struct dp_pdev *dp_pdev;
|
struct dp_pdev *dp_pdev;
|
||||||
struct dp_srng *dp_rxdma_srng;
|
struct dp_srng *dp_rxdma_srng;
|
||||||
@@ -1998,6 +2024,8 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
uint8_t tid = 0;
|
uint8_t tid = 0;
|
||||||
uint8_t msdu_continuation = 0;
|
uint8_t msdu_continuation = 0;
|
||||||
bool process_sg_buf = false;
|
bool process_sg_buf = false;
|
||||||
|
uint32_t wbm_err_src;
|
||||||
|
struct hal_buf_info buf_info = {0};
|
||||||
|
|
||||||
/* Debug -- Remove later */
|
/* Debug -- Remove later */
|
||||||
qdf_assert(soc && hal_ring_hdl);
|
qdf_assert(soc && hal_ring_hdl);
|
||||||
@@ -2032,32 +2060,34 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
*/
|
*/
|
||||||
qdf_assert_always(buf_type == HAL_RX_WBM_BUF_TYPE_REL_BUF);
|
qdf_assert_always(buf_type == HAL_RX_WBM_BUF_TYPE_REL_BUF);
|
||||||
|
|
||||||
qdf_assert((HAL_RX_WBM_ERR_SRC_GET(ring_desc)
|
wbm_err_src = hal_rx_wbm_err_src_get(hal_soc, ring_desc);
|
||||||
== HAL_RX_WBM_ERR_SRC_RXDMA) ||
|
qdf_assert((wbm_err_src == HAL_RX_WBM_ERR_SRC_RXDMA) ||
|
||||||
(HAL_RX_WBM_ERR_SRC_GET(ring_desc)
|
(wbm_err_src == HAL_RX_WBM_ERR_SRC_REO));
|
||||||
== HAL_RX_WBM_ERR_SRC_REO));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the buffer is to be processed on this processor
|
* Check if the buffer is to be processed on this processor
|
||||||
*/
|
*/
|
||||||
rbm = hal_rx_ret_buf_manager_get(ring_desc);
|
|
||||||
|
|
||||||
if (qdf_unlikely(rbm != HAL_RX_BUF_RBM_SW3_BM)) {
|
/* only cookie and rbm will be valid in buf_info */
|
||||||
|
hal_rx_buf_cookie_rbm_get(hal_soc, (uint32_t *)ring_desc,
|
||||||
|
&buf_info);
|
||||||
|
|
||||||
|
if (qdf_unlikely(buf_info.rbm !=
|
||||||
|
HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id))) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/* Call appropriate handler */
|
/* Call appropriate handler */
|
||||||
DP_STATS_INC(soc, rx.err.invalid_rbm, 1);
|
DP_STATS_INC(soc, rx.err.invalid_rbm, 1);
|
||||||
dp_rx_err_err("%pK: Invalid RBM %d", soc, rbm);
|
dp_rx_err_err("%pK: Invalid RBM %d", soc,
|
||||||
|
buf_info.rbm);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc);
|
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, buf_info.sw_cookie);
|
||||||
|
|
||||||
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie);
|
|
||||||
qdf_assert_always(rx_desc);
|
qdf_assert_always(rx_desc);
|
||||||
|
|
||||||
if (!dp_rx_desc_check_magic(rx_desc)) {
|
if (!dp_rx_desc_check_magic(rx_desc)) {
|
||||||
dp_rx_err_err("%pk: Invalid rx_desc cookie=%d",
|
dp_rx_err_err("%pk: Invalid rx_desc cookie=%d",
|
||||||
soc, rx_buf_cookie);
|
soc, buf_info.sw_cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2091,13 +2121,15 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
if (qdf_unlikely(soc->wbm_release_desc_rx_sg_support &&
|
if (qdf_unlikely(soc->wbm_release_desc_rx_sg_support &&
|
||||||
dp_rx_is_sg_formation_required(&wbm_err_info))) {
|
dp_rx_is_sg_formation_required(&wbm_err_info))) {
|
||||||
/* SG is detected from continuation bit */
|
/* SG is detected from continuation bit */
|
||||||
msdu_continuation = hal_rx_wbm_err_msdu_continuation_get(hal_soc,
|
msdu_continuation =
|
||||||
ring_desc);
|
hal_rx_wbm_err_msdu_continuation_get(hal_soc,
|
||||||
|
ring_desc);
|
||||||
if (msdu_continuation &&
|
if (msdu_continuation &&
|
||||||
!(soc->wbm_sg_param.wbm_is_first_msdu_in_sg)) {
|
!(soc->wbm_sg_param.wbm_is_first_msdu_in_sg)) {
|
||||||
/* Update length from first buffer in SG */
|
/* Update length from first buffer in SG */
|
||||||
soc->wbm_sg_param.wbm_sg_desc_msdu_len =
|
soc->wbm_sg_param.wbm_sg_desc_msdu_len =
|
||||||
hal_rx_msdu_start_msdu_len_get(
|
hal_rx_msdu_start_msdu_len_get(
|
||||||
|
soc->hal_soc,
|
||||||
qdf_nbuf_data(nbuf));
|
qdf_nbuf_data(nbuf));
|
||||||
soc->wbm_sg_param.wbm_is_first_msdu_in_sg = true;
|
soc->wbm_sg_param.wbm_is_first_msdu_in_sg = true;
|
||||||
}
|
}
|
||||||
@@ -2122,8 +2154,10 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||||||
* info when we do the actual nbuf processing
|
* info when we do the actual nbuf processing
|
||||||
*/
|
*/
|
||||||
wbm_err_info.pool_id = rx_desc->pool_id;
|
wbm_err_info.pool_id = rx_desc->pool_id;
|
||||||
hal_rx_wbm_err_info_set_in_tlv(qdf_nbuf_data(nbuf),
|
hal_rx_priv_info_set_in_tlv(soc->hal_soc,
|
||||||
&wbm_err_info);
|
qdf_nbuf_data(nbuf),
|
||||||
|
(uint8_t *)&wbm_err_info,
|
||||||
|
sizeof(wbm_err_info));
|
||||||
|
|
||||||
rx_bufs_reaped[rx_desc->pool_id]++;
|
rx_bufs_reaped[rx_desc->pool_id]++;
|
||||||
|
|
||||||
@@ -2187,7 +2221,9 @@ done:
|
|||||||
* retrieve the wbm desc info from nbuf TLV, so we can
|
* retrieve the wbm desc info from nbuf TLV, so we can
|
||||||
* handle error cases appropriately
|
* handle error cases appropriately
|
||||||
*/
|
*/
|
||||||
hal_rx_wbm_err_info_get_from_tlv(rx_tlv_hdr, &wbm_err_info);
|
hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_tlv_hdr,
|
||||||
|
(uint8_t *)&wbm_err_info,
|
||||||
|
sizeof(wbm_err_info));
|
||||||
|
|
||||||
peer_id = hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
|
peer_id = hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
|
||||||
rx_tlv_hdr);
|
rx_tlv_hdr);
|
||||||
@@ -2262,7 +2298,7 @@ done:
|
|||||||
}
|
}
|
||||||
QDF_NBUF_CB_RX_PKT_LEN(nbuf) =
|
QDF_NBUF_CB_RX_PKT_LEN(nbuf) =
|
||||||
hal_rx_msdu_start_msdu_len_get(
|
hal_rx_msdu_start_msdu_len_get(
|
||||||
rx_tlv_hdr);
|
soc->hal_soc, rx_tlv_hdr);
|
||||||
nbuf->next = NULL;
|
nbuf->next = NULL;
|
||||||
dp_2k_jump_handle(soc, nbuf,
|
dp_2k_jump_handle(soc, nbuf,
|
||||||
rx_tlv_hdr,
|
rx_tlv_hdr,
|
||||||
@@ -2282,7 +2318,7 @@ done:
|
|||||||
}
|
}
|
||||||
QDF_NBUF_CB_RX_PKT_LEN(nbuf) =
|
QDF_NBUF_CB_RX_PKT_LEN(nbuf) =
|
||||||
hal_rx_msdu_start_msdu_len_get(
|
hal_rx_msdu_start_msdu_len_get(
|
||||||
rx_tlv_hdr);
|
soc->hal_soc, rx_tlv_hdr);
|
||||||
nbuf->next = NULL;
|
nbuf->next = NULL;
|
||||||
dp_rx_oor_handle(soc, nbuf,
|
dp_rx_oor_handle(soc, nbuf,
|
||||||
rx_tlv_hdr,
|
rx_tlv_hdr,
|
||||||
@@ -2464,8 +2500,8 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
|
hal_rx_reo_ent_buf_paddr_get(soc->hal_soc, rxdma_dst_ring_desc,
|
||||||
&msdu_cnt);
|
&buf_info, &msdu_cnt);
|
||||||
|
|
||||||
push_reason =
|
push_reason =
|
||||||
hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc);
|
hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc);
|
||||||
@@ -2492,9 +2528,10 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
* else iterate through the msdu link desc list and
|
* else iterate through the msdu link desc list and
|
||||||
* free each msdu in the list.
|
* free each msdu in the list.
|
||||||
*/
|
*/
|
||||||
if (msdu_list.rbm[0] != HAL_RX_BUF_RBM_SW3_BM &&
|
if (msdu_list.rbm[0] !=
|
||||||
wlan_cfg_get_dp_pdev_nss_enabled(
|
HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id) &&
|
||||||
pdev->wlan_cfg_ctx))
|
wlan_cfg_get_dp_pdev_nss_enabled(
|
||||||
|
pdev->wlan_cfg_ctx))
|
||||||
bm_action = HAL_BM_ACTION_RELEASE_MSDU_LIST;
|
bm_action = HAL_BM_ACTION_RELEASE_MSDU_LIST;
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < num_msdus; i++) {
|
for (i = 0; i < num_msdus; i++) {
|
||||||
@@ -2555,10 +2592,12 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
* Store the current link buffer into to the local structure
|
* Store the current link buffer into to the local structure
|
||||||
* to be used for release purpose.
|
* to be used for release purpose.
|
||||||
*/
|
*/
|
||||||
hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr,
|
hal_rxdma_buff_addr_info_set(soc->hal_soc, rx_link_buf_info,
|
||||||
buf_info.sw_cookie, buf_info.rbm);
|
buf_info.paddr, buf_info.sw_cookie,
|
||||||
|
buf_info.rbm);
|
||||||
|
|
||||||
hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info);
|
hal_rx_mon_next_link_desc_get(soc->hal_soc, rx_msdu_link_desc,
|
||||||
|
&buf_info);
|
||||||
dp_rx_link_desc_return_by_addr(soc,
|
dp_rx_link_desc_return_by_addr(soc,
|
||||||
(hal_buff_addrinfo_t)
|
(hal_buff_addrinfo_t)
|
||||||
rx_link_buf_info,
|
rx_link_buf_info,
|
||||||
@@ -2662,8 +2701,8 @@ dp_wbm_int_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
|
hal_rx_reo_ent_buf_paddr_get(soc->hal_soc, rxdma_dst_ring_desc,
|
||||||
&msdu_cnt);
|
&buf_info, &msdu_cnt);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rx_msdu_link_desc =
|
rx_msdu_link_desc =
|
||||||
@@ -2714,10 +2753,12 @@ dp_wbm_int_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
* Store the current link buffer into to the local structure
|
* Store the current link buffer into to the local structure
|
||||||
* to be used for release purpose.
|
* to be used for release purpose.
|
||||||
*/
|
*/
|
||||||
hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr,
|
hal_rxdma_buff_addr_info_set(soc->hal_soc, rx_link_buf_info,
|
||||||
buf_info.sw_cookie, buf_info.rbm);
|
buf_info.paddr, buf_info.sw_cookie,
|
||||||
|
buf_info.rbm);
|
||||||
|
|
||||||
hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info);
|
hal_rx_mon_next_link_desc_get(soc->hal_soc, rx_msdu_link_desc,
|
||||||
|
&buf_info);
|
||||||
dp_rx_link_desc_return_by_addr(soc, (hal_buff_addrinfo_t)
|
dp_rx_link_desc_return_by_addr(soc, (hal_buff_addrinfo_t)
|
||||||
rx_link_buf_info,
|
rx_link_buf_info,
|
||||||
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
||||||
@@ -2753,7 +2794,6 @@ dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc,
|
|||||||
struct hal_buf_info buf_info = {0};
|
struct hal_buf_info buf_info = {0};
|
||||||
struct dp_rx_desc *rx_desc = NULL;
|
struct dp_rx_desc *rx_desc = NULL;
|
||||||
struct rx_desc_pool *rx_desc_pool;
|
struct rx_desc_pool *rx_desc_pool;
|
||||||
uint32_t rx_buf_cookie;
|
|
||||||
uint32_t rx_bufs_reaped = 0;
|
uint32_t rx_bufs_reaped = 0;
|
||||||
union dp_rx_desc_list_elem_t *head = NULL;
|
union dp_rx_desc_list_elem_t *head = NULL;
|
||||||
union dp_rx_desc_list_elem_t *tail = NULL;
|
union dp_rx_desc_list_elem_t *tail = NULL;
|
||||||
@@ -2766,12 +2806,14 @@ dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(hal_desc);
|
/* buffer_addr_info is the first element of ring_desc */
|
||||||
pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(rx_buf_cookie);
|
hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)hal_desc,
|
||||||
|
&buf_info);
|
||||||
|
pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(buf_info.sw_cookie);
|
||||||
|
|
||||||
if (buf_type == HAL_WBM_RELEASE_RING_2_BUFFER_TYPE) {
|
if (buf_type == HAL_WBM_RELEASE_RING_2_BUFFER_TYPE) {
|
||||||
DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_MSDU_BUFF], 1);
|
DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_MSDU_BUFF], 1);
|
||||||
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie);
|
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, buf_info.sw_cookie);
|
||||||
|
|
||||||
if (rx_desc && rx_desc->nbuf) {
|
if (rx_desc && rx_desc->nbuf) {
|
||||||
rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id];
|
rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id];
|
||||||
|
Reference in New Issue
Block a user