浏览代码

qcacmn: Parse EHT-SIG header from PHY tlv

Add support to parse the EHT-SIG header from
the PHY TLV for EHT data traffic.

Change-Id: I05773c0086d1b67df8a08872832e36a96fb4b0b0
CRs-Fixed: 3093087
Rakesh Pillai 3 年之前
父节点
当前提交
02df9e2ae8
共有 2 个文件被更改,包括 432 次插入0 次删除
  1. 329 0
      hal/wifi3.0/be/hal_be_generic_api.h
  2. 103 0
      hal/wifi3.0/hal_api_mon.h

+ 329 - 0
hal/wifi3.0/be/hal_be_generic_api.h

@@ -532,6 +532,333 @@ hal_rx_parse_u_sig_hdr(struct hal_soc *hal_soc, void *rx_tlv,
 		return hal_rx_parse_u_sig_mu(hal_soc, rx_tlv, ppdu_info);
 }
 
+static inline uint32_t
+hal_rx_parse_usig_overflow(struct hal_soc *hal_soc, void *tlv,
+			   struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_eht_sig_cc_usig_overflow *usig_ovflow =
+		(struct hal_eht_sig_cc_usig_overflow *)tlv;
+
+	ppdu_info->rx_status.eht_known |=
+		QDF_MON_STATUS_EHT_SPATIAL_REUSE_KNOWN |
+		QDF_MON_STATUS_EHT_EHT_LTF_KNOWN |
+		QDF_MON_STATUS_EHT_LDPC_EXTRA_SYMBOL_SEG_KNOWN |
+		QDF_MON_STATUS_EHT_PRE_FEC_PADDING_FACTOR_KNOWN |
+		QDF_MON_STATUS_EHT_PE_DISAMBIGUITY_KNOWN |
+		QDF_MON_STATUS_EHT_DISREARD_KNOWN;
+
+	ppdu_info->rx_status.eht_data[0] |= (usig_ovflow->spatial_reuse <<
+				QDF_MON_STATUS_EHT_SPATIAL_REUSE_SHIFT);
+	/*
+	 * GI and LTF size are separately indicated in radiotap header
+	 * and hence will be parsed from other TLV
+	 **/
+	ppdu_info->rx_status.eht_data[0] |= (usig_ovflow->num_ltf_sym <<
+				QDF_MON_STATUS_EHT_EHT_LTF_SHIFT);
+	ppdu_info->rx_status.eht_data[0] |= (usig_ovflow->ldpc_extra_sym <<
+				QDF_MON_STATUS_EHT_LDPC_EXTRA_SYMBOL_SEG_SHIFT);
+	ppdu_info->rx_status.eht_data[0] |= (usig_ovflow->pre_fec_pad_factor <<
+			QDF_MON_STATUS_EHT_PRE_FEC_PADDING_FACTOR_SHIFT);
+	ppdu_info->rx_status.eht_data[0] |= (usig_ovflow->pe_disambiguity <<
+				QDF_MON_STATUS_EHT_PE_DISAMBIGUITY_SHIFT);
+	ppdu_info->rx_status.eht_data[0] |= (0xF <<
+				QDF_MON_STATUS_EHT_DISREGARD_SHIFT);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_non_ofdma_users(struct hal_soc *hal_soc, void *tlv,
+			     struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_eht_sig_non_ofdma_cmn_eb *non_ofdma_cmn_eb =
+				(struct hal_eht_sig_non_ofdma_cmn_eb *)tlv;
+
+	ppdu_info->rx_status.eht_known |=
+				QDF_MON_STATUS_EHT_NUM_NON_OFDMA_USERS_KNOWN;
+
+	ppdu_info->rx_status.eht_data[4] |= (non_ofdma_cmn_eb->num_users <<
+				QDF_MON_STATUS_EHT_NUM_NON_OFDMA_USERS_SHIFT);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_ru_allocation(struct hal_soc *hal_soc, void *tlv,
+			   struct hal_rx_ppdu_info *ppdu_info)
+{
+	uint64_t *ehtsig_tlv = (uint64_t *)tlv;
+	struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1;
+	struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2;
+	uint8_t num_ru_allocation_known = 0;
+
+	ofdma_cmn_eb1 = (struct hal_eht_sig_ofdma_cmn_eb1 *)ehtsig_tlv;
+	ofdma_cmn_eb2 = (struct hal_eht_sig_ofdma_cmn_eb2 *)(ehtsig_tlv + 1);
+
+	switch (ppdu_info->u_sig_info.bw) {
+	case HAL_EHT_BW_320_2:
+	case HAL_EHT_BW_320_1:
+		num_ru_allocation_known += 4;
+
+		ppdu_info->rx_status.eht_data[3] |=
+				(ofdma_cmn_eb2->ru_allocation2_6 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_6_SHIFT);
+		ppdu_info->rx_status.eht_data[3] |=
+				(ofdma_cmn_eb2->ru_allocation2_5 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_5_SHIFT);
+		ppdu_info->rx_status.eht_data[3] |=
+				(ofdma_cmn_eb2->ru_allocation2_4 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_4_SHIFT);
+		ppdu_info->rx_status.eht_data[2] |=
+				(ofdma_cmn_eb2->ru_allocation2_3 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_3_SHIFT);
+		/* fallthrough */
+	case HAL_EHT_BW_160:
+		num_ru_allocation_known += 2;
+
+		ppdu_info->rx_status.eht_data[2] |=
+				(ofdma_cmn_eb2->ru_allocation2_2 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_2_SHIFT);
+		ppdu_info->rx_status.eht_data[2] |=
+				(ofdma_cmn_eb2->ru_allocation2_1 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION2_1_SHIFT);
+		/* fallthrough */
+	case HAL_EHT_BW_80:
+		num_ru_allocation_known += 1;
+
+		ppdu_info->rx_status.eht_data[1] |=
+				(ofdma_cmn_eb1->ru_allocation1_2 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION1_2_SHIFT);
+		/* fallthrough */
+	case HAL_EHT_BW_40:
+	case HAL_EHT_BW_20:
+		num_ru_allocation_known += 1;
+
+		ppdu_info->rx_status.eht_data[1] |=
+				(ofdma_cmn_eb1->ru_allocation1_1 <<
+				 QDF_MON_STATUS_EHT_RU_ALLOCATION1_1_SHIFT);
+		break;
+	default:
+		break;
+	}
+
+	ppdu_info->rx_status.eht_known |= (num_ru_allocation_known <<
+			QDF_MON_STATUS_EHT_NUM_KNOWN_RU_ALLOCATIONS_SHIFT);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_mumimo_user_info(struct hal_soc *hal_soc, void *tlv,
+				      struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_eht_sig_mu_mimo_user_info *user_info;
+	uint32_t user_idx = ppdu_info->rx_status.num_eht_user_info_valid;
+
+	user_info = (struct hal_eht_sig_mu_mimo_user_info *)tlv;
+
+	ppdu_info->rx_status.eht_user_info[user_idx] |=
+				QDF_MON_STATUS_EHT_USER_STA_ID_KNOWN |
+				QDF_MON_STATUS_EHT_USER_MCS_KNOWN |
+				QDF_MON_STATUS_EHT_USER_CODING_KNOWN |
+				QDF_MON_STATUS_EHT_USER_SPATIAL_CONFIG_KNOWN;
+
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->sta_id <<
+				QDF_MON_STATUS_EHT_USER_STA_ID_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->mcs <<
+				QDF_MON_STATUS_EHT_USER_MCS_SHIFT);
+
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->coding <<
+					QDF_MON_STATUS_EHT_USER_CODING_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |=
+				(user_info->spatial_coding <<
+				QDF_MON_STATUS_EHT_USER_SPATIAL_CONFIG_SHIFT);
+
+	/* CRC for matched user block */
+	ppdu_info->rx_status.eht_known |=
+			QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_KNOWN |
+			QDF_MON_STATUS_EHT_USER_ENC_BLOCK_TAIL_KNOWN;
+	ppdu_info->rx_status.eht_data[4] |= (user_info->crc <<
+				QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_SHIFT);
+
+	ppdu_info->rx_status.num_eht_user_info_valid++;
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_non_mumimo_user_info(struct hal_soc *hal_soc, void *tlv,
+					  struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_eht_sig_non_mu_mimo_user_info *user_info;
+	uint32_t user_idx = ppdu_info->rx_status.num_eht_user_info_valid;
+
+	user_info = (struct hal_eht_sig_non_mu_mimo_user_info *)tlv;
+
+	ppdu_info->rx_status.eht_user_info[user_idx] |=
+				QDF_MON_STATUS_EHT_USER_STA_ID_KNOWN |
+				QDF_MON_STATUS_EHT_USER_MCS_KNOWN |
+				QDF_MON_STATUS_EHT_USER_CODING_KNOWN |
+				QDF_MON_STATUS_EHT_USER_NSS_KNOWN |
+				QDF_MON_STATUS_EHT_USER_BEAMFORMING_KNOWN;
+
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->sta_id <<
+				QDF_MON_STATUS_EHT_USER_STA_ID_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->mcs <<
+				QDF_MON_STATUS_EHT_USER_MCS_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->nss <<
+					QDF_MON_STATUS_EHT_USER_NSS_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |=
+				(user_info->beamformed <<
+				QDF_MON_STATUS_EHT_USER_BEAMFORMING_SHIFT);
+	ppdu_info->rx_status.eht_user_info[user_idx] |= (user_info->coding <<
+					QDF_MON_STATUS_EHT_USER_CODING_SHIFT);
+
+	/* CRC for matched user block */
+	ppdu_info->rx_status.eht_known |=
+			QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_KNOWN |
+			QDF_MON_STATUS_EHT_USER_ENC_BLOCK_TAIL_KNOWN;
+	ppdu_info->rx_status.eht_data[4] |= (user_info->crc <<
+				QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_SHIFT);
+
+	ppdu_info->rx_status.num_eht_user_info_valid++;
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline bool hal_rx_is_ofdma(struct hal_soc *hal_soc,
+				   struct hal_rx_ppdu_info *ppdu_info)
+{
+	if (ppdu_info->u_sig_info.ppdu_type_comp_mode == 0 &&
+	    ppdu_info->u_sig_info.ul_dl == 0)
+		return true;
+
+	return false;
+}
+
+static inline bool hal_rx_is_non_ofdma(struct hal_soc *hal_soc,
+				       struct hal_rx_ppdu_info *ppdu_info)
+{
+	uint32_t ppdu_type_comp_mode =
+				ppdu_info->u_sig_info.ppdu_type_comp_mode;
+	uint32_t ul_dl = ppdu_info->u_sig_info.ul_dl;
+
+	if ((ppdu_type_comp_mode == 0 && ul_dl == 1) ||
+	    (ppdu_type_comp_mode == 0 && ul_dl == 2) ||
+	    (ppdu_type_comp_mode == 1 && ul_dl == 1))
+		return true;
+
+	return false;
+}
+
+static inline bool hal_rx_is_mu_mimo_user(struct hal_soc *hal_soc,
+					  struct hal_rx_ppdu_info *ppdu_info)
+{
+	if (ppdu_info->u_sig_info.ppdu_type_comp_mode == 0 &&
+	    ppdu_info->u_sig_info.ul_dl == 2)
+		return true;
+
+	return false;
+}
+
+static inline bool
+hal_rx_is_frame_type_ndp(struct hal_soc *hal_soc,
+			 struct hal_rx_ppdu_info *ppdu_info)
+{
+	if (ppdu_info->u_sig_info.ppdu_type_comp_mode == 1 &&
+	    ppdu_info->u_sig_info.eht_sig_mcs == 0 &&
+	    ppdu_info->u_sig_info.num_eht_sig_sym == 0)
+		return true;
+
+	return false;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_ndp(struct hal_soc *hal_soc, void *tlv,
+			 struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp =
+				(struct hal_eht_sig_ndp_cmn_eb *)tlv;
+
+	ppdu_info->rx_status.eht_known |=
+		QDF_MON_STATUS_EHT_SPATIAL_REUSE_KNOWN |
+		QDF_MON_STATUS_EHT_EHT_LTF_KNOWN |
+		QDF_MON_STATUS_EHT_NDP_NSS_KNOWN |
+		QDF_MON_STATUS_EHT_NDP_BEAMFORMED_KNOWN |
+		QDF_MON_STATUS_EHT_NDP_DISREGARD_KNOWN |
+		QDF_MON_STATUS_EHT_CRC1_KNOWN |
+		QDF_MON_STATUS_EHT_TAIL1_KNOWN;
+
+	ppdu_info->rx_status.eht_data[0] |= (eht_sig_ndp->spatial_reuse <<
+				QDF_MON_STATUS_EHT_SPATIAL_REUSE_SHIFT);
+	/*
+	 * GI and LTF size are separately indicated in radiotap header
+	 * and hence will be parsed from other TLV
+	 **/
+	ppdu_info->rx_status.eht_data[0] |= (eht_sig_ndp->num_ltf_sym <<
+				QDF_MON_STATUS_EHT_EHT_LTF_SHIFT);
+	ppdu_info->rx_status.eht_data[0] |= (0xF <<
+				QDF_MON_STATUS_EHT_NDP_DISREGARD_SHIFT);
+
+	ppdu_info->rx_status.eht_data[4] |= (eht_sig_ndp->nss <<
+				QDF_MON_STATUS_EHT_NDP_NSS_SHIFT);
+	ppdu_info->rx_status.eht_data[4] |= (eht_sig_ndp->beamformed <<
+				QDF_MON_STATUS_EHT_NDP_BEAMFORMED_SHIFT);
+
+	ppdu_info->rx_status.eht_data[0] |= (eht_sig_ndp->crc <<
+					QDF_MON_STATUS_EHT_CRC1_SHIFT);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_non_ofdma(struct hal_soc *hal_soc, void *tlv,
+			       struct hal_rx_ppdu_info *ppdu_info)
+{
+	hal_rx_parse_usig_overflow(hal_soc, tlv, ppdu_info);
+	hal_rx_parse_non_ofdma_users(hal_soc, tlv, ppdu_info);
+
+	if (hal_rx_is_mu_mimo_user(hal_soc, ppdu_info))
+		hal_rx_parse_eht_sig_mumimo_user_info(hal_soc, tlv,
+						      ppdu_info);
+	else
+		hal_rx_parse_eht_sig_non_mumimo_user_info(hal_soc, tlv,
+							  ppdu_info);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_ofdma(struct hal_soc *hal_soc, void *tlv,
+			   struct hal_rx_ppdu_info *ppdu_info)
+{
+	uint64_t *eht_sig_tlv = (uint64_t *)tlv;
+	void *user_info = (void *)(eht_sig_tlv + 2);
+
+	hal_rx_parse_usig_overflow(hal_soc, tlv, ppdu_info);
+	hal_rx_parse_ru_allocation(hal_soc, tlv, ppdu_info);
+	hal_rx_parse_eht_sig_non_mumimo_user_info(hal_soc, user_info,
+						  ppdu_info);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
+static inline uint32_t
+hal_rx_parse_eht_sig_hdr(struct hal_soc *hal_soc, uint8_t *tlv,
+			 struct hal_rx_ppdu_info *ppdu_info)
+{
+	ppdu_info->rx_status.eht_flags = 1;
+
+	if (hal_rx_is_frame_type_ndp(hal_soc, ppdu_info))
+		hal_rx_parse_eht_sig_ndp(hal_soc, tlv, ppdu_info);
+	else if (hal_rx_is_non_ofdma(hal_soc, ppdu_info))
+		hal_rx_parse_eht_sig_non_ofdma(hal_soc, tlv, ppdu_info);
+	else if (hal_rx_is_ofdma(hal_soc, ppdu_info))
+		hal_rx_parse_eht_sig_ofdma(hal_soc, tlv, ppdu_info);
+
+	return HAL_TLV_STATUS_PPDU_NOT_DONE;
+}
+
 /**
  * hal_rx_status_get_tlv_info() - process receive info TLV
  * @rx_tlv_hdr: pointer to TLV header
@@ -1676,6 +2003,8 @@ hal_rx_status_process_aggr_tlv(struct hal_soc *hal_soc,
 
 	switch (aggr_tlv_tag) {
 	case WIFIPHYRX_GENERIC_EHT_SIG_E:
+		hal_rx_parse_eht_sig_hdr(hal_soc, ppdu_info->tlv_aggr.buf,
+					 ppdu_info);
 		break;
 	default:
 		/* Aggregated TLV cannot be handled */

+ 103 - 0
hal/wifi3.0/hal_api_mon.h

@@ -763,6 +763,107 @@ struct hal_mon_usig_hdr {
 		 HAL_RX_MON_USIG_RX_INTEGRITY_CHECK_PASSED_MASK) >> \
 		 HAL_RX_MON_USIG_RX_INTEGRITY_CHECK_PASSED_LSB)
 
+/**
+ * enum hal_eht_bw: Reception bandwidth
+ * @HAL_EHT_BW_20: 20Mhz
+ * @HAL_EHT_BW_40: 40Mhz
+ * @HAL_EHT_BW_80: 80Mhz
+ * @HAL_EHT_BW_160: 160Mhz
+ * @HAL_EHT_BW_320_1: 320_1 band
+ * @HAL_EHT_BW_320_2: 320_2 band
+ */
+enum hal_eht_bw {
+	HAL_EHT_BW_20 = 0,
+	HAL_EHT_BW_40,
+	HAL_EHT_BW_80,
+	HAL_EHT_BW_160,
+	HAL_EHT_BW_320_1,
+	HAL_EHT_BW_320_2,
+};
+
+struct hal_eht_sig_mu_mimo_user_info {
+	uint32_t sta_id : 11,
+		 mcs : 4,
+		 coding : 1,
+		 spatial_coding : 6,
+		 crc : 4;
+};
+
+struct hal_eht_sig_non_mu_mimo_user_info {
+	uint32_t sta_id : 11,
+		 mcs : 4,
+		 validate : 1,
+		 nss : 4,
+		 beamformed : 1,
+		 coding : 1,
+		 crc : 4;
+};
+
+/**
+ * union hal_eht_sig_user_field: User field in EHTSIG
+ * @mu_mimo_usr: MU-MIMO user field information in EHTSIG
+ * @non_mu_mimo_usr: Non MU-MIMO user field information in EHTSIG
+ */
+union hal_eht_sig_user_field {
+	struct hal_eht_sig_mu_mimo_user_info mu_mimo_usr;
+	struct hal_eht_sig_non_mu_mimo_user_info non_mu_mimo_usr;
+};
+
+struct hal_eht_sig_ofdma_cmn_eb1 {
+	uint64_t spatial_reuse : 4,
+		 gi_ltf : 2,
+		 num_ltf_sym : 3,
+		 ldpc_extra_sym : 1,
+		 pre_fec_pad_factor : 2,
+		 pe_disambiguity : 1,
+		 disregard : 4,
+		 ru_allocation1_1 : 9,
+		 ru_allocation1_2 : 9,
+		 crc : 4;
+};
+
+struct hal_eht_sig_ofdma_cmn_eb2 {
+	uint64_t ru_allocation2_1 : 9,
+		 ru_allocation2_2 : 9,
+		 ru_allocation2_3 : 9,
+		 ru_allocation2_4 : 9,
+		 ru_allocation2_5 : 9,
+		 ru_allocation2_6 : 9,
+		 crc : 4;
+};
+
+struct hal_eht_sig_cc_usig_overflow {
+	uint32_t spatial_reuse : 4,
+		 gi_ltf : 2,
+		 num_ltf_sym : 3,
+		 ldpc_extra_sym : 1,
+		 pre_fec_pad_factor : 2,
+		 pe_disambiguity : 1,
+		 disregard : 4;
+};
+
+struct hal_eht_sig_non_ofdma_cmn_eb {
+	uint32_t spatial_reuse : 4,
+		 gi_ltf : 2,
+		 num_ltf_sym : 3,
+		 ldpc_extra_sym : 1,
+		 pre_fec_pad_factor : 2,
+		 pe_disambiguity : 1,
+		 disregard : 4,
+		 num_users : 3;
+	union hal_eht_sig_user_field user_field;
+};
+
+struct hal_eht_sig_ndp_cmn_eb {
+	uint32_t spatial_reuse : 4,
+		 gi_ltf : 2,
+		 num_ltf_sym : 3,
+		 nss : 4,
+		 beamformed : 1,
+		 disregard : 2,
+		 crc : 4;
+};
+
 #define HAL_RX_MON_MAX_AGGR_SIZE	128
 
 /**
@@ -838,6 +939,8 @@ struct hal_rx_ppdu_info {
 	struct hal_rx_frm_type_info frm_type_info;
 	/* TLV aggregation metadata context */
 	struct hal_rx_tlv_aggr_info tlv_aggr;
+	/* EHT SIG user info */
+	uint32_t eht_sig_user_info;
 };
 
 static inline uint32_t