Loading drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h +13 −1 Original line number Diff line number Diff line /* * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2021 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 Loading Loading @@ -170,4 +170,16 @@ void ol_txrx_remove_peers_for_vdev_no_lock(ol_txrx_vdev_handle vdev, ol_txrx_vdev_peer_remove_cb callback, void *callback_context); /** * ol_txrx_peer_flush_frags() - Flush fragments for a particular peer * @pdev - datapath pdev handle * @vdev_id - virtual device id * @peer_mac - peer mac address * * Return: None */ void ol_txrx_peer_flush_frags(ol_txrx_pdev_handle pdev, uint8_t vdev_id, uint8_t *peer_mac); #endif /* _CDP_TXRX_PEER_H_ */ drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c +33 −3 Original line number Diff line number Diff line /* * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2011-2019, 2021 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 Loading Loading @@ -445,6 +445,8 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev, struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; uint16_t frxseq, rxseq, seq; htt_pdev_handle htt_pdev = pdev->htt_pdev; void *rx_desc; uint8_t index; seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask; qdf_assert(seq == 0); Loading @@ -458,6 +460,28 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev, IEEE80211_SEQ_FRAG_MASK; more_frag = mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG; rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag); qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(htt_pdev, rx_desc)); index = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc) ? txrx_sec_mcast : txrx_sec_ucast; /* * Multicast/Broadcast frames should not be fragmented so drop * such frames. */ if (index != txrx_sec_ucast) { ol_rx_frames_free(htt_pdev, frag); return; } if (peer->security[index].sec_type != htt_sec_type_none && !htt_rx_mpdu_is_encrypted(htt_pdev, rx_desc)) { ol_txrx_err("Unencrypted fragment received in security mode %d", peer->security[index].sec_type); ol_rx_frames_free(htt_pdev, frag); return; } if ((!more_frag) && (!fragno) && (!rx_reorder_array_elem->head)) { ol_rx_fraglist_insert(htt_pdev, &rx_reorder_array_elem->head, &rx_reorder_array_elem->tail, frag, &all_frag_present); Loading Loading @@ -700,7 +724,13 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, while (cur) { tmp_next = qdf_nbuf_next(cur); qdf_nbuf_set_next(cur, NULL); if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) { /* * Strict PN check between the first fragment of the current * frame and the last fragment of the previous frame is not * necessary. */ if (!ol_rx_pn_check_base(vdev, peer, tid, cur, (cur == frag_list) ? false : true)) { /* PN check failed,discard frags */ if (prev) { qdf_nbuf_set_next(prev, NULL); Loading Loading @@ -935,7 +965,7 @@ ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const uint8_t *key, ol_rx_defrag_copydata(msdu, pktlen - f_tkip.ic_miclen + rx_desc_len, f_tkip.ic_miclen, (caddr_t) mic0); if (!qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) if (qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) return OL_RX_DEFRAG_ERR; qdf_nbuf_trim_tail(msdu, f_tkip.ic_miclen); Loading drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c +22 −1 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2014-2018, 2021 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 Loading Loading @@ -150,6 +150,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, while (msdu) { struct ol_txrx_vdev_t *tx_vdev; void *rx_desc; uint16_t off = 0; /* * Remember the next list elem, because our processing * may cause the MSDU to get linked into a different list. Loading Loading @@ -204,6 +205,26 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, continue; } if (pdev->cfg.is_high_latency) off = htt_rx_msdu_rx_desc_size_hl( pdev->htt_pdev, rx_desc); if (vdev->opmode == wlan_op_mode_ap && __qdf_nbuf_data_is_ipv4_eapol_pkt( qdf_nbuf_data(msdu) + off) && qdf_mem_cmp(qdf_nbuf_data(msdu) + QDF_NBUF_DEST_MAC_OFFSET, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE)) { TXRX_STATS_MSDU_LIST_INCR( pdev, tx.dropped.host_reject, msdu); qdf_nbuf_set_next(msdu, NULL); qdf_nbuf_tx_free(msdu, QDF_NBUF_PKT_ERROR); msdu = msdu_list; continue; } /* * This MSDU needs to be forwarded to the tx path. * Check whether it also needs to be sent to the OS Loading drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c +24 −13 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2013-2017 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2013-2017, 2021 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 Loading Loading @@ -37,25 +37,36 @@ } while (0) int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff)); return rc; if (strict_chk) return ((new_pn->pn24 & 0xffffff) - (old_pn->pn24 & 0xffffff) != 1); else return ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff)); } int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int rc = ((new_pn->pn48 & 0xffffffffffffULL) <= if (strict_chk) return ((new_pn->pn48 & 0xffffffffffffULL) - (old_pn->pn48 & 0xffffffffffffULL) != 1); else return ((new_pn->pn48 & 0xffffffffffffULL) <= (old_pn->pn48 & 0xffffffffffffULL)); return rc; } int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int pn_is_replay = 0; /* TODO Strick check for WAPI is not implemented*/ if (new_pn->pn128[1] == old_pn->pn128[1]) pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]); else Loading @@ -73,7 +84,7 @@ int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, qdf_nbuf_t ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk) { struct ol_txrx_pdev_t *pdev = vdev->pdev; union htt_rx_pn_t *last_pn; Loading Loading @@ -132,7 +143,7 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, pn_is_replay = pdev->rx_pn[peer->security[index].sec_type]. cmp(&new_pn, last_pn, index == txrx_sec_ucast, vdev->opmode); vdev->opmode, strict_chk); } else { last_pn_valid = peer->tids_last_pn_valid[tid] = 1; } Loading Loading @@ -253,7 +264,7 @@ ol_rx_pn_check(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) { msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false); ol_rx_fwd_check(vdev, peer, tid, msdu_list); } Loading @@ -262,7 +273,7 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) { msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false); ol_rx_deliver(vdev, peer, tid, msdu_list); } Loading drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h +9 −5 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2014-2017, 2021 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 Loading @@ -24,13 +24,16 @@ #include <ol_txrx_api.h> /* ol_txrx_peer_t, etc. */ int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); /** * @brief If applicable, check the Packet Number to detect replays. Loading Loading @@ -87,11 +90,12 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev, * @param tid - which TID within the peer the rx frames belong to * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on * (if PN check is applicable, i.e. PN length > 0) * @param strick_chk - if PN consecutive stric check is needed or not * @return list of netbufs that didn't fail the PN check */ qdf_nbuf_t ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list); unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk); #endif /* _OL_RX_PN_H_ */ Loading
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h +13 −1 Original line number Diff line number Diff line /* * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2021 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 Loading Loading @@ -170,4 +170,16 @@ void ol_txrx_remove_peers_for_vdev_no_lock(ol_txrx_vdev_handle vdev, ol_txrx_vdev_peer_remove_cb callback, void *callback_context); /** * ol_txrx_peer_flush_frags() - Flush fragments for a particular peer * @pdev - datapath pdev handle * @vdev_id - virtual device id * @peer_mac - peer mac address * * Return: None */ void ol_txrx_peer_flush_frags(ol_txrx_pdev_handle pdev, uint8_t vdev_id, uint8_t *peer_mac); #endif /* _CDP_TXRX_PEER_H_ */
drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c +33 −3 Original line number Diff line number Diff line /* * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2011-2019, 2021 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 Loading Loading @@ -445,6 +445,8 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev, struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; uint16_t frxseq, rxseq, seq; htt_pdev_handle htt_pdev = pdev->htt_pdev; void *rx_desc; uint8_t index; seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask; qdf_assert(seq == 0); Loading @@ -458,6 +460,28 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev, IEEE80211_SEQ_FRAG_MASK; more_frag = mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG; rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag); qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(htt_pdev, rx_desc)); index = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc) ? txrx_sec_mcast : txrx_sec_ucast; /* * Multicast/Broadcast frames should not be fragmented so drop * such frames. */ if (index != txrx_sec_ucast) { ol_rx_frames_free(htt_pdev, frag); return; } if (peer->security[index].sec_type != htt_sec_type_none && !htt_rx_mpdu_is_encrypted(htt_pdev, rx_desc)) { ol_txrx_err("Unencrypted fragment received in security mode %d", peer->security[index].sec_type); ol_rx_frames_free(htt_pdev, frag); return; } if ((!more_frag) && (!fragno) && (!rx_reorder_array_elem->head)) { ol_rx_fraglist_insert(htt_pdev, &rx_reorder_array_elem->head, &rx_reorder_array_elem->tail, frag, &all_frag_present); Loading Loading @@ -700,7 +724,13 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, while (cur) { tmp_next = qdf_nbuf_next(cur); qdf_nbuf_set_next(cur, NULL); if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) { /* * Strict PN check between the first fragment of the current * frame and the last fragment of the previous frame is not * necessary. */ if (!ol_rx_pn_check_base(vdev, peer, tid, cur, (cur == frag_list) ? false : true)) { /* PN check failed,discard frags */ if (prev) { qdf_nbuf_set_next(prev, NULL); Loading Loading @@ -935,7 +965,7 @@ ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const uint8_t *key, ol_rx_defrag_copydata(msdu, pktlen - f_tkip.ic_miclen + rx_desc_len, f_tkip.ic_miclen, (caddr_t) mic0); if (!qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) if (qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) return OL_RX_DEFRAG_ERR; qdf_nbuf_trim_tail(msdu, f_tkip.ic_miclen); Loading
drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c +22 −1 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2014-2018, 2021 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 Loading Loading @@ -150,6 +150,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, while (msdu) { struct ol_txrx_vdev_t *tx_vdev; void *rx_desc; uint16_t off = 0; /* * Remember the next list elem, because our processing * may cause the MSDU to get linked into a different list. Loading Loading @@ -204,6 +205,26 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, continue; } if (pdev->cfg.is_high_latency) off = htt_rx_msdu_rx_desc_size_hl( pdev->htt_pdev, rx_desc); if (vdev->opmode == wlan_op_mode_ap && __qdf_nbuf_data_is_ipv4_eapol_pkt( qdf_nbuf_data(msdu) + off) && qdf_mem_cmp(qdf_nbuf_data(msdu) + QDF_NBUF_DEST_MAC_OFFSET, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE)) { TXRX_STATS_MSDU_LIST_INCR( pdev, tx.dropped.host_reject, msdu); qdf_nbuf_set_next(msdu, NULL); qdf_nbuf_tx_free(msdu, QDF_NBUF_PKT_ERROR); msdu = msdu_list; continue; } /* * This MSDU needs to be forwarded to the tx path. * Check whether it also needs to be sent to the OS Loading
drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c +24 −13 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2013-2017 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2013-2017, 2021 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 Loading Loading @@ -37,25 +37,36 @@ } while (0) int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff)); return rc; if (strict_chk) return ((new_pn->pn24 & 0xffffff) - (old_pn->pn24 & 0xffffff) != 1); else return ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff)); } int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int rc = ((new_pn->pn48 & 0xffffffffffffULL) <= if (strict_chk) return ((new_pn->pn48 & 0xffffffffffffULL) - (old_pn->pn48 & 0xffffffffffffULL) != 1); else return ((new_pn->pn48 & 0xffffffffffffULL) <= (old_pn->pn48 & 0xffffffffffffULL)); return rc; } int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode) union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk) { int pn_is_replay = 0; /* TODO Strick check for WAPI is not implemented*/ if (new_pn->pn128[1] == old_pn->pn128[1]) pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]); else Loading @@ -73,7 +84,7 @@ int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, qdf_nbuf_t ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk) { struct ol_txrx_pdev_t *pdev = vdev->pdev; union htt_rx_pn_t *last_pn; Loading Loading @@ -132,7 +143,7 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, pn_is_replay = pdev->rx_pn[peer->security[index].sec_type]. cmp(&new_pn, last_pn, index == txrx_sec_ucast, vdev->opmode); vdev->opmode, strict_chk); } else { last_pn_valid = peer->tids_last_pn_valid[tid] = 1; } Loading Loading @@ -253,7 +264,7 @@ ol_rx_pn_check(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) { msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false); ol_rx_fwd_check(vdev, peer, tid, msdu_list); } Loading @@ -262,7 +273,7 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list) { msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false); ol_rx_deliver(vdev, peer, tid, msdu_list); } Loading
drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h +9 −5 Original line number Diff line number Diff line /* * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2014-2017, 2021 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 Loading @@ -24,13 +24,16 @@ #include <ol_txrx_api.h> /* ol_txrx_peer_t, etc. */ int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn, union htt_rx_pn_t *old_pn, int is_unicast, int opmode); union htt_rx_pn_t *old_pn, int is_unicast, int opmode, bool strict_chk); /** * @brief If applicable, check the Packet Number to detect replays. Loading Loading @@ -87,11 +90,12 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev, * @param tid - which TID within the peer the rx frames belong to * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on * (if PN check is applicable, i.e. PN length > 0) * @param strick_chk - if PN consecutive stric check is needed or not * @return list of netbufs that didn't fail the PN check */ qdf_nbuf_t ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t msdu_list); unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk); #endif /* _OL_RX_PN_H_ */