Browse Source

Merge "qcacmn: Fix DFS kernel panic"

Linux Build Service Account 7 years ago
parent
commit
367584a18d

+ 106 - 5
hal/wifi3.0/hal_api_mon.h

@@ -86,6 +86,23 @@
 #define HAL_RX_RECEPTION_TYPE_OFDMA	2
 #define HAL_RX_RECEPTION_TYPE_MU_OFDMA	3
 
+#define HAL_11B_RATE_0MCS	11
+#define HAL_11B_RATE_1MCS	5.5
+#define HAL_11B_RATE_2MCS	2
+#define HAL_11B_RATE_3MCS	1
+#define HAL_11B_RATE_4MCS	11
+#define HAL_11B_RATE_5MCS	5.5
+#define HAL_11B_RATE_6MCS	2
+
+#define HAL_11A_RATE_0MCS	48
+#define HAL_11A_RATE_1MCS	24
+#define HAL_11A_RATE_2MCS	12
+#define HAL_11A_RATE_3MCS	6
+#define HAL_11A_RATE_4MCS	54
+#define HAL_11A_RATE_5MCS	36
+#define HAL_11A_RATE_6MCS	18
+#define HAL_11A_RATE_7MCS	9
+
 enum {
 	HAL_HW_RX_DECAP_FORMAT_RAW = 0,
 	HAL_HW_RX_DECAP_FORMAT_NWIFI,
@@ -351,7 +368,7 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
 	struct rx_msdu_start *rx_msdu_start;
 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
 	uint32_t reg_value;
-
+	uint8_t nss = 0;
 	static uint32_t sgi_hw_to_cdp[] = {
 		CDP_SGI_0_8_US,
 		CDP_SGI_0_4_US,
@@ -373,12 +390,19 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
 
 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
 	switch (reg_value) {
+	case HAL_RX_PKT_TYPE_11N:
+		rs->ht_flags = 1;
+		rs->bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
+			RECEIVE_BANDWIDTH);
+		break;
 	case HAL_RX_PKT_TYPE_11AC:
 		rs->vht_flags = 1;
 		reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
-		RECEIVE_BANDWIDTH);
-		rs->vht_flag_values2 = 0x01 << reg_value;
-		rs->vht_flag_values3[0] = rs->mcs << 4;
+			RECEIVE_BANDWIDTH);
+		rs->vht_flag_values2 = reg_value;
+		nss = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
+		nss = nss + 1;
+		rs->vht_flag_values3[0] = (rs->mcs << 4) | nss ;
 		break;
 	case HAL_RX_PKT_TYPE_11AX:
 		rs->he_flags = 1;
@@ -386,7 +410,6 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
 	default:
 		break;
 	}
-
 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
 	rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0;
 	/* TODO: rs->beamformed should be set for SU beamforming also */
@@ -436,6 +459,7 @@ static inline uint32_t
 hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
 {
 	uint32_t tlv_tag, user_id, tlv_len, value;
+	uint8_t group_id = 0;
 
 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
 	user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv);
@@ -526,15 +550,92 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
 			1 : 0;
 		break;
 	}
+
+	case WIFIPHYRX_L_SIG_B_E:
+	{
+		uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
+				HAL_RX_OFFSET(PHYRX_L_SIG_B_0,
+				L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
+
+		value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
+		switch (value) {
+		case 1:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
+			break;
+		case 2:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
+			break;
+		case 3:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
+			break;
+		case 4:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
+			break;
+		case 5:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
+			break;
+		case 6:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
+			break;
+		case 7:
+			ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
+			break;
+		default:
+			break;
+		}
+	break;
+	}
+
+	case WIFIPHYRX_L_SIG_A_E:
+	{
+		uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
+				HAL_RX_OFFSET(PHYRX_L_SIG_A_0,
+				L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
+
+		value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
+		switch (value) {
+		case 8:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
+			break;
+		case 9:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
+			break;
+		case 10:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
+			break;
+		case 11:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
+			break;
+		case 12:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
+			break;
+		case 13:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
+			break;
+		case 14:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
+			break;
+		case 15:
+			ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
+			break;
+		default:
+			break;
+		}
+	break;
+	}
+
 	case WIFIPHYRX_VHT_SIG_A_E:
 	{
 		uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
 				HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0,
 				VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
+
 		value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
 				SU_MU_CODING);
 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
 			1 : 0;
+		group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
+		ppdu_info->rx_status.vht_flag_values5 = group_id;
 		break;
 	}
 	case WIFIPHYRX_HE_SIG_A_SU_E:

+ 2 - 0
hal/wifi3.0/hal_internal.h

@@ -70,6 +70,8 @@
 #include "phyrx_he_sig_b1_mu.h"
 #include "phyrx_he_sig_b2_mu.h"
 #include "phyrx_he_sig_b2_ofdma.h"
+#include "phyrx_l_sig_a.h"
+#include "phyrx_l_sig_b.h"
 #include "phyrx_vht_sig_a.h"
 #include "phyrx_ht_sig.h"
 #include "tx_msdu_extension.h"

+ 2 - 2
os_if/linux/p2p/src/wlan_cfg80211_p2p.c

@@ -284,8 +284,8 @@ static void wlan_p2p_event_callback(void *user_data,
 		goto fail;
 	}
 
-	chan = __ieee80211_get_channel(wdev->wiphy,
-			wlan_chan_to_freq(p2p_event->chan));
+	chan = ieee80211_get_channel(wdev->wiphy,
+				     wlan_chan_to_freq(p2p_event->chan));
 	if (p2p_event->roc_event == ROC_EVENT_READY_ON_CHAN) {
 		cfg80211_ready_on_channel(wdev,
 			p2p_event->cookie, chan,

+ 16 - 2
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -199,6 +199,20 @@ static void wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req,
 }
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+static inline void
+wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
+{
+	cfg80211_sched_scan_results(wiphy);
+}
+#else
+static inline void
+wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
+{
+	cfg80211_sched_scan_results(wiphy, reqid);
+}
+#endif
+
 /**
  * wlan_cfg80211_pno_callback() - pno callback function to handle
  * pno events.
@@ -231,7 +245,7 @@ static void wlan_cfg80211_pno_callback(struct wlan_objmgr_vdev *vdev,
 		cfg80211_err("pdev_ospriv is NULL");
 		return;
 	}
-	cfg80211_sched_scan_results(pdev_ospriv->wiphy);
+	wlan_cfg80211_sched_scan_results(pdev_ospriv->wiphy, 0);
 }
 
 #ifdef WLAN_POLICY_MGR_ENABLE
@@ -1499,7 +1513,7 @@ wlan_get_ieee80211_channel(struct wiphy *wiphy, int chan_no)
 		return NULL;
 	}
 
-	chan = __ieee80211_get_channel(wiphy, freq);
+	chan = ieee80211_get_channel(wiphy, freq);
 
 	if (!chan)
 		cfg80211_err("chan is NULL, chan_no: %d freq: %d",

+ 8 - 0
pld_stub/inc/pld_common.h

@@ -268,6 +268,14 @@ static inline void *pld_hif_sdio_get_virt_ramdump_mem(struct device *dev,
 static inline void pld_hif_sdio_release_ramdump_mem(unsigned long *address)
 {
 }
+static inline struct sk_buff *pld_nbuf_pre_alloc(size_t size)
+{
+	return NULL;
+}
+static inline int pld_nbuf_pre_alloc_free(struct sk_buff *skb)
+{
+	return 0;
+}
 
 #endif
 #endif

+ 50 - 3
qdf/linux/src/qdf_nbuf.c

@@ -42,6 +42,7 @@
 #include <qdf_trace.h>
 #include <net/ieee80211_radiotap.h>
 #include <qdf_module.h>
+#include <pld_common.h>
 
 #if defined(FEATURE_TSO)
 #include <net/ipv6.h>
@@ -52,6 +53,7 @@
 #endif /* FEATURE_TSO */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
+
 #define qdf_nbuf_users_inc atomic_inc
 #define qdf_nbuf_users_dec atomic_dec
 #define qdf_nbuf_users_set atomic_set
@@ -63,6 +65,19 @@
 #define qdf_nbuf_users_read refcount_read
 #endif /* KERNEL_VERSION(4, 13, 0) */
 
+#define RATE_MULTIPLIER		2
+
+#define IEEE80211_RADIOTAP_VHT_BW_20	0
+#define IEEE80211_RADIOTAP_VHT_BW_40	1
+#define IEEE80211_RADIOTAP_VHT_BW_80	2
+#define IEEE80211_RADIOTAP_VHT_BW_160	3
+
+#define RADIOTAP_VHT_BW_20	0
+#define RADIOTAP_VHT_BW_40	1
+#define RADIOTAP_VHT_BW_80	4
+#define RADIOTAP_VHT_BW_160	11
+
+
 /* Packet Counter */
 static uint32_t nbuf_tx_mgmt[QDF_NBUF_TX_PKT_STATE_MAX];
 static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX];
@@ -210,11 +225,17 @@ struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
 realloc:
 	skb = dev_alloc_skb(size);
 
+	if (skb)
+		goto skb_alloc;
+
+	skb = pld_nbuf_pre_alloc(size);
+
 	if (!skb) {
 		pr_info("ERROR:NBUF alloc failed\n");
 		return NULL;
 	}
 
+skb_alloc:
 	/* Hawkeye M2M emulation cannot handle memory addresses below 0x50000040
 	 * Though we are trying to reserve low memory upfront to prevent this,
 	 * we sometimes see SKBs allocated from low memory.
@@ -271,9 +292,15 @@ struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
 
 	skb = dev_alloc_skb(size);
 
+	if (skb)
+		goto skb_alloc;
+
+	skb = pld_nbuf_pre_alloc(size);
+
 	if (!skb)
 		return NULL;
 
+skb_alloc:
 	memset(skb->cb, 0x0, sizeof(skb->cb));
 
 	/*
@@ -315,6 +342,9 @@ EXPORT_SYMBOL(__qdf_nbuf_alloc);
 #ifdef CONFIG_MCL
 void __qdf_nbuf_free(struct sk_buff *skb)
 {
+	if (pld_nbuf_pre_alloc_free(skb))
+		return;
+
 	if (nbuf_free_cb)
 		nbuf_free_cb(skb);
 	else
@@ -323,6 +353,9 @@ void __qdf_nbuf_free(struct sk_buff *skb)
 #else
 void __qdf_nbuf_free(struct sk_buff *skb)
 {
+	if (pld_nbuf_pre_alloc_free(skb))
+		return;
+
 	dev_kfree_skb_any(skb);
 }
 #endif
@@ -2655,8 +2688,20 @@ static unsigned int qdf_nbuf_update_radiotap_vht_flags(
 		(rx_status->beamformed ?
 		 IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED : 0);
 	rtap_len += 1;
-
-	rtap_buf[rtap_len] = (rx_status->vht_flag_values2);
+	switch (rx_status->vht_flag_values2) {
+	case IEEE80211_RADIOTAP_VHT_BW_20:
+		rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20;
+		break;
+	case IEEE80211_RADIOTAP_VHT_BW_40:
+		rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40;
+		break;
+	case IEEE80211_RADIOTAP_VHT_BW_80:
+		rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80;
+		break;
+	case IEEE80211_RADIOTAP_VHT_BW_160:
+		rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160;
+		break;
+	}
 	rtap_len += 1;
 	rtap_buf[rtap_len] = (rx_status->vht_flag_values3[0]);
 	rtap_len += 1;
@@ -2791,7 +2836,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	/* IEEE80211_RADIOTAP_RATE  u8           500kb/s */
 	if (!rx_status->ht_flags && !rx_status->vht_flags) {
 		rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
-		rtap_buf[rtap_len] = rx_status->rate;
+		rtap_buf[rtap_len] = rx_status->rate * RATE_MULTIPLIER;
 	} else
 		rtap_buf[rtap_len] = 0;
 	rtap_len += 1;
@@ -2833,6 +2878,8 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 			rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_SGI;
 		if (rx_status->bw)
 			rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_40;
+		else
+			rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_20;
 		rtap_len += 1;
 
 		rtap_buf[rtap_len] = rx_status->mcs;

+ 12 - 8
umac/dfs/core/src/misc/dfs.c

@@ -924,10 +924,12 @@ int dfs_control(struct wlan_dfs *dfs,
 		dfs_print_nolhistory(dfs);
 		break;
 	case DFS_BANGRADAR:
-		dfs->dfs_bangradar = 1;
-		dfs->wlan_radar_tasksched = 1;
-		qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
-		error = 0;
+		if (!dfs->dfs_is_offload_enabled) {
+			dfs->dfs_bangradar = 1;
+			dfs->wlan_radar_tasksched = 1;
+			qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
+			error = 0;
+		}
 		break;
 	case DFS_SHOW_PRECAC_LISTS:
 		dfs_print_precaclists(dfs);
@@ -936,10 +938,12 @@ int dfs_control(struct wlan_dfs *dfs,
 		dfs_reset_precac_lists(dfs);
 		break;
 	case DFS_SECOND_SEGMENT_BANGRADAR:
-		dfs->dfs_second_segment_bangradar = 1;
-		dfs->wlan_radar_tasksched = 1;
-		qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
-		error = 0;
+		if (!dfs->dfs_is_offload_enabled) {
+			dfs->dfs_second_segment_bangradar = 1;
+			dfs->wlan_radar_tasksched = 1;
+			qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
+			error = 0;
+		}
 		break;
 	default:
 		error = -EINVAL;