diff mbox series

[3/4] wcn36xx: Track SNR and RSSI for each RX frame

Message ID 20220107153323.1807905-4-bryan.odonoghue@linaro.org (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series wcn36xx: Add spectrum survey reporting | expand

Commit Message

Bryan O'Donoghue Jan. 7, 2022, 3:33 p.m. UTC
The BDs for each RX frame contain both the RSSI and SNR for the received
frame. If we track and store this information it can be useful to us in
get_survey() and potentially elsewhere.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 drivers/net/wireless/ath/wcn36xx/main.c    | 12 ++++++++
 drivers/net/wireless/ath/wcn36xx/txrx.c    | 32 ++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 10 +++++++
 3 files changed, 54 insertions(+)

Comments

kernel test robot Jan. 8, 2022, 8:41 a.m. UTC | #1
Hi Bryan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on kvalo-wireless-drivers-next/master]
[also build test WARNING on kvalo-ath/ath-next next-20220107]
[cannot apply to kvalo-wireless-drivers/master v5.16-rc8]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Bryan-O-Donoghue/wcn36xx-Add-spectrum-survey-reporting/20220107-233226
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: riscv-randconfig-r042-20220107 (https://download.01.org/0day-ci/archive/20220108/202201081611.NwbnsnbW-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f3a344d2125fa37e59bae1b0874442c650a19607)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/7fa379bc4e1728cf4e30f1f9de93bea0f520e37b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bryan-O-Donoghue/wcn36xx-Add-spectrum-survey-reporting/20220107-233226
        git checkout 7fa379bc4e1728cf4e30f1f9de93bea0f520e37b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/net/wireless/ath/wcn36xx/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/net/wireless/ath/wcn36xx/main.c:22:
   In file included from include/linux/of_address.h:7:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:36:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/net/wireless/ath/wcn36xx/main.c:22:
   In file included from include/linux/of_address.h:7:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:34:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/net/wireless/ath/wcn36xx/main.c:22:
   In file included from include/linux/of_address.h:7:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> drivers/net/wireless/ath/wcn36xx/main.c:1600:3: warning: variable 'ret' is uninitialized when used here [-Wuninitialized]
                   ret -= ENOMEM;
                   ^~~
   drivers/net/wireless/ath/wcn36xx/main.c:1567:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
   8 warnings generated.


vim +/ret +1600 drivers/net/wireless/ath/wcn36xx/main.c

  1561	
  1562	static int wcn36xx_probe(struct platform_device *pdev)
  1563	{
  1564		struct ieee80211_hw *hw;
  1565		struct wcn36xx *wcn;
  1566		void *wcnss;
  1567		int ret;
  1568		const u8 *addr;
  1569		int n_channels;
  1570	
  1571		wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
  1572	
  1573		wcnss = dev_get_drvdata(pdev->dev.parent);
  1574	
  1575		hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops);
  1576		if (!hw) {
  1577			wcn36xx_err("failed to alloc hw\n");
  1578			ret = -ENOMEM;
  1579			goto out_err;
  1580		}
  1581		platform_set_drvdata(pdev, hw);
  1582		wcn = hw->priv;
  1583		wcn->hw = hw;
  1584		wcn->dev = &pdev->dev;
  1585		wcn->first_boot = true;
  1586		mutex_init(&wcn->conf_mutex);
  1587		mutex_init(&wcn->hal_mutex);
  1588		mutex_init(&wcn->scan_lock);
  1589		__skb_queue_head_init(&wcn->amsdu);
  1590	
  1591		wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL);
  1592		if (!wcn->hal_buf) {
  1593			ret = -ENOMEM;
  1594			goto out_wq;
  1595		}
  1596	
  1597		n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
  1598		wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
  1599		if (!wcn->chan_survey) {
> 1600			ret -= ENOMEM;
  1601			goto out_wq;
  1602		}
  1603	
  1604		ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
  1605		if (ret < 0) {
  1606			wcn36xx_err("failed to set DMA mask: %d\n", ret);
  1607			goto out_wq;
  1608		}
  1609	
  1610		wcn->nv_file = WLAN_NV_FILE;
  1611		ret = of_property_read_string(wcn->dev->parent->of_node, "firmware-name", &wcn->nv_file);
  1612		if (ret < 0 && ret != -EINVAL) {
  1613			wcn36xx_err("failed to read \"firmware-name\" property: %d\n", ret);
  1614			goto out_wq;
  1615		}
  1616	
  1617		wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
  1618		if (IS_ERR(wcn->smd_channel)) {
  1619			wcn36xx_err("failed to open WLAN_CTRL channel\n");
  1620			ret = PTR_ERR(wcn->smd_channel);
  1621			goto out_wq;
  1622		}
  1623	
  1624		addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
  1625		if (addr && ret != ETH_ALEN) {
  1626			wcn36xx_err("invalid local-mac-address\n");
  1627			ret = -EINVAL;
  1628			goto out_destroy_ept;
  1629		} else if (addr) {
  1630			wcn36xx_info("mac address: %pM\n", addr);
  1631			SET_IEEE80211_PERM_ADDR(wcn->hw, addr);
  1632		}
  1633	
  1634		ret = wcn36xx_platform_get_resources(wcn, pdev);
  1635		if (ret)
  1636			goto out_destroy_ept;
  1637	
  1638		wcn36xx_init_ieee80211(wcn);
  1639		ret = ieee80211_register_hw(wcn->hw);
  1640		if (ret)
  1641			goto out_unmap;
  1642	
  1643		return 0;
  1644	
  1645	out_unmap:
  1646		iounmap(wcn->ccu_base);
  1647		iounmap(wcn->dxe_base);
  1648	out_destroy_ept:
  1649		rpmsg_destroy_ept(wcn->smd_channel);
  1650	out_wq:
  1651		ieee80211_free_hw(hw);
  1652	out_err:
  1653		return ret;
  1654	}
  1655	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Bryan O'Donoghue Jan. 8, 2022, 3:48 p.m. UTC | #2
On 08/01/2022 08:41, kernel test robot wrote:
> ret -= ENOMEM;

nice catch
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index d2b99f6112f6b..d130ebb965146 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -331,6 +331,7 @@  static int wcn36xx_start(struct ieee80211_hw *hw)
 
 	INIT_LIST_HEAD(&wcn->vif_list);
 	spin_lock_init(&wcn->dxe_lock);
+	spin_lock_init(&wcn->survey_lock);
 
 	return 0;
 
@@ -394,6 +395,7 @@  static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
 	struct wcn36xx_vif *tmp;
 	struct ieee80211_supported_band *band;
 	struct ieee80211_channel *channel;
+	unsigned long flags;
 	int i, j;
 
 	for (i = 0; i < ARRAY_SIZE(wcn->hw->wiphy->bands); i++) {
@@ -415,8 +417,10 @@  static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
 		return;
 	}
 
+	spin_lock_irqsave(&wcn->survey_lock, flags);
 	wcn->band = band;
 	wcn->channel = channel;
+	spin_unlock_irqrestore(&wcn->survey_lock, flags);
 
 	list_for_each_entry(tmp, &wcn->vif_list, list) {
 		vif = wcn36xx_priv_to_vif(tmp);
@@ -1562,6 +1566,7 @@  static int wcn36xx_probe(struct platform_device *pdev)
 	void *wcnss;
 	int ret;
 	const u8 *addr;
+	int n_channels;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
 
@@ -1589,6 +1594,13 @@  static int wcn36xx_probe(struct platform_device *pdev)
 		goto out_wq;
 	}
 
+	n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
+	wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
+	if (!wcn->chan_survey) {
+		ret -= ENOMEM;
+		goto out_wq;
+	}
+
 	ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
 	if (ret < 0) {
 		wcn36xx_err("failed to set DMA mask: %d\n", ret);
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
index a3eb476c2cbc4..0425781bc2fe1 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -271,6 +271,34 @@  static void __skb_queue_purge_irq(struct sk_buff_head *list)
 		dev_kfree_skb_irq(skb);
 }
 
+static void wcn36xx_update_survey(struct wcn36xx *wcn, int rssi, int snr,
+				  int band, int freq)
+{
+	static struct ieee80211_channel *channel;
+	struct ieee80211_supported_band *sband;
+	int idx;
+	int i;
+
+	idx = 0;
+	if (band == NL80211_BAND_5GHZ)
+		idx = wcn->hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
+
+	sband = wcn->hw->wiphy->bands[band];
+	channel = sband->channels;
+
+	for (i = 0; i < sband->n_channels; i++, channel++) {
+		if (channel->center_freq == freq) {
+			idx += i;
+			break;
+		}
+	}
+
+	spin_lock(&wcn->survey_lock);
+	wcn->chan_survey[idx].rssi = rssi;
+	wcn->chan_survey[idx].snr = snr;
+	spin_unlock(&wcn->survey_lock);
+}
+
 int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
 {
 	struct ieee80211_rx_status status;
@@ -343,11 +371,15 @@  int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
 			status.band = NL80211_BAND_2GHZ;
 			status.freq = ieee80211_channel_to_frequency(hwch, status.band);
 		}
+
 	} else {
 		status.band = WCN36XX_BAND(wcn);
 		status.freq = WCN36XX_CENTER_FREQ(wcn);
 	}
 
+	 wcn36xx_update_survey(wcn, status.signal, get_snr(bd),
+			       status.band, status.freq);
+
 	if (bd->rate_id < ARRAY_SIZE(wcn36xx_rate_table)) {
 		rate = &wcn36xx_rate_table[bd->rate_id];
 		status.encoding = rate->encoding;
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index dd2570e468084..81eaa74601d0f 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -194,7 +194,14 @@  struct wcn36xx_sta {
 	enum wcn36xx_ampdu_state ampdu_state[16];
 	int non_agg_frame_ct;
 };
+
 struct wcn36xx_dxe_ch;
+
+struct wcn36xx_chan_survey {
+	s8	rssi;
+	u8	snr;
+};
+
 struct wcn36xx {
 	struct ieee80211_hw	*hw;
 	struct device		*dev;
@@ -284,6 +291,9 @@  struct wcn36xx {
 
 	struct ieee80211_supported_band *band;
 	struct ieee80211_channel *channel;
+
+	spinlock_t survey_lock;		/* protects chan_survey */
+	struct wcn36xx_chan_survey	*chan_survey;
 };
 
 static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,