Jelajahi Sumber

qcacmn: Get the correct MSDU length in the RX path

Skb under panic issue is seen when a packet comes via RX err path,
MSDU length read by SW is coming as 0 and leaving no space for skb_push
in buffer, data is moving beyond the head and causing the issue.
MSDU length is read by generic API which is architecture-independent,
hence the struct size for one architecture is different from another
architecture.

FIX is to get the MSDU length by architecture-specific API.

Change-Id: I5a6259034e5e06ae9ce7ba6b135b44f2849f2fd9
CRs-Fixed: 3235636
Devender Kumar 3 tahun lalu
induk
melakukan
e198badbe6

+ 21 - 0
hal/wifi3.0/qca5018/hal_5018.c

@@ -150,6 +150,25 @@ static uint32_t hal_rx_msdu_start_nss_get_5018(uint8_t *buf)
 	return qdf_get_hweight8(mimo_ss_bitmap);
 }
 
+/**
+ * hal_rx_msdu_start_get_len_5018(): API to get the MSDU length
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: (uint32_t)msdu length
+ */
+static uint32_t hal_rx_msdu_start_get_len_5018(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+	uint32_t msdu_len;
+
+	msdu_len = HAL_RX_MSDU_START_MSDU_LEN_GET(msdu_start);
+
+	return msdu_len;
+}
+
 /**
  * hal_rx_mon_hw_desc_get_mpdu_status_5018(): Retrieve MPDU status
  *
@@ -1842,6 +1861,8 @@ static void hal_hw_txrx_ops_attach_qca5018(struct hal_soc *hal_soc)
 	hal_soc->ops->hal_setup_link_idle_list =
 				hal_setup_link_idle_list_generic_li;
 	hal_soc->ops->hal_compute_reo_remap_ix0 = NULL;
+	hal_soc->ops->hal_rx_tlv_msdu_len_get =
+				hal_rx_msdu_start_get_len_5018;
 };
 
 struct hal_hw_srng_config hw_srng_table_5018[] = {

+ 21 - 0
hal/wifi3.0/qca6490/hal_6490.c

@@ -138,6 +138,25 @@ hal_rx_msdu_start_nss_get_6490(uint8_t *buf)
 	return qdf_get_hweight8(mimo_ss_bitmap);
 }
 
+/**
+ * hal_rx_msdu_start_get_len_6490(): API to get the MSDU length
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: (uint32_t)msdu length
+ */
+static uint32_t hal_rx_msdu_start_get_len_6490(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+	uint32_t msdu_len;
+
+	msdu_len = HAL_RX_MSDU_START_MSDU_LEN_GET(msdu_start);
+
+	return msdu_len;
+}
+
 /**
  * hal_rx_mon_hw_desc_get_mpdu_status_6490(): Retrieve MPDU status
  *
@@ -1929,6 +1948,8 @@ static void hal_hw_txrx_ops_attach_qca6490(struct hal_soc *hal_soc)
 					hal_compute_reo_remap_ix0_6490;
 	hal_soc->ops->hal_rx_tlv_l3_type_get =
 		hal_rx_tlv_l3_type_get_6490;
+	hal_soc->ops->hal_rx_tlv_msdu_len_get =
+				hal_rx_msdu_start_get_len_6490;
 };
 
 struct hal_hw_srng_config hw_srng_table_6490[] = {

+ 21 - 0
hal/wifi3.0/qca6750/hal_6750.c

@@ -138,6 +138,25 @@ hal_rx_msdu_start_nss_get_6750(uint8_t *buf)
 	return qdf_get_hweight8(mimo_ss_bitmap);
 }
 
+/**
+ * hal_rx_msdu_start_get_len_6750(): API to get the MSDU length
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: (uint32_t)msdu length
+ */
+static uint32_t hal_rx_msdu_start_get_len_6750(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+	uint32_t msdu_len;
+
+	msdu_len = HAL_RX_MSDU_START_MSDU_LEN_GET(msdu_start);
+
+	return msdu_len;
+}
+
 /**
  * hal_rx_mon_hw_desc_get_mpdu_status_6750(): Retrieve MPDU status
  *
@@ -2070,6 +2089,8 @@ static void hal_hw_txrx_ops_attach_qca6750(struct hal_soc *hal_soc)
 #endif
 	hal_soc->ops->hal_compute_reo_remap_ix0 =
 				hal_compute_reo_remap_ix0_6750;
+	hal_soc->ops->hal_rx_tlv_msdu_len_get =
+				hal_rx_msdu_start_get_len_6750;
 };
 
 struct hal_hw_srng_config hw_srng_table_6750[] = {

+ 21 - 0
hal/wifi3.0/qcn6122/hal_qcn6122.c

@@ -196,6 +196,25 @@ static uint32_t hal_rx_msdu_start_nss_get_6122(uint8_t *buf)
 	return qdf_get_hweight8(mimo_ss_bitmap);
 }
 
+/**
+ * hal_rx_msdu_start_get_len_6122(): API to get the MSDU length
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: (uint32_t)msdu length
+ */
+static uint32_t hal_rx_msdu_start_get_len_6122(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+	uint32_t msdu_len;
+
+	msdu_len = HAL_RX_MSDU_START_MSDU_LEN_GET(msdu_start);
+
+	return msdu_len;
+}
+
 /**
  * hal_rx_mon_hw_desc_get_mpdu_status_6122(): Retrieve MPDU status
  *
@@ -1901,6 +1920,8 @@ static void hal_hw_txrx_ops_attach_qcn6122(struct hal_soc *hal_soc)
 	hal_soc->ops->hal_setup_link_idle_list =
 				hal_setup_link_idle_list_generic_li;
 	hal_soc->ops->hal_compute_reo_remap_ix0 = NULL;
+	hal_soc->ops->hal_rx_tlv_msdu_len_get =
+				hal_rx_msdu_start_get_len_6122;
 };
 
 struct hal_hw_srng_config hw_srng_table_6122[] = {

+ 21 - 0
hal/wifi3.0/qcn9000/hal_9000.c

@@ -206,6 +206,25 @@ static uint32_t hal_rx_msdu_start_nss_get_9000(uint8_t *buf)
 	return qdf_get_hweight8(mimo_ss_bitmap);
 }
 
+/**
+ * hal_rx_msdu_start_get_len_9000(): API to get the MSDU length
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: (uint32_t)msdu length
+ */
+static uint32_t hal_rx_msdu_start_get_len_9000(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+	uint32_t msdu_len;
+
+	msdu_len = HAL_RX_MSDU_START_MSDU_LEN_GET(msdu_start);
+
+	return msdu_len;
+}
+
 /**
  * hal_rx_mon_hw_desc_get_mpdu_status_9000(): Retrieve MPDU status
  *
@@ -1946,6 +1965,8 @@ static void hal_hw_txrx_ops_attach_qcn9000(struct hal_soc *hal_soc)
 	hal_soc->ops->hal_setup_link_idle_list =
 				hal_setup_link_idle_list_generic_li;
 	hal_soc->ops->hal_compute_reo_remap_ix0 = NULL;
+	hal_soc->ops->hal_rx_tlv_msdu_len_get =
+				hal_rx_msdu_start_get_len_9000;
 };
 
 struct hal_hw_srng_config hw_srng_table_9000[] = {