Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH 21/27] qtnfmac: extend "IE set" TLV to include frame type info
From: Sergey Matyukevich @ 2017-08-30 12:07 UTC (permalink / raw)
  To: igor.mitsyanko.os; +Cc: linux-wireless, avinashp, johannes
In-Reply-To: <20170825023024.10565-22-igor.mitsyanko.os@quantenna.com>

> -		if (tlv_full_len > payload_len) {
> -			pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
> -				mac->macid, vif->vifid, tlv_type,
> -				tlv_value_len);
> +		if (tlv_full_len > payload_len)
>  			return -EINVAL;
> -		}

Why drop this sanity check ?

>  		if (tlv_type == QTN_TLV_ID_IE_SET) {
> -			sinfo.assoc_req_ies = tlv->val;
> -			sinfo.assoc_req_ies_len = tlv_value_len;
> +			const struct qlink_tlv_ie_set *ie_set;
> +			unsigned int ie_len;
> +
> +			if (payload_len < sizeof(*ie_set))
> +				return -EINVAL;
> +
> +			ie_set = (const struct qlink_tlv_ie_set *)tlv;
> +			ie_len = tlv_value_len -
> +				(sizeof(*ie_set) - sizeof(ie_set->hdr));
> +
> +			if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
> +				sinfo.assoc_req_ies = ie_set->ie_data;
> +				sinfo.assoc_req_ies_len = ie_len;
> +			}
>  		}

Does it make sense to keep QTN_TLV_ID_IE_SET here at all ?
Maybe replace it completely by qlink_tlv_ie_set with
QLINK_IE_SET_ASSOC_REQ type ? Also see the comment below
for the similar snippet in qtnf_event_handle_scan_results.

...

> -		if (tlv_full_len > payload_len) {
> -			pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
> -				vif->mac->macid, vif->vifid, tlv_type,
> -				tlv_value_len);
> +		if (tlv_full_len > payload_len)
>  			return -EINVAL;
> -		}

ditto

...

>  		if (tlv_type == QTN_TLV_ID_IE_SET) {
> -			ies = tlv->val;
> -			ies_len = tlv_value_len;
> +			const struct qlink_tlv_ie_set *ie_set;
> +			unsigned int ie_len;
> +
> +			if (payload_len < sizeof(*ie_set))
> +				return -EINVAL;
> +
> +			ie_set = (const struct qlink_tlv_ie_set *)tlv;
> +			ie_len = tlv_value_len -
> +				(sizeof(*ie_set) - sizeof(ie_set->hdr));
> +
> +			if (ie_len) {
> +				ies = ie_set->ie_data;
> +				ies_len = ie_len;
> +			}
>  		}
>  	}

Two points here. First, it looks like there is a problem here inherited
from the existing implementation. We go through payload, but in fact we
pass to cfg80211_inform_bss only the last QTN_TLV_ID_IE_SET element.
Second, it looks like QTN_TLV_ID_IE_SET here should be treated in
the same way as in qtnf_event_handle_sta_assoc, to avoid confusion.
In other words, either we use only QTN_TLV_ID_IE_SET in both cases,
or switch to specific qlink_tlv_ie_set elements.

Thoughts ? Comments ?

Regards,
Sergey

^ permalink raw reply

* [PATCH] rsi: add driver and firmware version info
From: Amitkumar Karwar @ 2017-08-30 12:02 UTC (permalink / raw)
  To: Kalle Valo
  Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi,
	Pavani Muthyala

From: Pavani Muthyala <pavani.muthyala@redpinesignals.com>

We will dump information about driver and firmware versions,
firmware file name and operating mode during initialization.

Signed-off-by: Pavani Muthyala <pavani.muthyala@redpinesignals.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_debugfs.c | 20 +++++++-------------
 drivers/net/wireless/rsi/rsi_91x_hal.c     | 13 +++++++++++++
 drivers/net/wireless/rsi/rsi_91x_main.c    | 29 +++++++++++++++++++++++++++++
 drivers/net/wireless/rsi/rsi_hal.h         |  3 +++
 drivers/net/wireless/rsi/rsi_main.h        | 17 +++++++++++++----
 5 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
index e98eb55..a1b5e28 100644
--- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
+++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
@@ -83,19 +83,13 @@ static int rsi_version_read(struct seq_file *seq, void *data)
 {
 	struct rsi_common *common = seq->private;
 
-	common->driver_ver.major = 0;
-	common->driver_ver.minor = 1;
-	common->driver_ver.release_num = 0;
-	common->driver_ver.patch_num = 0;
-	seq_printf(seq, "Driver : %x.%d.%d.%d\nLMAC   : %d.%d.%d.%d\n",
-		   common->driver_ver.major,
-		   common->driver_ver.minor,
-		   common->driver_ver.release_num,
-		   common->driver_ver.patch_num,
-		   common->fw_ver.major,
-		   common->fw_ver.minor,
-		   common->fw_ver.release_num,
-		   common->fw_ver.patch_num);
+	seq_printf(seq, "Driver : %s\nLMAC   : %d.%d.%d.%d\n",
+		   common->driver_ver,
+		   common->lmac_ver.major,
+		   common->lmac_ver.minor,
+		   common->lmac_ver.release_num,
+		   common->lmac_ver.patch_num);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 7e8e5d4..71b02ad 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -769,6 +769,7 @@ static int auto_fw_upgrade(struct rsi_hw *adapter, u8 *flash_content,
 
 static int rsi_load_firmware(struct rsi_hw *adapter)
 {
+	struct rsi_common *common = adapter->priv;
 	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
 	const struct firmware *fw_entry = NULL;
 	u32 regout_val = 0, content_size;
@@ -844,6 +845,18 @@ static int rsi_load_firmware(struct rsi_hw *adapter)
 	content_size = fw_entry->size;
 	rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", content_size);
 
+	/* Get the firmware version */
+	common->lmac_ver.ver.info.fw_ver[0] =
+		flash_content[LMAC_VER_OFFSET] & 0xFF;
+	common->lmac_ver.ver.info.fw_ver[1] =
+		flash_content[LMAC_VER_OFFSET + 1] & 0xFF;
+	common->lmac_ver.major = flash_content[LMAC_VER_OFFSET + 2] & 0xFF;
+	common->lmac_ver.release_num =
+		flash_content[LMAC_VER_OFFSET + 3] & 0xFF;
+	common->lmac_ver.minor = flash_content[LMAC_VER_OFFSET + 4] & 0xFF;
+	common->lmac_ver.patch_num = 0;
+	rsi_print_version(common);
+
 	status = bl_write_header(adapter, flash_content, content_size);
 	if (status) {
 		rsi_dbg(ERR_ZONE,
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index b57bfdc..ed988b3 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -20,6 +20,7 @@
 #include <linux/firmware.h>
 #include "rsi_mgmt.h"
 #include "rsi_common.h"
+#include "rsi_hal.h"
 
 u32 rsi_zone_enabled = /* INFO_ZONE |
 			INIT_ZONE |
@@ -56,6 +57,34 @@ void rsi_dbg(u32 zone, const char *fmt, ...)
 }
 EXPORT_SYMBOL_GPL(rsi_dbg);
 
+static char *opmode_str(int oper_mode)
+{
+	switch (oper_mode) {
+	case RSI_DEV_OPMODE_WIFI_ALONE:
+		return "Wi-Fi alone";
+	}
+
+	return "Unknown";
+}
+
+void rsi_print_version(struct rsi_common *common)
+{
+	memcpy(common->driver_ver, DRV_VER, ARRAY_SIZE(DRV_VER));
+	common->driver_ver[ARRAY_SIZE(DRV_VER)] = '\0';
+
+	rsi_dbg(ERR_ZONE, "================================================\n");
+	rsi_dbg(ERR_ZONE, "================ RSI Version Info ==============\n");
+	rsi_dbg(ERR_ZONE, "================================================\n");
+	rsi_dbg(ERR_ZONE, "FW Version\t: %d.%d.%d\n",
+		common->lmac_ver.major, common->lmac_ver.minor,
+		common->lmac_ver.release_num);
+	rsi_dbg(ERR_ZONE, "Driver Version\t: %s", common->driver_ver);
+	rsi_dbg(ERR_ZONE, "Operating mode\t: %d [%s]",
+		common->oper_mode, opmode_str(common->oper_mode));
+	rsi_dbg(ERR_ZONE, "Firmware file\t: %s", common->priv->fw_file_name);
+	rsi_dbg(ERR_ZONE, "================================================\n");
+}
+
 /**
  * rsi_prepare_skb() - This function prepares the skb.
  * @common: Pointer to the driver private structure.
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index ad0d653..a09d36b 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -101,6 +101,9 @@
 
 #define BBP_INFO_40MHZ 0x6
 
+#define FW_FLASH_OFFSET			0x820
+#define LMAC_VER_OFFSET			(FW_FLASH_OFFSET + 0x200)
+
 struct bl_header {
 	__le32 flags;
 	__le32 image_no;
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 34089ab..53343a3f 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -32,6 +32,8 @@ struct rsi_hw;
 
 #include "rsi_ps.h"
 
+#define DRV_VER				"RS911X.NB0.NL.GNU.LNX.1.0"
+
 #define ERR_ZONE                        BIT(0)  /* For Error Msgs             */
 #define INFO_ZONE                       BIT(1)  /* For General Status Msgs    */
 #define INIT_ZONE                       BIT(2)  /* For Driver Init Seq Msgs   */
@@ -113,8 +115,13 @@ extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
 struct version_info {
 	u16 major;
 	u16 minor;
-	u16 release_num;
-	u16 patch_num;
+	u8 release_num;
+	u8 patch_num;
+	union {
+		struct {
+			u8 fw_ver[8];
+		} info;
+	} ver;
 } __packed;
 
 struct skb_info {
@@ -199,8 +206,8 @@ struct rsi_common {
 	struct vif_priv vif_info[RSI_MAX_VIFS];
 
 	bool mgmt_q_block;
-	struct version_info driver_ver;
-	struct version_info fw_ver;
+	char driver_ver[32];
+	struct version_info lmac_ver;
 
 	struct rsi_thread tx_thread;
 	struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 2];
@@ -334,6 +341,8 @@ struct rsi_hw {
 	int (*determine_event_timeout)(struct rsi_hw *adapter);
 };
 
+void rsi_print_version(struct rsi_common *common);
+
 struct rsi_host_intf_ops {
 	int (*read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
 	int (*write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH] Documentation: dt-binding: net: wireless: add bcm43430-fmac
From: Antony Antony @ 2017-08-30 12:02 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Antony Antony, Kalle Valo, Rob Herring, Mark Rutland,
	Icenowy Zheng, devicetree, Hans de Goede, linux-wireless,
	Maxime Ripard
In-Reply-To: <CAGb2v66=JvS9wHkUNBwd+vHwx4NAQsaWyhx1OyEokSZizo+7-g@mail.gmail.com>

hi,

On Wed, Aug 30, 2017 at 10:28:20AM +0800, Chen-Yu Tsai wrote:
> On Wed, Aug 30, 2017 at 5:43 AM, Antony Antony <antony@phenome.org> wrote:

> > a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
> > +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
> > @@ -6,7 +6,9 @@ connects the device to the system.
> >
> >  Required properties:
> >
> > - - compatible : Should be "brcm,bcm4329-fmac".
> > + - compatible : should be one of the following:
> > +       * "brcm,bcm4329-fmac"
> > +       * "brcm,bcm43430-fmac"
> 
> You updated the bindings, but not the driver. So it's not actually
> going to work. More specifically, OOB interrupts won't work.
>

understood, ignore this patch for now. Thanks Chen-Yu.

> IIRC, The compatible string for this particular case, as it was
> originally proposed, only serves as a placeholder for the driver
> to check against. None of the instances in sunxi device trees
> match the actual chip model. Actual model matching is done
> through SDIO, as you've already seen.

yes it seems SDIO driveer code is smarter, once it initialize 
brcm,bcm4329-fmac it ignore the DT info and read the chip details to locate 
firmware file.

I also noticed other boards using bcm4329-fmac in similar situations.
https://patchwork.kernel.org/patch/9739181/

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts?h=v4.13-rc7

I will resend "NanoPi NEO Plus2" dts with "brcm,bcm4329-fmac" and see where 
it goes. 

regards,
-antony

^ permalink raw reply

* Re: [PATCH resend] brcmfmac: p2p and normal ap access are not always possible at the same time
From: Hans de Goede @ 2017-08-30 10:30 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Franky Lin, Hante Meuleman, Kalle Valo, linux-wireless,
	brcm80211-dev-list.pdl
In-Reply-To: <d59fb4f8-4ba3-bd75-8de4-9b6b04e4dbe0@redhat.com>

Hi,

On 30-08-17 12:24, Hans de Goede wrote:
> Hi Arend,
> 
> Sorry I was a bit slow to respond to this.
> 
> On 04-08-17 14:35, Arend van Spriel wrote:
>> On 5/26/2017 12:57 PM, Hans de Goede wrote:
>>> The firmware responding with -EBUSY when trying to add an extra virtual-if
>>> is a normal thing, do not print an error for this.
>>
>> Hi Hans,
>>
>> First of all, sorry! This one is long overdue (thanks for the reminder, Kalle). Not sure what the claim is here. I have to check the firmware to see what could make this fail. Thing is that wpa_supplicant will try to create the interface upon startup and it is really required for P2P operations. Now people not using that will probably not care about the failure, but I would like to find out why it is failing. wpa_supplicant will not do a retry upon -EBUSY.
>>
>> With which firmware (target string and version) are you seeing this so I know where to dive in.
> 
> [root@localhost ~]# dmesg | grep brcm
> [   11.252078] brcmutil: loading out-of-tree module taints kernel.
> [   11.252159] brcmutil: module verification failed: signature and/or required key missing - tainting kernel
> [   11.484195] brcmfmac: brcmf_sdio_probe: Loading firmware brcm/brcmfmac43430a0-sdio.bin for chip 0000a9a6 rev 00000000
> [   11.484290] usbcore: registered new interface driver brcmfmac
> [   11.616053] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Jun  6 2014 14:50:39 version 7.10.226.49 (r) FWID 01-8962686a
> [   14.782464] brcmfmac: brcmf_p2p_create_p2pdev: set p2p_disc error
> [   14.782488] brcmfmac: brcmf_cfg80211_add_iface: add iface p2p-dev-wlan0 type 10 failed: err=-16
> [   34.300531] brcmfmac: brcmf_p2p_create_p2pdev: set p2p_disc error
> [   34.300549] brcmfmac: brcmf_cfg80211_add_iface: add iface p2p-dev-wlan0 type 10 failed: err=-16
> 
> [root@localhost ~]# strings /lib/firmware/brcm/brcmfmac43430a0-sdio.bin | tail -n 1
> 43430a0-roml/sdio-g-pool-p2p-pno-pktfilter-keepalive-aoe-mchan-proptxstatus-lpc-wl11u-rcc-fmc-wepso-ccx-okc-fbt-noccxaka-txpwr-ampduhostreorder-clm_43xx_lg Version: 7.10.226.49 CRC: bf92cb0b Date: Fri 2014-06-06 14:55:15 KST FWID 01-8962686a

Since that firmware is quite old, I've tried again with a newer version:

[   11.219863] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Jul  1 2016 18:02:40 version 7.10.1 (A0 Station/P2P feature) FWID 01-bae8afee

[root@localhost ~]# strings /lib/firmware/brcm/brcmfmac43430a0-sdio.bin | tail -n 1
43430a0-roml/sdio-g-pool-p2p-pno-pktfilter-keepalive-aoe-mchan-proptxstatus-lpc-wl11u-rcc-fmc-wepso-ccx-okc-fbt-noccxaka-txpwr-ampduhostreorder-clm_43xx_lg-ndoe Version: 7.10.1.244 CRC: 73c82137 Date: Fri 2016-07-01 18:03:15 KST Ucode Ver: 940.1020 FWID: 01-bae8afee

Which still results in the same errors.

Note this is with the a0 revision of the 43430 for which a firmware file is
still missing from linux-firmware. If you happen to be able to add a file
to linux-firmware while looking into this, that would be great.

Regards,

Hans

^ permalink raw reply

* Re: [PATCH resend] brcmfmac: p2p and normal ap access are not always possible at the same time
From: Hans de Goede @ 2017-08-30 10:24 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Franky Lin, Hante Meuleman, Kalle Valo, linux-wireless,
	brcm80211-dev-list.pdl
In-Reply-To: <59846A11.80400@broadcom.com>

Hi Arend,

Sorry I was a bit slow to respond to this.

On 04-08-17 14:35, Arend van Spriel wrote:
> On 5/26/2017 12:57 PM, Hans de Goede wrote:
>> The firmware responding with -EBUSY when trying to add an extra virtual-if
>> is a normal thing, do not print an error for this.
> 
> Hi Hans,
> 
> First of all, sorry! This one is long overdue (thanks for the reminder, Kalle). Not sure what the claim is here. I have to check the firmware to see what could make this fail. Thing is that wpa_supplicant will try to create the interface upon startup and it is really required for P2P operations. Now people not using that will probably not care about the failure, but I would like to find out why it is failing. wpa_supplicant will not do a retry upon -EBUSY.
> 
> With which firmware (target string and version) are you seeing this so I know where to dive in.

[root@localhost ~]# dmesg | grep brcm
[   11.252078] brcmutil: loading out-of-tree module taints kernel.
[   11.252159] brcmutil: module verification failed: signature and/or required key missing - tainting kernel
[   11.484195] brcmfmac: brcmf_sdio_probe: Loading firmware brcm/brcmfmac43430a0-sdio.bin for chip 0000a9a6 rev 00000000
[   11.484290] usbcore: registered new interface driver brcmfmac
[   11.616053] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Jun  6 2014 14:50:39 version 7.10.226.49 (r) FWID 01-8962686a
[   14.782464] brcmfmac: brcmf_p2p_create_p2pdev: set p2p_disc error
[   14.782488] brcmfmac: brcmf_cfg80211_add_iface: add iface p2p-dev-wlan0 type 10 failed: err=-16
[   34.300531] brcmfmac: brcmf_p2p_create_p2pdev: set p2p_disc error
[   34.300549] brcmfmac: brcmf_cfg80211_add_iface: add iface p2p-dev-wlan0 type 10 failed: err=-16

[root@localhost ~]# strings /lib/firmware/brcm/brcmfmac43430a0-sdio.bin | tail -n 1
43430a0-roml/sdio-g-pool-p2p-pno-pktfilter-keepalive-aoe-mchan-proptxstatus-lpc-wl11u-rcc-fmc-wepso-ccx-okc-fbt-noccxaka-txpwr-ampduhostreorder-clm_43xx_lg Version: 7.10.226.49 CRC: bf92cb0b Date: Fri 2014-06-06 14:55:15 KST FWID 01-8962686a

Regards,

Hans

^ permalink raw reply

* [PATCH 8/8] rsi: miscellaneous changes for p2p mode
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

Add P2P_GO condition as well when handling BEACON_ENABLE
from mac80211. Also passing 'vif' for auto rate request.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 15 +++++++++------
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |  6 +++---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 79426a2..b1f5dbb 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -756,7 +756,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
-	    (vif->type == NL80211_IFTYPE_AP)) {
+	    ((vif->type == NL80211_IFTYPE_AP) ||
+	     (vif->type == NL80211_IFTYPE_P2P_GO))) {
 		if (bss->enable_beacon) {
 			rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n");
 			common->beacon_enabled = 1;
@@ -1147,9 +1148,9 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
  */
 static void rsi_perform_cqm(struct rsi_common *common,
 			    u8 *bssid,
-			    s8 rssi)
+			    s8 rssi,
+			    struct ieee80211_vif *vif)
 {
-	struct rsi_hw *adapter = common->priv;
 	s8 last_event = common->cqm_info.last_cqm_event_rssi;
 	int thold = common->cqm_info.rssi_thold;
 	u32 hyst = common->cqm_info.rssi_hyst;
@@ -1165,7 +1166,7 @@ static void rsi_perform_cqm(struct rsi_common *common,
 
 	common->cqm_info.last_cqm_event_rssi = rssi;
 	rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
-	ieee80211_cqm_rssi_notify(adapter->vifs[0], event, rssi, GFP_KERNEL);
+	ieee80211_cqm_rssi_notify(vif, event, rssi, GFP_KERNEL);
 
 	return;
 }
@@ -1228,15 +1229,17 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
 		vif = adapter->vifs[i];
 		if (!vif)
 			continue;
-		if (vif->type == NL80211_IFTYPE_STATION)
+		if (vif->type == NL80211_IFTYPE_STATION) {
 			bss = &vif->bss_conf;
+			break;
+		}
 	}
 	if (!bss)
 		return;
 	/* CQM only for connected AP beacons, the RSSI is a weighted avg */
 	if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) {
 		if (ieee80211_is_beacon(hdr->frame_control))
-			rsi_perform_cqm(common, hdr->addr2, rxs->signal);
+			rsi_perform_cqm(common, hdr->addr2, rxs->signal, vif);
 	}
 
 	return;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 383cd43..4b94190 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1160,9 +1160,9 @@ static bool rsi_map_rates(u16 rate, int *offset)
  */
 static int rsi_send_auto_rate_request(struct rsi_common *common,
 				      struct ieee80211_sta *sta,
-				      u16 sta_id)
+				      u16 sta_id,
+				      struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif = common->priv->vifs[0];
 	struct sk_buff *skb;
 	struct rsi_auto_rate *auto_rate;
 	int ii = 0, jj = 0, kk = 0;
@@ -1332,7 +1332,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
 					      aid, sta_id,
 					      vif);
 		if (common->min_rate == 0xffff)
-			rsi_send_auto_rate_request(common, sta, sta_id);
+			rsi_send_auto_rate_request(common, sta, sta_id, vif);
 		if (opmode == RSI_OPMODE_STA) {
 			if (!rsi_send_block_unblock_frame(common, false))
 				common->hw_data_qs_blocked = false;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 7/8] rsi: aggregation changes for p2p mode
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

P2P Go condition is added wherever AP mode is there
in aggregation path.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 09ad909..79426a2 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1005,7 +1005,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
 	if (ssn != NULL)
 		seq_no = *ssn;
 
-	if (vif->type == NL80211_IFTYPE_AP) {
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 		rsta = rsi_find_sta(common, sta->addr);
 		if (!rsta) {
 			rsi_dbg(ERR_ZONE, "No station mapped\n");
@@ -1039,9 +1040,11 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
 		break;
 
 	case IEEE80211_AMPDU_TX_START:
-		if (vif->type == NL80211_IFTYPE_STATION)
+		if ((vif->type == NL80211_IFTYPE_STATION) ||
+		    (vif->type == NL80211_IFTYPE_P2P_CLIENT))
 			common->vif_info[ii].seq_start = seq_no;
-		else if (vif->type == NL80211_IFTYPE_AP)
+		else if ((vif->type == NL80211_IFTYPE_AP) ||
+			 (vif->type == NL80211_IFTYPE_P2P_GO))
 			rsta->seq_start[tid] = seq_no;
 		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		status = 0;
@@ -1061,9 +1064,11 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
 		break;
 
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
-		if (vif->type == NL80211_IFTYPE_STATION)
+		if ((vif->type == NL80211_IFTYPE_STATION) ||
+		    (vif->type == NL80211_IFTYPE_P2P_CLIENT))
 			seq_start = common->vif_info[ii].seq_start;
-		else if (vif->type == NL80211_IFTYPE_AP)
+		else if ((vif->type == NL80211_IFTYPE_AP) ||
+			 (vif->type == NL80211_IFTYPE_P2P_GO))
 			seq_start = rsta->seq_start[tid];
 		status = rsi_send_aggregation_params_frame(common,
 							   tid,
-- 
2.7.4

^ permalink raw reply related

* [PATCH 6/8] rsi: disallow power save config when AP vap running
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

When AP or P2P GO VAP is running, power save configuration should
be disallowed. To check interface type in power save configuration
'vif' parameters is passed.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 33 ++++++++++++++++++++---------
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |  5 +++--
 drivers/net/wireless/rsi/rsi_91x_ps.c       | 15 +++++++------
 drivers/net/wireless/rsi/rsi_mgmt.h         |  2 ++
 drivers/net/wireless/rsi/rsi_ps.h           |  7 +++---
 5 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index b1550bc..09ad909 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -592,7 +592,6 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
 {
 	struct rsi_hw *adapter = hw->priv;
 	struct rsi_common *common = adapter->priv;
-	struct ieee80211_vif *vif = adapter->vifs[0];
 	struct ieee80211_conf *conf = &hw->conf;
 	int status = -EOPNOTSUPP;
 
@@ -608,16 +607,30 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
 	}
 
 	/* Power save parameters */
-	if ((changed & IEEE80211_CONF_CHANGE_PS) &&
-	    (vif->type == NL80211_IFTYPE_STATION)) {
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		struct ieee80211_vif *vif;
 		unsigned long flags;
+		int i, set_ps = 1;
 
-		spin_lock_irqsave(&adapter->ps_lock, flags);
-		if (conf->flags & IEEE80211_CONF_PS)
-			rsi_enable_ps(adapter);
-		else
-			rsi_disable_ps(adapter);
-		spin_unlock_irqrestore(&adapter->ps_lock, flags);
+		for (i = 0; i < RSI_MAX_VIFS; i++) {
+			vif = adapter->vifs[i];
+			if (!vif)
+				continue;
+			/* Don't go to power save if AP vap exists */
+			if ((vif->type == NL80211_IFTYPE_AP) ||
+			    (vif->type == NL80211_IFTYPE_P2P_GO)) {
+				set_ps = 0;
+				break;
+			}
+		}
+		if (set_ps) {
+			spin_lock_irqsave(&adapter->ps_lock, flags);
+			if (conf->flags & IEEE80211_CONF_PS)
+				rsi_enable_ps(adapter, vif);
+			else
+				rsi_disable_ps(adapter, vif);
+			spin_unlock_irqrestore(&adapter->ps_lock, flags);
+		}
 	}
 
 	/* RTS threshold */
@@ -726,7 +739,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 	if (bss->assoc) {
 		if (common->uapsd_bitmap) {
 			rsi_dbg(INFO_ZONE, "Configuring UAPSD\n");
-			rsi_conf_uapsd(adapter);
+			rsi_conf_uapsd(adapter, vif);
 		}
 	} else {
 		common->uapsd_bitmap = 0;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 4e50cfd..383cd43 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1474,10 +1474,11 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
 	return rsi_send_internal_mgmt_frame(common, skb);
 }
 
-int rsi_send_ps_request(struct rsi_hw *adapter, bool enable)
+int rsi_send_ps_request(struct rsi_hw *adapter, bool enable,
+			struct ieee80211_vif *vif)
 {
 	struct rsi_common *common = adapter->priv;
-	struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
+	struct ieee80211_bss_conf *bss = &vif->bss_conf;
 	struct rsi_request_ps *ps;
 	struct rsi_ps_info *ps_info;
 	struct sk_buff *skb;
diff --git a/drivers/net/wireless/rsi/rsi_91x_ps.c b/drivers/net/wireless/rsi/rsi_91x_ps.c
index 48c79f0..523f532 100644
--- a/drivers/net/wireless/rsi/rsi_91x_ps.c
+++ b/drivers/net/wireless/rsi/rsi_91x_ps.c
@@ -67,7 +67,7 @@ void rsi_default_ps_params(struct rsi_hw *adapter)
 	ps_info->deep_sleep_wakeup_period = RSI_DEF_DS_WAKEUP_PERIOD;
 }
 
-void rsi_enable_ps(struct rsi_hw *adapter)
+void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 {
 	if (adapter->ps_state != PS_NONE) {
 		rsi_dbg(ERR_ZONE,
@@ -76,7 +76,7 @@ void rsi_enable_ps(struct rsi_hw *adapter)
 		return;
 	}
 
-	if (rsi_send_ps_request(adapter, true)) {
+	if (rsi_send_ps_request(adapter, true, vif)) {
 		rsi_dbg(ERR_ZONE,
 			"%s: Failed to send PS request to device\n",
 			__func__);
@@ -86,7 +86,8 @@ void rsi_enable_ps(struct rsi_hw *adapter)
 	rsi_modify_ps_state(adapter, PS_ENABLE_REQ_SENT);
 }
 
-void rsi_disable_ps(struct rsi_hw *adapter)
+/* This function is used to disable power save */
+void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 {
 	if (adapter->ps_state != PS_ENABLED) {
 		rsi_dbg(ERR_ZONE,
@@ -95,7 +96,7 @@ void rsi_disable_ps(struct rsi_hw *adapter)
 		return;
 	}
 
-	if (rsi_send_ps_request(adapter, false)) {
+	if (rsi_send_ps_request(adapter, false, vif)) {
 		rsi_dbg(ERR_ZONE,
 			"%s: Failed to send PS request to device\n",
 			__func__);
@@ -105,16 +106,16 @@ void rsi_disable_ps(struct rsi_hw *adapter)
 	rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
 }
 
-void rsi_conf_uapsd(struct rsi_hw *adapter)
+void rsi_conf_uapsd(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 {
 	int ret;
 
 	if (adapter->ps_state != PS_ENABLED)
 		return;
 
-	ret = rsi_send_ps_request(adapter, false);
+	ret = rsi_send_ps_request(adapter, false, vif);
 	if (!ret)
-		ret = rsi_send_ps_request(adapter, true);
+		ret = rsi_send_ps_request(adapter, true, vif);
 	if (ret)
 		rsi_dbg(ERR_ZONE,
 			"%s: Failed to send PS request to device\n",
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 331d64b..b9d0802 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -641,4 +641,6 @@ int rsi_band_check(struct rsi_common *common, struct ieee80211_channel *chan);
 int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
 int rsi_send_radio_params_update(struct rsi_common *common);
 int rsi_set_antenna(struct rsi_common *common, u8 antenna);
+int rsi_send_ps_request(struct rsi_hw *adapter, bool enable,
+			struct ieee80211_vif *vif);
 #endif
diff --git a/drivers/net/wireless/rsi/rsi_ps.h b/drivers/net/wireless/rsi/rsi_ps.h
index d847587..98ff6a4 100644
--- a/drivers/net/wireless/rsi/rsi_ps.h
+++ b/drivers/net/wireless/rsi/rsi_ps.h
@@ -55,10 +55,9 @@ struct rsi_ps_info {
 } __packed;
 
 char *str_psstate(enum ps_state state);
-void rsi_enable_ps(struct rsi_hw *adapter);
-void rsi_disable_ps(struct rsi_hw *adapter);
+void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif);
+void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif);
 int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg);
 void rsi_default_ps_params(struct rsi_hw *hw);
-int rsi_send_ps_request(struct rsi_hw *adapter, bool enable);
-void rsi_conf_uapsd(struct rsi_hw *adapter);
+void rsi_conf_uapsd(struct rsi_hw *adapter, struct ieee80211_vif *vif);
 #endif
-- 
2.7.4

^ permalink raw reply related

* [PATCH 5/8] rsi: tx and rx path enhancements for p2p mode
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

Data descriptor is updated to include vap_id. TX command frame
key config also updated to include vap_id.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_core.c     |  9 +++++++--
 drivers/net/wireless/rsi/rsi_91x_hal.c      | 26 ++++++++++++++++++--------
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 23 +++++++++++++++++++----
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |  4 ++--
 drivers/net/wireless/rsi/rsi_mgmt.h         |  3 ++-
 5 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index 432d6eb..bc18a19 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -95,6 +95,8 @@ static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
 	s16 txop = common->tx_qinfo[q_num].txop * 32;
 	__le16 r_txop;
 	struct ieee80211_rate rate;
+	struct ieee80211_hdr *wh;
+	struct ieee80211_vif *vif;
 
 	rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */
 	if (q_num == VI_Q)
@@ -106,8 +108,10 @@ static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
 		return 0;
 
 	do {
+		wh = (struct ieee80211_hdr *)skb->data;
+		vif = rsi_get_vif(adapter, wh->addr2);
 		r_txop = ieee80211_generic_frame_duration(adapter->hw,
-							  adapter->vifs[0],
+							  vif,
 							  common->band,
 							  skb->len, &rate);
 		txop -= le16_to_cpu(r_txop);
@@ -403,7 +407,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
 		q_num = skb->priority;
 		tx_params->tid = tid;
 
-		if ((vif->type == NL80211_IFTYPE_AP) &&
+		if (((vif->type == NL80211_IFTYPE_AP) ||
+		     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
 		    (!is_broadcast_ether_addr(wh->addr1)) &&
 		    (!is_multicast_ether_addr(wh->addr1))) {
 			rsta = rsi_find_sta(common, wh->addr1);
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index d0b119e..7e8e5d4 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -157,7 +157,8 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 	u16 seq_num;
 
 	info = IEEE80211_SKB_CB(skb);
-	bss = &info->control.vif->bss_conf;
+	vif = info->control.vif;
+	bss = &vif->bss_conf;
 	tx_params = (struct skb_info *)info->driver_data;
 
 	header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
@@ -181,7 +182,6 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 	xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
 	wh = (struct ieee80211_hdr *)&skb->data[header_size];
 	seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl));
-	vif = adapter->vifs[0];
 
 	data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;
 
@@ -190,7 +190,8 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 		data_desc->mac_flags |= cpu_to_le16(RSI_QOS_ENABLE);
 	}
 
-	if ((vif->type == NL80211_IFTYPE_STATION) &&
+	if (((vif->type == NL80211_IFTYPE_STATION) ||
+	     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
 	    (adapter->ps_state == PS_ENABLED))
 		wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE);
 
@@ -246,17 +247,23 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 		data_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);
 		data_desc->sta_id = vap_id;
 
-		if (vif->type == NL80211_IFTYPE_AP) {
+		if ((vif->type == NL80211_IFTYPE_AP) ||
+		    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 			if (common->band == NL80211_BAND_5GHZ)
 				data_desc->rate_info = cpu_to_le16(RSI_RATE_6);
 			else
 				data_desc->rate_info = cpu_to_le16(RSI_RATE_1);
 		}
 	}
-	if ((vif->type == NL80211_IFTYPE_AP) &&
+	if (((vif->type == NL80211_IFTYPE_AP) ||
+	     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
 	    (ieee80211_has_moredata(wh->frame_control)))
 		data_desc->frame_info |= cpu_to_le16(MORE_DATA_PRESENT);
 
+	data_desc->rate_info |=
+		cpu_to_le16((tx_params->vap_id << RSI_DESC_VAP_ID_OFST) &
+			    RSI_DESC_VAP_ID_MASK);
+
 	return 0;
 }
 
@@ -264,7 +271,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
 {
 	struct rsi_hw *adapter = common->priv;
-	struct ieee80211_vif *vif = adapter->vifs[0];
+	struct ieee80211_vif *vif;
 	struct ieee80211_tx_info *info;
 	struct ieee80211_bss_conf *bss;
 	int status = -EINVAL;
@@ -277,9 +284,12 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
 	info = IEEE80211_SKB_CB(skb);
 	if (!info->control.vif)
 		goto err;
-	bss = &info->control.vif->bss_conf;
+	vif = info->control.vif;
+	bss = &vif->bss_conf;
 
-	if ((vif->type == NL80211_IFTYPE_STATION) && (!bss->assoc))
+	if (((vif->type == NL80211_IFTYPE_STATION) ||
+	     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
+	    (!bss->assoc))
 		goto err;
 
 	status = rsi_prepare_data_desc(common, skb);
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index ce2f911..b1550bc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -879,7 +879,8 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
 						  RSI_PAIRWISE_KEY,
 						  key->keyidx,
 						  key->cipher,
-						  sta_id);
+						  sta_id,
+						  vif);
 			if (status)
 				return status;
 		}
@@ -891,7 +892,8 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
 				key_type,
 				key->keyidx,
 				key->cipher,
-				sta_id);
+				sta_id,
+				vif);
 }
 
 /**
@@ -1165,7 +1167,9 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
 			       struct rsi_common *common,
 			       struct ieee80211_rx_status *rxs)
 {
-	struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf;
+	struct rsi_hw *adapter = common->priv;
+	struct ieee80211_vif *vif;
+	struct ieee80211_bss_conf *bss = NULL;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct skb_info *rx_params = (struct skb_info *)info->driver_data;
 	struct ieee80211_hdr *hdr;
@@ -1173,6 +1177,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
 	u8 hdrlen = 0;
 	u8 channel = rx_params->channel;
 	s32 freq;
+	int i;
 
 	hdr = ((struct ieee80211_hdr *)(skb->data));
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1201,6 +1206,15 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
 		rxs->flag |= RX_FLAG_IV_STRIPPED;
 	}
 
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		vif = adapter->vifs[i];
+		if (!vif)
+			continue;
+		if (vif->type == NL80211_IFTYPE_STATION)
+			bss = &vif->bss_conf;
+	}
+	if (!bss)
+		return;
 	/* CQM only for connected AP beacons, the RSSI is a weighted avg */
 	if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) {
 		if (ieee80211_is_beacon(hdr->frame_control))
@@ -1363,7 +1377,8 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 							 RSI_PAIRWISE_KEY,
 							 key->keyidx,
 							 key->cipher,
-							 sta_idx);
+							 sta_idx,
+							 vif);
 			}
 
 			common->num_stations++;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 428369b..4e50cfd 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -716,9 +716,9 @@ int rsi_hal_load_key(struct rsi_common *common,
 		     u8 key_type,
 		     u8 key_id,
 		     u32 cipher,
-		     s16 sta_id)
+		     s16 sta_id,
+		     struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif = common->priv->vifs[0];
 	struct sk_buff *skb = NULL;
 	struct rsi_set_key *set_key;
 	u16 key_descriptor = 0;
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index a82552cf..331d64b 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -618,7 +618,8 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid,
 				      u16 ssn, u8 buf_size, u8 event,
 				      u8 sta_id);
 int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
-		     u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
+		     u8 key_type, u8 key_id, u32 cipher, s16 sta_id,
+		     struct ieee80211_vif *vif);
 int rsi_set_channel(struct rsi_common *common,
 		    struct ieee80211_channel *channel);
 int rsi_send_vap_dynamic_update(struct rsi_common *common);
-- 
2.7.4

^ permalink raw reply related

* [PATCH 4/8] rsi: handle peer connection and disconnection in p2p mode
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

Parameter 'vif' is passed to inform_bss_status function to
check the type of vif and to get vap_id.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_core.c     |  9 ++++--
 drivers/net/wireless/rsi/rsi_91x_hal.c      | 47 +++++++++++++++++------------
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 22 +++++++++-----
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 15 +++++----
 drivers/net/wireless/rsi/rsi_hal.h          |  3 +-
 drivers/net/wireless/rsi/rsi_main.h         |  2 ++
 drivers/net/wireless/rsi/rsi_mgmt.h         |  5 ++-
 7 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index d212196..432d6eb 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -361,8 +361,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
 	struct rsi_hw *adapter = common->priv;
 	struct ieee80211_tx_info *info;
 	struct skb_info *tx_params;
-	struct ieee80211_hdr *wh;
-	struct ieee80211_vif *vif = adapter->vifs[0];
+	struct ieee80211_hdr *wh = NULL;
+	struct ieee80211_vif *vif;
 	u8 q_num, tid = 0;
 	struct rsi_sta *rsta = NULL;
 
@@ -381,6 +381,11 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
 	wh = (struct ieee80211_hdr *)&skb->data[0];
 	tx_params->sta_id = 0;
 
+	vif = rsi_get_vif(adapter, wh->addr2);
+	if (!vif)
+		goto xmit_fail;
+	tx_params->vif = vif;
+	tx_params->vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id;
 	if ((ieee80211_is_mgmt(wh->frame_control)) ||
 	    (ieee80211_is_ctl(wh->frame_control)) ||
 	    (ieee80211_is_qos_nullfunc(wh->frame_control))) {
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 070dfd6..d0b119e 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -42,7 +42,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 	struct ieee80211_hdr *wh = NULL;
 	struct ieee80211_tx_info *info;
 	struct ieee80211_conf *conf = &adapter->hw->conf;
-	struct ieee80211_vif *vif = adapter->vifs[0];
+	struct ieee80211_vif *vif;
 	struct rsi_mgmt_desc *mgmt_desc;
 	struct skb_info *tx_params;
 	struct ieee80211_bss_conf *bss = NULL;
@@ -57,6 +57,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 
 	info = IEEE80211_SKB_CB(skb);
 	tx_params = (struct skb_info *)info->driver_data;
+	vif = tx_params->vif;
 
 	/* Update header size */
 	header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
@@ -78,7 +79,7 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 
 	tx_params->internal_hdr_size = header_size;
 	memset(&skb->data[0], 0, header_size);
-	bss = &info->control.vif->bss_conf;
+	bss = &vif->bss_conf;
 	wh = (struct ieee80211_hdr *)&skb->data[header_size];
 
 	mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
@@ -95,10 +96,10 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 
 	mgmt_desc->seq_ctrl =
 		cpu_to_le16(IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl)));
-	if (common->band == NL80211_BAND_2GHZ)
-		mgmt_desc->rate_info = RSI_RATE_1;
+	if ((common->band == NL80211_BAND_2GHZ) && !common->p2p_enabled)
+		mgmt_desc->rate_info = cpu_to_le16(RSI_RATE_1);
 	else
-		mgmt_desc->rate_info = RSI_RATE_6;
+		mgmt_desc->rate_info = cpu_to_le16(RSI_RATE_6);
 
 	if (conf_is_ht40(conf))
 		mgmt_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
@@ -121,7 +122,8 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 		xtend_desc->retry_cnt = PROBE_RESP_RETRY_CNT;
 	}
 
-	if ((vif->type == NL80211_IFTYPE_AP) &&
+	if (((vif->type == NL80211_IFTYPE_AP) ||
+	     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
 	    (ieee80211_is_action(wh->frame_control))) {
 		struct rsi_sta *rsta = rsi_find_sta(common, wh->addr1);
 
@@ -130,6 +132,10 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
 		else
 			return -EINVAL;
 	}
+	mgmt_desc->rate_info |=
+		cpu_to_le16((tx_params->vap_id << RSI_DESC_VAP_ID_OFST) &
+			    RSI_DESC_VAP_ID_MASK);
+
 	return 0;
 }
 
@@ -306,21 +312,11 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
 	struct ieee80211_tx_info *info;
 	struct skb_info *tx_params;
 	int status = -E2BIG;
-	u8 extnd_size;
 
 	info = IEEE80211_SKB_CB(skb);
 	tx_params = (struct skb_info *)info->driver_data;
-	extnd_size = ((uintptr_t)skb->data & 0x3);
 
 	if (tx_params->flags & INTERNAL_MGMT_PKT) {
-		skb->data[1] |= BIT(7); /* Immediate Wakeup bit*/
-		if ((extnd_size) > skb_headroom(skb)) {
-			rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
-			dev_kfree_skb(skb);
-			return -ENOSPC;
-		}
-		skb_push(skb, extnd_size);
-		skb->data[extnd_size + 4] = extnd_size;
 		status = adapter->host_intf_ops->write_pkt(common->priv,
 							   (u8 *)skb->data,
 							   skb->len);
@@ -352,12 +348,23 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)
 	struct rsi_data_desc *bcn_frm;
 	struct ieee80211_hw *hw = common->priv->hw;
 	struct ieee80211_conf *conf = &hw->conf;
+	struct ieee80211_vif *vif;
 	struct sk_buff *mac_bcn;
-	u8 vap_id = 0;
-	u16 tim_offset;
-
+	u8 vap_id = 0, i;
+	u16 tim_offset = 0;
+
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		vif = adapter->vifs[i];
+		if (!vif)
+			continue;
+		if ((vif->type == NL80211_IFTYPE_AP) ||
+		    (vif->type == NL80211_IFTYPE_P2P_GO))
+			break;
+	}
+	if (!vif)
+		return -EINVAL;
 	mac_bcn = ieee80211_beacon_get_tim(adapter->hw,
-					   adapter->vifs[adapter->sc_nvifs - 1],
+					   vif,
 					   &tim_offset, NULL);
 	if (!mac_bcn) {
 		rsi_dbg(ERR_ZONE, "Failed to get beacon from mac80211\n");
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 6780c1c..ce2f911 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -718,7 +718,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 				      bss_conf->bssid,
 				      bss_conf->qos,
 				      bss_conf->aid,
-				      NULL, 0);
+				      NULL, 0, vif);
 		adapter->ps_info.dtim_interval_duration = bss->dtim_period;
 		adapter->ps_info.listen_interval = conf->listen_interval;
 
@@ -862,7 +862,8 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
 	rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n",
 		__func__, key->cipher, key_type, key->keylen);
 
-	if (vif->type == NL80211_IFTYPE_AP) {
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 		if (sta) {
 			rsta = rsi_find_sta(adapter->priv, sta->addr);
 			if (rsta)
@@ -1297,7 +1298,8 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 
 	mutex_lock(&common->mutex);
 
-	if (vif->type == NL80211_IFTYPE_AP) {
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 		u8 cnt;
 		int sta_idx = -1;
 		int free_index = -1;
@@ -1348,7 +1350,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 			rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
 			rsi_inform_bss_status(common, RSI_OPMODE_AP, 1,
 					      sta->addr, sta->wme, sta->aid,
-					      sta, sta_idx);
+					      sta, sta_idx, vif);
 
 			if (common->key) {
 				struct ieee80211_key_conf *key = common->key;
@@ -1368,7 +1370,8 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 		}
 	}
 
-	if (vif->type == NL80211_IFTYPE_STATION) {
+	if ((vif->type == NL80211_IFTYPE_STATION) ||
+	    (vif->type == NL80211_IFTYPE_P2P_CLIENT)) {
 		rsi_set_min_rate(hw, sta, common);
 		if (sta->ht_cap.ht_supported) {
 			common->vif_info[0].is_ht = true;
@@ -1409,7 +1412,8 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 
 	mutex_lock(&common->mutex);
 
-	if (vif->type == NL80211_IFTYPE_AP) {
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 		u8 sta_idx, cnt;
 
 		/* Send peer notify to device */
@@ -1422,7 +1426,8 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 			if (!memcmp(rsta->sta->addr, sta->addr, ETH_ALEN)) {
 				rsi_inform_bss_status(common, RSI_OPMODE_AP, 0,
 						      sta->addr, sta->wme,
-						      sta->aid, sta, sta_idx);
+						      sta->aid, sta, sta_idx,
+						      vif);
 				rsta->sta = NULL;
 				rsta->sta_id = -1;
 				for (cnt = 0; cnt < IEEE80211_NUM_TIDS; cnt++)
@@ -1436,7 +1441,8 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 			rsi_dbg(ERR_ZONE, "%s: No station found\n", __func__);
 	}
 
-	if (vif->type == NL80211_IFTYPE_STATION) {
+	if ((vif->type == NL80211_IFTYPE_STATION) ||
+	    (vif->type == NL80211_IFTYPE_P2P_CLIENT)) {
 		/* Resetting all the fields to default values */
 		memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN);
 		bss->qos = sta->wme;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index aaf5f32..428369b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -460,12 +460,12 @@ static int rsi_hal_send_sta_notify_frame(struct rsi_common *common,
 					 const unsigned char *bssid,
 					 u8 qos_enable,
 					 u16 aid,
-					 u16 sta_id)
+					 u16 sta_id,
+					 struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif = common->priv->vifs[0];
 	struct sk_buff *skb = NULL;
 	struct rsi_peer_notify *peer_notify;
-	u16 vap_id = 0;
+	u16 vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id;
 	int status;
 	u16 frame_len = sizeof(struct rsi_peer_notify);
 
@@ -1318,7 +1318,8 @@ void rsi_inform_bss_status(struct rsi_common *common,
 			   u8 qos_enable,
 			   u16 aid,
 			   struct ieee80211_sta *sta,
-			   u16 sta_id)
+			   u16 sta_id,
+			   struct ieee80211_vif *vif)
 {
 	if (status) {
 		if (opmode == RSI_OPMODE_STA)
@@ -1328,7 +1329,8 @@ void rsi_inform_bss_status(struct rsi_common *common,
 					      STA_CONNECTED,
 					      addr,
 					      qos_enable,
-					      aid, sta_id);
+					      aid, sta_id,
+					      vif);
 		if (common->min_rate == 0xffff)
 			rsi_send_auto_rate_request(common, sta, sta_id);
 		if (opmode == RSI_OPMODE_STA) {
@@ -1343,7 +1345,8 @@ void rsi_inform_bss_status(struct rsi_common *common,
 					      STA_DISCONNECTED,
 					      addr,
 					      qos_enable,
-					      aid, sta_id);
+					      aid, sta_id,
+					      vif);
 		if (opmode == RSI_OPMODE_STA)
 			rsi_send_block_unblock_frame(common, true);
 	}
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 7c14505..ad0d653 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -121,8 +121,7 @@ struct rsi_mgmt_desc {
 	u8 xtend_desc_size;
 	u8 header_len;
 	__le16 frame_info;
-	u8 rate_info;
-	u8 reserved1;
+	__le16 rate_info;
 	__le16 bbp_info;
 	__le16 seq_ctrl;
 	u8 reserved2;
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index fd07b37..34089ab 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -124,6 +124,8 @@ struct skb_info {
 	s8 tid;
 	s8 sta_id;
 	u8 internal_hdr_size;
+	struct ieee80211_vif *vif;
+	u8 vap_id;
 };
 
 enum edca_queue {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 08e3b43..a82552cf 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -189,6 +189,8 @@
 	 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
 	 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
 
+#define RSI_DESC_VAP_ID_MASK		0xC000
+#define RSI_DESC_VAP_ID_OFST		14
 #define RSI_DATA_DESC_MAC_BBP_INFO	BIT(0)
 #define RSI_DATA_DESC_NO_ACK_IND	BIT(9)
 #define RSI_DATA_DESC_QOS_EN		BIT(12)
@@ -623,7 +625,8 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common);
 int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
 void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
 			   u8 status, const u8 *addr, u8 qos_enable, u16 aid,
-			   struct ieee80211_sta *sta, u16 sta_id);
+			   struct ieee80211_sta *sta, u16 sta_id,
+			   struct ieee80211_vif *vif);
 void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
 int rsi_mac80211_attach(struct rsi_common *common);
 void rsi_indicate_tx_status(struct rsi_hw *common, struct sk_buff *skb,
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/8] rsi: add support for p2p listen
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

Remain-on-channel and cancel-remain-on-channel are implemented
to support p2p listen phase.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_core.c     |  15 +++
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 188 +++++++++++++++++++++++++---
 drivers/net/wireless/rsi/rsi_91x_main.c     |   9 +-
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |   4 +-
 drivers/net/wireless/rsi/rsi_common.h       |   4 +-
 drivers/net/wireless/rsi/rsi_main.h         |   2 +
 drivers/net/wireless/rsi/rsi_mgmt.h         |   2 +-
 7 files changed, 199 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index 2b0516d..d212196 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -334,6 +334,21 @@ struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
 	return NULL;
 }
 
+struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac)
+{
+	struct ieee80211_vif *vif;
+	int i;
+
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		vif = adapter->vifs[i];
+		if (!vif)
+			continue;
+		if (!memcmp(vif->addr, mac, ETH_ALEN))
+			return vif;
+	}
+	return NULL;
+}
+
 /**
  * rsi_core_xmit() - This function transmits the packets received from mac80211
  * @common: Pointer to the driver private structure.
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index db69d87..6780c1c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -503,35 +503,44 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
 	int status = -EOPNOTSUPP;
 	struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 	u16 channel = curchan->hw_value;
-	struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
+	struct ieee80211_vif *vif;
+	struct ieee80211_bss_conf *bss;
+	bool assoc = false;
+	int i;
 
 	rsi_dbg(INFO_ZONE,
 		"%s: Set channel: %d MHz type: %d channel_no %d\n",
 		__func__, curchan->center_freq,
 		curchan->flags, channel);
 
-	if (bss->assoc) {
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		vif = adapter->vifs[i];
+		if (!vif)
+			continue;
+		if (vif->type == NL80211_IFTYPE_STATION) {
+			bss = &vif->bss_conf;
+			if (bss->assoc) {
+				assoc = true;
+				break;
+			}
+		}
+	}
+	if (assoc) {
 		if (!common->hw_data_qs_blocked &&
-		    (rsi_get_connected_channel(adapter) != channel)) {
+		    (rsi_get_connected_channel(vif) != channel)) {
 			rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
 			if (!rsi_send_block_unblock_frame(common, true))
 				common->hw_data_qs_blocked = true;
 		}
 	}
 
-	status = rsi_band_check(common);
+	status = rsi_band_check(common, curchan);
 	if (!status)
 		status = rsi_set_channel(adapter->priv, curchan);
 
-	if (bss->assoc) {
+	if (assoc) {
 		if (common->hw_data_qs_blocked &&
-		    (rsi_get_connected_channel(adapter) == channel)) {
-			rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
-			if (!rsi_send_block_unblock_frame(common, false))
-				common->hw_data_qs_blocked = false;
-		}
-	} else {
-		if (common->hw_data_qs_blocked) {
+		    (rsi_get_connected_channel(vif) == channel)) {
 			rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
 			if (!rsi_send_block_unblock_frame(common, false))
 				common->hw_data_qs_blocked = false;
@@ -632,16 +641,42 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
  *
  * Return: Current connected AP's channel number is returned.
  */
-u16 rsi_get_connected_channel(struct rsi_hw *adapter)
+u16 rsi_get_connected_channel(struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif = adapter->vifs[0];
-	if (vif) {
-		struct ieee80211_bss_conf *bss = &vif->bss_conf;
-		struct ieee80211_channel *channel = bss->chandef.chan;
-		return channel->hw_value;
-	}
+	struct ieee80211_bss_conf *bss;
+	struct ieee80211_channel *channel;
 
-	return 0;
+	if (!vif)
+		return 0;
+
+	bss = &vif->bss_conf;
+	channel = bss->chandef.chan;
+
+	if (!channel)
+		return 0;
+
+	return channel->hw_value;
+}
+
+static void rsi_switch_channel(struct rsi_hw *adapter,
+			       struct ieee80211_vif *vif)
+{
+	struct rsi_common *common = adapter->priv;
+	struct ieee80211_channel *channel;
+
+	if (common->iface_down)
+		return;
+	if (!vif)
+		return;
+
+	channel = vif->bss_conf.chandef.chan;
+
+	if (!channel)
+		return;
+
+	rsi_band_check(common, channel);
+	rsi_set_channel(common, channel);
+	rsi_dbg(INFO_ZONE, "Switched to channel - %d\n", channel->hw_value);
 }
 
 /**
@@ -1561,6 +1596,114 @@ static void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
 	mutex_unlock(&common->mutex);
 }
 
+static void rsi_resume_conn_channel(struct rsi_common *common)
+{
+	struct rsi_hw *adapter = common->priv;
+	struct ieee80211_vif *vif;
+	int cnt;
+
+	for (cnt = 0; cnt < RSI_MAX_VIFS; cnt++) {
+		vif = adapter->vifs[cnt];
+		if (!vif)
+			continue;
+
+		if ((vif->type == NL80211_IFTYPE_AP) ||
+		    (vif->type == NL80211_IFTYPE_P2P_GO)) {
+			rsi_switch_channel(adapter, vif);
+			break;
+		}
+		if (((vif->type == NL80211_IFTYPE_STATION) ||
+		     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
+		    vif->bss_conf.assoc) {
+			rsi_switch_channel(adapter, vif);
+			break;
+		}
+	}
+}
+
+void rsi_roc_timeout(unsigned long data)
+{
+	struct rsi_common *common = (struct rsi_common *)data;
+
+	rsi_dbg(INFO_ZONE, "Remain on channel expired\n");
+
+	mutex_lock(&common->mutex);
+	ieee80211_remain_on_channel_expired(common->priv->hw);
+
+	if (timer_pending(&common->roc_timer))
+		del_timer(&common->roc_timer);
+
+	rsi_resume_conn_channel(common);
+	mutex_unlock(&common->mutex);
+}
+
+static int rsi_mac80211_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			    struct ieee80211_channel *chan, int duration,
+			    enum ieee80211_roc_type type)
+{
+	struct rsi_hw *adapter = (struct rsi_hw *)hw->priv;
+	struct rsi_common *common = (struct rsi_common *)adapter->priv;
+	int status = 0;
+
+	rsi_dbg(INFO_ZONE, "***** Remain on channel *****\n");
+
+	mutex_lock(&common->mutex);
+	rsi_dbg(INFO_ZONE, "%s: channel: %d duration: %dms\n",
+		__func__, chan->hw_value, duration);
+
+	if (timer_pending(&common->roc_timer)) {
+		rsi_dbg(INFO_ZONE, "Stop on-going ROC\n");
+		del_timer(&common->roc_timer);
+	}
+	common->roc_timer.expires = msecs_to_jiffies(duration) + jiffies;
+	add_timer(&common->roc_timer);
+
+	/* Configure band */
+	if (rsi_band_check(common, chan)) {
+		rsi_dbg(ERR_ZONE, "Failed to set band\n");
+		status = -EINVAL;
+		goto out;
+	}
+
+	/* Configure channel */
+	if (rsi_set_channel(common, chan)) {
+		rsi_dbg(ERR_ZONE, "Failed to set the channel\n");
+		status = -EINVAL;
+		goto out;
+	}
+
+	common->roc_vif = vif;
+	ieee80211_ready_on_channel(hw);
+	rsi_dbg(INFO_ZONE, "%s: Ready on channel :%d\n",
+		__func__, chan->hw_value);
+
+out:
+	mutex_unlock(&common->mutex);
+
+	return status;
+}
+
+static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw)
+{
+	struct rsi_hw *adapter = hw->priv;
+	struct rsi_common *common = adapter->priv;
+
+	rsi_dbg(INFO_ZONE, "Cancel remain on channel\n");
+
+	mutex_lock(&common->mutex);
+	if (!timer_pending(&common->roc_timer)) {
+		mutex_unlock(&common->mutex);
+		return 0;
+	}
+
+	del_timer(&common->roc_timer);
+
+	rsi_resume_conn_channel(common);
+	mutex_unlock(&common->mutex);
+
+	return 0;
+}
+
 static const struct ieee80211_ops mac80211_ops = {
 	.tx = rsi_mac80211_tx,
 	.start = rsi_mac80211_start,
@@ -1580,6 +1723,8 @@ static const struct ieee80211_ops mac80211_ops = {
 	.set_antenna = rsi_mac80211_set_antenna,
 	.get_antenna = rsi_mac80211_get_antenna,
 	.rfkill_poll = rsi_mac80211_rfkill_poll,
+	.remain_on_channel = rsi_mac80211_roc,
+	.cancel_remain_on_channel = rsi_mac80211_cancel_roc,
 };
 
 /**
@@ -1666,6 +1811,9 @@ int rsi_mac80211_attach(struct rsi_common *common)
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 
 	/* Wi-Fi direct parameters */
+	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+	wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX;
+	wiphy->max_remain_on_channel_duration = 10000;
 	hw->max_listen_interval = 10;
 	wiphy->iface_combinations = rsi_iface_combinations;
 	wiphy->n_iface_combinations = ARRAY_SIZE(rsi_iface_combinations);
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index 3e1e808..b57bfdc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -74,6 +74,8 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
 	struct skb_info *rx_params;
 	struct sk_buff *skb = NULL;
 	u8 payload_offset;
+	struct ieee80211_vif *vif;
+	struct ieee80211_hdr *wh;
 
 	if (WARN(!pkt_len, "%s: Dummy pkt received", __func__))
 		return NULL;
@@ -92,11 +94,13 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
 	payload_offset = (extended_desc + FRAME_DESC_SZ);
 	skb_put(skb, pkt_len);
 	memcpy((skb->data), (buffer + payload_offset), skb->len);
+	wh = (struct ieee80211_hdr *)skb->data;
+	vif = rsi_get_vif(common->priv, wh->addr1);
 
 	info = IEEE80211_SKB_CB(skb);
 	rx_params = (struct skb_info *)info->driver_data;
 	rx_params->rssi = rsi_get_rssi(buffer);
-	rx_params->channel = rsi_get_connected_channel(common->priv);
+	rx_params->channel = rsi_get_connected_channel(vif);
 
 	return skb;
 }
@@ -233,6 +237,9 @@ struct rsi_hw *rsi_91x_init(void)
 
 	rsi_default_ps_params(adapter);
 	spin_lock_init(&adapter->ps_lock);
+	common->roc_timer.data = (unsigned long)common;
+	common->roc_timer.function = (void *)&rsi_roc_timeout;
+	init_timer(&common->roc_timer);
 	common->init_done = true;
 	return adapter;
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 082329d..aaf5f32 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -926,13 +926,13 @@ static int rsi_send_reset_mac(struct rsi_common *common)
  *
  * Return: 0 on success, corresponding error code on failure.
  */
-int rsi_band_check(struct rsi_common *common)
+int rsi_band_check(struct rsi_common *common,
+		   struct ieee80211_channel *curchan)
 {
 	struct rsi_hw *adapter = common->priv;
 	struct ieee80211_hw *hw = adapter->hw;
 	u8 prev_bw = common->channel_width;
 	u8 prev_ep = common->endpoint;
-	struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 	int status = 0;
 
 	if (common->band != curchan->band) {
diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h
index e579d69..272e18d 100644
--- a/drivers/net/wireless/rsi/rsi_common.h
+++ b/drivers/net/wireless/rsi/rsi_common.h
@@ -79,9 +79,11 @@ static inline int rsi_kill_thread(struct rsi_thread *handle)
 }
 
 void rsi_mac80211_detach(struct rsi_hw *hw);
-u16 rsi_get_connected_channel(struct rsi_hw *adapter);
+u16 rsi_get_connected_channel(struct ieee80211_vif *vif);
 struct rsi_hw *rsi_91x_init(void);
 void rsi_91x_deinit(struct rsi_hw *adapter);
 int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len);
 struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
+struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac);
+void rsi_roc_timeout(unsigned long data);
 #endif
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index a4837fa..fd07b37 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -274,6 +274,8 @@ struct rsi_common {
 
 	/* Wi-Fi direct mode related */
 	bool p2p_enabled;
+	struct timer_list roc_timer;
+	struct ieee80211_vif *roc_vif;
 };
 
 enum host_intf {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 8bd7dfa..08e3b43 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -633,7 +633,7 @@ void rsi_core_qos_processor(struct rsi_common *common);
 void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb);
 int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
 int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
-int rsi_band_check(struct rsi_common *common);
+int rsi_band_check(struct rsi_common *common, struct ieee80211_channel *chan);
 int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
 int rsi_send_radio_params_update(struct rsi_common *common);
 int rsi_set_antenna(struct rsi_common *common, u8 antenna);
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/8] rsi: add/remove interface enhancements for p2p
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

STA_OPMODE and AP_OPMODE macros are renamed to RSI_OPMODE_STA
and RSI_OPMODE_AP. New opmodes are added to this list for P2P
support. Mapping of mac80211 interface types to rsi interface
types are added.
Add and remove interface callbacks are handled for P2P mode.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 117 +++++++++++++++++-----------
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |  12 +--
 drivers/net/wireless/rsi/rsi_main.h         |   6 +-
 drivers/net/wireless/rsi/rsi_mgmt.h         |   9 ++-
 4 files changed, 89 insertions(+), 55 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 992ac6c..db69d87 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -355,6 +355,24 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw)
 	mutex_unlock(&common->mutex);
 }
 
+static int rsi_map_intf_mode(enum nl80211_iftype vif_type)
+{
+	switch (vif_type) {
+	case NL80211_IFTYPE_STATION:
+		return RSI_OPMODE_STA;
+	case NL80211_IFTYPE_AP:
+		return RSI_OPMODE_AP;
+	case NL80211_IFTYPE_P2P_DEVICE:
+		return RSI_OPMODE_P2P_CLIENT;
+	case NL80211_IFTYPE_P2P_CLIENT:
+		return RSI_OPMODE_P2P_CLIENT;
+	case NL80211_IFTYPE_P2P_GO:
+		return RSI_OPMODE_P2P_GO;
+	default:
+		return RSI_OPMODE_UNSUPPORTED;
+	}
+}
+
 /**
  * rsi_mac80211_add_interface() - This function is called when a netdevice
  *				  attached to the hardware is enabled.
@@ -368,54 +386,62 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
 {
 	struct rsi_hw *adapter = hw->priv;
 	struct rsi_common *common = adapter->priv;
+	struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv;
 	enum opmode intf_mode;
-	int ret = -EOPNOTSUPP;
+	enum vap_status vap_status;
+	int vap_idx = -1, i;
 
 	vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
 	mutex_lock(&common->mutex);
 
-	if (adapter->sc_nvifs > 1) {
-		mutex_unlock(&common->mutex);
-		return -EOPNOTSUPP;
-	}
-
-	switch (vif->type) {
-	case NL80211_IFTYPE_STATION:
-		rsi_dbg(INFO_ZONE, "Station Mode");
-		intf_mode = STA_OPMODE;
-		break;
-	case NL80211_IFTYPE_AP:
-		rsi_dbg(INFO_ZONE, "AP Mode");
-		intf_mode = AP_OPMODE;
-		break;
-	default:
+	intf_mode = rsi_map_intf_mode(vif->type);
+	if (intf_mode == RSI_OPMODE_UNSUPPORTED) {
 		rsi_dbg(ERR_ZONE,
 			"%s: Interface type %d not supported\n", __func__,
 			vif->type);
-		goto out;
+		mutex_unlock(&common->mutex);
+		return -EOPNOTSUPP;
+	}
+	if ((vif->type == NL80211_IFTYPE_P2P_DEVICE) ||
+	    (vif->type == NL80211_IFTYPE_P2P_CLIENT) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO))
+		common->p2p_enabled = true;
+
+	/* Get free vap index */
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		if (!adapter->vifs[i]) {
+			vap_idx = i;
+			break;
+		}
+	}
+	if (vap_idx < 0) {
+		rsi_dbg(ERR_ZONE, "Reject: Max VAPs reached\n");
+		mutex_unlock(&common->mutex);
+		return -EOPNOTSUPP;
 	}
+	vif_info->vap_id = vap_idx;
+	adapter->vifs[vap_idx] = vif;
+	adapter->sc_nvifs++;
+	vap_status = VAP_ADD;
 
-	adapter->vifs[adapter->sc_nvifs++] = vif;
-	ret = rsi_set_vap_capabilities(common, intf_mode, common->mac_addr,
-				       0, VAP_ADD);
-	if (ret) {
+	if (rsi_set_vap_capabilities(common, intf_mode, vif->addr,
+				     vif_info->vap_id, vap_status)) {
 		rsi_dbg(ERR_ZONE, "Failed to set VAP capabilities\n");
-		goto out;
+		mutex_unlock(&common->mutex);
+		return -EINVAL;
 	}
 
-	if (vif->type == NL80211_IFTYPE_AP) {
-		int i;
-
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_P2P_GO)) {
 		rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
 		common->min_rate = RSI_RATE_AUTO;
 		for (i = 0; i < common->max_stations; i++)
 			common->stations[i].sta = NULL;
 	}
 
-out:
 	mutex_unlock(&common->mutex);
 
-	return ret;
+	return 0;
 }
 
 /**
@@ -432,6 +458,7 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
 	struct rsi_hw *adapter = hw->priv;
 	struct rsi_common *common = adapter->priv;
 	enum opmode opmode;
+	int i;
 
 	rsi_dbg(INFO_ZONE, "Remove Interface Called\n");
 
@@ -442,23 +469,22 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
 		return;
 	}
 
-	switch (vif->type) {
-	case NL80211_IFTYPE_STATION:
-		opmode = STA_OPMODE;
-		break;
-	case NL80211_IFTYPE_AP:
-		opmode = AP_OPMODE;
-		break;
-	default:
+	opmode = rsi_map_intf_mode(vif->type);
+	if (opmode == RSI_OPMODE_UNSUPPORTED) {
+		rsi_dbg(ERR_ZONE, "Opmode error : %d\n", opmode);
 		mutex_unlock(&common->mutex);
 		return;
 	}
-	rsi_set_vap_capabilities(common, opmode, vif->addr,
-				 0, VAP_DELETE);
-	adapter->sc_nvifs--;
-
-	if (!memcmp(adapter->vifs[0], vif, sizeof(struct ieee80211_vif)))
-		adapter->vifs[0] = NULL;
+	for (i = 0; i < RSI_MAX_VIFS; i++) {
+		if (!adapter->vifs[i])
+			continue;
+		if (vif == adapter->vifs[i]) {
+			rsi_set_vap_capabilities(common, opmode, vif->addr,
+						 i, VAP_DELETE);
+			adapter->sc_nvifs--;
+			adapter->vifs[i] = NULL;
+		}
+	}
 	mutex_unlock(&common->mutex);
 }
 
@@ -652,7 +678,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 			rsi_send_rx_filter_frame(common, rx_filter_word);
 		}
 		rsi_inform_bss_status(common,
-				      STA_OPMODE,
+				      RSI_OPMODE_STA,
 				      bss_conf->assoc,
 				      bss_conf->bssid,
 				      bss_conf->qos,
@@ -1285,8 +1311,9 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 
 			/* Send peer notify to device */
 			rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
-			rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr,
-					      sta->wme, sta->aid, sta, sta_idx);
+			rsi_inform_bss_status(common, RSI_OPMODE_AP, 1,
+					      sta->addr, sta->wme, sta->aid,
+					      sta, sta_idx);
 
 			if (common->key) {
 				struct ieee80211_key_conf *key = common->key;
@@ -1358,7 +1385,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 			if (!rsta->sta)
 				continue;
 			if (!memcmp(rsta->sta->addr, sta->addr, ETH_ALEN)) {
-				rsi_inform_bss_status(common, AP_OPMODE, 0,
+				rsi_inform_bss_status(common, RSI_OPMODE_AP, 0,
 						      sta->addr, sta->wme,
 						      sta->aid, sta, sta_idx);
 				rsta->sta = NULL;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index f7b550f..082329d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -482,9 +482,9 @@ static int rsi_hal_send_sta_notify_frame(struct rsi_common *common,
 	memset(skb->data, 0, frame_len);
 	peer_notify = (struct rsi_peer_notify *)skb->data;
 
-	if (opmode == STA_OPMODE)
+	if (opmode == RSI_OPMODE_STA)
 		peer_notify->command = cpu_to_le16(PEER_TYPE_AP << 1);
-	else if (opmode == AP_OPMODE)
+	else if (opmode == RSI_OPMODE_AP)
 		peer_notify->command = cpu_to_le16(PEER_TYPE_STA << 1);
 
 	switch (notify_event) {
@@ -1321,7 +1321,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
 			   u16 sta_id)
 {
 	if (status) {
-		if (opmode == STA_OPMODE)
+		if (opmode == RSI_OPMODE_STA)
 			common->hw_data_qs_blocked = true;
 		rsi_hal_send_sta_notify_frame(common,
 					      opmode,
@@ -1331,12 +1331,12 @@ void rsi_inform_bss_status(struct rsi_common *common,
 					      aid, sta_id);
 		if (common->min_rate == 0xffff)
 			rsi_send_auto_rate_request(common, sta, sta_id);
-		if (opmode == STA_OPMODE) {
+		if (opmode == RSI_OPMODE_STA) {
 			if (!rsi_send_block_unblock_frame(common, false))
 				common->hw_data_qs_blocked = false;
 		}
 	} else {
-		if (opmode == STA_OPMODE)
+		if (opmode == RSI_OPMODE_STA)
 			common->hw_data_qs_blocked = true;
 		rsi_hal_send_sta_notify_frame(common,
 					      opmode,
@@ -1344,7 +1344,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
 					      addr,
 					      qos_enable,
 					      aid, sta_id);
-		if (opmode == STA_OPMODE)
+		if (opmode == RSI_OPMODE_STA)
 			rsi_send_block_unblock_frame(common, true);
 	}
 }
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 2c18dde..a4837fa 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -60,7 +60,7 @@ enum RSI_FSM_STATES {
 extern u32 rsi_zone_enabled;
 extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
 
-#define RSI_MAX_VIFS                    1
+#define RSI_MAX_VIFS                    3
 #define NUM_EDCA_QUEUES                 4
 #define IEEE80211_ADDR_LEN              6
 #define FRAME_DESC_SZ                   16
@@ -157,6 +157,7 @@ struct vif_priv {
 	bool is_ht;
 	bool sgi;
 	u16 seq_start;
+	int vap_id;
 };
 
 struct rsi_event {
@@ -270,6 +271,9 @@ struct rsi_common {
 	int num_stations;
 	int max_stations;
 	struct ieee80211_key_conf *key;
+
+	/* Wi-Fi direct mode related */
+	bool p2p_enabled;
 };
 
 enum host_intf {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index c6e1fa6..8bd7dfa 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -200,8 +200,11 @@
 #define RSI_DATA_DESC_INSERT_SEQ_NO	BIT(2)
 
 enum opmode {
-	AP_OPMODE = 0,
-	STA_OPMODE,
+	RSI_OPMODE_UNSUPPORTED = -1,
+	RSI_OPMODE_AP = 0,
+	RSI_OPMODE_STA,
+	RSI_OPMODE_P2P_GO,
+	RSI_OPMODE_P2P_CLIENT
 };
 
 enum vap_status {
@@ -363,9 +366,9 @@ struct rsi_vap_caps {
 	u8 vif_type;
 	u8 channel_bw;
 	__le16 antenna_info;
+	__le16 token;
 	u8 radioid_macid;
 	u8 vap_id;
-	__le16 reserved3;
 	u8 mac_addr[6];
 	__le16 keep_alive_period;
 	u8 bssid[6];
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/8] rsi: add p2p support parameters to mac80211
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi
In-Reply-To: <1504085908-2163-1-git-send-email-amitkarwar@gmail.com>

From: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>

This patch adds p2p supported parameters to mac80211 hw and
wiphy structures during mac80211 registration.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 37 ++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index fa12c05..992ac6c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -139,6 +139,32 @@ static const u32 rsi_max_ap_stas[16] = {
 	4,	/* 14 - AP + BT Dual */
 };
 
+static const struct ieee80211_iface_limit rsi_iface_limits[] = {
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_STATION),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_AP) |
+			BIT(NL80211_IFTYPE_P2P_CLIENT) |
+			BIT(NL80211_IFTYPE_P2P_GO),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+	},
+};
+
+static const struct ieee80211_iface_combination rsi_iface_combinations[] = {
+	{
+		.num_different_channels = 1,
+		.max_interfaces = 3,
+		.limits = rsi_iface_limits,
+		.n_limits = ARRAY_SIZE(rsi_iface_limits),
+	},
+};
+
 /**
  * rsi_is_cipher_wep() -  This function determines if the cipher is WEP or not.
  * @common: Pointer to the driver private structure.
@@ -1581,7 +1607,11 @@ int rsi_mac80211_attach(struct rsi_common *common)
 	ether_addr_copy(hw->wiphy->addr_mask, addr_mask);
 
 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-				 BIT(NL80211_IFTYPE_AP);
+				 BIT(NL80211_IFTYPE_AP) |
+				 BIT(NL80211_IFTYPE_P2P_DEVICE) |
+				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
+				 BIT(NL80211_IFTYPE_P2P_GO);
+
 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 	wiphy->retry_short = RETRY_SHORT;
 	wiphy->retry_long  = RETRY_LONG;
@@ -1608,6 +1638,11 @@ int rsi_mac80211_attach(struct rsi_common *common)
 
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 
+	/* Wi-Fi direct parameters */
+	hw->max_listen_interval = 10;
+	wiphy->iface_combinations = rsi_iface_combinations;
+	wiphy->n_iface_combinations = ARRAY_SIZE(rsi_iface_combinations);
+
 	status = ieee80211_register_hw(hw);
 	if (status)
 		return status;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 0/8] rsi: p2p mode support
From: Amitkumar Karwar @ 2017-08-30  9:38 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Amitkumar Karwar, Prameela Rani Garnepudi

From: Amitkumar Karwar <amit.karwar@redpinesignals.com>

p2p mode support is added in this patch series. Major changes
include allowing multiple interface addition and updating
interface type checks wherever needed.

Prameela Rani Garnepudi (8):
  rsi: add p2p support parameters to mac80211
  rsi: add/remove interface enhancements for p2p
  rsi: add support for p2p listen
  rsi: handle peer connection and disconnection in p2p mode
  rsi: tx and rx path enhancements for p2p mode
  rsi: disallow power save config when AP vap running
  rsi: aggregation changes for p2p mode
  rsi: miscellaneous changes for p2p mode

 drivers/net/wireless/rsi/rsi_91x_core.c     |  33 +-
 drivers/net/wireless/rsi/rsi_91x_hal.c      |  73 +++--
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 446 ++++++++++++++++++++++------
 drivers/net/wireless/rsi/rsi_91x_main.c     |   9 +-
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     |  46 +--
 drivers/net/wireless/rsi/rsi_91x_ps.c       |  15 +-
 drivers/net/wireless/rsi/rsi_common.h       |   4 +-
 drivers/net/wireless/rsi/rsi_hal.h          |   3 +-
 drivers/net/wireless/rsi/rsi_main.h         |  10 +-
 drivers/net/wireless/rsi/rsi_mgmt.h         |  21 +-
 drivers/net/wireless/rsi/rsi_ps.h           |   7 +-
 11 files changed, 495 insertions(+), 172 deletions(-)

-- 
2.7.4

^ permalink raw reply

* pull-request: iwlwifi-next 2017-08-30
From: Luca Coelho @ 2017-08-30  9:38 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, linuxwifi

[-- Attachment #1: Type: text/plain, Size: 1792 bytes --]

Hi Kalle,

Here's my fourth and final pull-request intended for v4.14.  It contains
just a couple of small fixes and a FW API number bump.  More details in
the tag description.

I have fixed the subject of one of the patches for the typo you reported
during review.

I have sent this out before, and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit d081a16db80ef7a260fb178aa1199e01f7432625:

  net: bcmgenet: Do not return from void function (2017-08-29 22:39:51 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git tags/iwlwifi-next-for-kalle-2017-08-30

for you to fetch changes up to d7a5b3e9e42ee95190742fef0d617bbde4f74d80:

  iwlwifi: mvm: bump API to 34 for 8000 and up (2017-08-30 12:30:56 +0300)

----------------------------------------------------------------
Last set of iwlwifi patches for 4.14

* Fix a queue hang problem due to 11w behavior
* Fix a warning caused by a too long debug print
* Bump API number to the latest version we support

----------------------------------------------------------------
David Spinadel (1):
      iwlwifi: mvm: Avoid deferring non bufferable frames

Emmanuel Grumbach (1):
      iwlwifi: mvm: bump API to 34 for 8000 and up

Liad Kaufman (1):
      iwlwifi: fix long debug print

 drivers/net/wireless/intel/iwlwifi/cfg/8000.c      | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c      | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/a000.c      | 2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 9 +++++++--
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  | 9 +++++----
 5 files changed, 16 insertions(+), 10 deletions(-)

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* [PATCH] iwlwifi: mvm: bump API to 34 for 8000 and up
From: Luca Coelho @ 2017-08-30  9:27 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Emmanuel Grumbach, Luca Coelho

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

These devices support -34.ucode, so load it.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/a000.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
index 5081720608af..2e6c52664cee 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
@@ -70,8 +70,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX	33
-#define IWL8265_UCODE_API_MAX	33
+#define IWL8000_UCODE_API_MAX	34
+#define IWL8265_UCODE_API_MAX	34
 
 /* Lowest firmware API version supported */
 #define IWL8000_UCODE_API_MIN	22
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index 97208ce19f92..2babe0a1f18b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL9000_UCODE_API_MAX	33
+#define IWL9000_UCODE_API_MAX	34
 
 /* Lowest firmware API version supported */
 #define IWL9000_UCODE_API_MIN	30
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
index dcd35b5c9d24..76ba1f8bc72f 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL_A000_UCODE_API_MAX	33
+#define IWL_A000_UCODE_API_MAX	34
 
 /* Lowest firmware API version supported */
 #define IWL_A000_UCODE_API_MIN	24
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH 3/5] qtnfmac: modify qtnf_map_bar not to return NULL
From: Sergey Matyukevich @ 2017-08-30  8:45 UTC (permalink / raw)
  To: Igor Mitsyanko; +Cc: linux-wireless, Avinash Patil
In-Reply-To: <fc30ee02-2aaa-23c6-46e3-fbeb5b5230ef@quantenna.com>

On Tue, Aug 29, 2017 at 07:13:35PM -0700, Igor Mitsyanko wrote:
> On 08/29/2017 05:16 AM, Sergey Matyukevich wrote:
> > NULL is not a special type of success here but a error pointer.
> > So it makes sense to check against NULL in qtnf_map_bar
> > and return error code.
> > 
> > Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
> > ---
> 
> On a first glance not immediately obvious what is logically changed here, is
> it so that pr_debug() would not print NULL pointer?

There is no actual bug here: all the mappings and error checks are in place.
This is more about coding style problem: when function return both NULL and
error pointeres, then the NULL is supposed to be a special type of success
return. In this particular case NULL is just yet another failure.

^ permalink raw reply

* Re: [PATCH 14/27] qtnfmac: do not cache CSA chandef info
From: Sergey Matyukevich @ 2017-08-30  8:05 UTC (permalink / raw)
  To: Igor Mitsyanko; +Cc: linux-wireless, avinashp, johannes
In-Reply-To: <0627667f-87d7-644b-a582-27b9ce638ff9@quantenna.com>

On Tue, Aug 29, 2017 at 06:48:23PM -0700, Igor Mitsyanko wrote:
> On 08/29/2017 08:44 AM, Sergey Matyukevich wrote:
> > I am ok with removal of CSA chandef info. It was kept mainly to warn
> > about channel switch to the frequency that differs from original
> > CSA request.
> > 
> > > -	if (vif->vifid != 0) {
> > > -		if (!(mac->status & QTNF_MAC_CSA_ACTIVE))
> > > -			return -EOPNOTSUPP;
> > > -
> > > -		if (!cfg80211_chandef_identical(&params->chandef,
> > > -						&mac->csa_chandef))
> > > -			return -EINVAL;
> > > -
> > > -		return 0;
> > > -	}
> > 
> > 
> > This particular CSA_ACTIVE status check was introduced for compatibility with
> > hostapd behaviour. Currently hostapd goes through all the virtual interfaces
> > and sends CSA for each of them. So the idea was to send CSA for primary
> > interface and confirm success for the others. If this snipped is dropped
> > then we end up in multiple identical CSA requests queued in firmware.
> > 
> > I suggest to remove chandef_identical check, but to keep the logic for
> > secondary virtual interface handling.
> 
> The idea was that driver doesn't have to keep track of this, but instead it
> will just forward directly to card, and card will return success for CSA
> request to the same channel, because card knows that already.
> 
> As a bonus, in case it will ever support virtual concurrent (virtual
> interfaces on different physical channels), no changes to driver will be
> required.

If we drop this check from driver, then we have to add similar check into
the firmware for the time being. We should drop subsequent CSA requests
for secondary virtual interfaces.

Regards,
Sergey

^ permalink raw reply

* Re: [PATCH 2/2] iwlwifi: mvm: Avoid deffering non bufferable frames
From: Luca Coelho @ 2017-08-30  7:32 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, David Spinadel
In-Reply-To: <87efruvl4e.fsf@kamboji.qca.qualcomm.com>

On Tue, 2017-08-29 at 11:22 +0300, Kalle Valo wrote:
> Luca Coelho <luca@coelho.fi> writes:
> 
> > From: David Spinadel <david.spinadel@intel.com>
> > 
> > Use bcast station for all non bufferable frames on AP and AD-HOC.
> > 
> > The host is no longer aware of STAs PS status because of buffer
> > station offload, so we can't rely on mac80211 to toggle on
> > IEEE80211_TX_CTL_NO_PS_BUFFER bit.
> > 
> > A possible issue with buffering such frames, beside the obvious spec
> > violation, is when a station disconnects while in PS but the AP isn't
> > aware of that. In such scenarios the AP won't be able to send probe
> > responses or auth frames so the STA won't be able to reconnect and
> > the AP will have a queue hang.
> > 
> > Fixes: 3e56eadfb6a1 ("iwlwifi: mvm: implement AP/GO uAPSD support")
> > Signed-off-by: David Spinadel <david.spinadel@intel.com>
> > Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
> 
> "deffering"? Should it be deferring?

Yeah, sorry, I'll fix it before sending the pull-req.

--
Cheers,
Luca.

^ permalink raw reply

* [PATCH] brcmfmac: feature check for multi-scheduled scan fails on bcm4345 devices
From: Ian W MORRISON @ 2017-08-30  6:04 UTC (permalink / raw)
  To: arend.vanspriel, kvalo, ian, linux-wireless

The firmware feature check introduced for multi-scheduled scan is also
failing for bcm4345 devices resulting in a firmware crash.
The reason for this crash has not yet been root cause so this patch avoids
the feature check for those device as a short-term fix.

Fixes: 9fe929aaace6 ("brcmfmac: add firmware feature detection for gscan feature")
Signed-off-by: Ian W Morrison <ianwmorrison@gmail.com>
---
Tested on MINIX NEO Z83-4 and MINIX NEO Z83-4 Pro devices.
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index f1b60740e..53ae302 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -159,7 +159,8 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)

        brcmf_feat_firmware_capabilities(ifp);
        memset(&gscan_cfg, 0, sizeof(gscan_cfg));
-       if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID)
+       if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID &&
+           drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID)
                brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN,
                                          "pfn_gscan_cfg",
                                          &gscan_cfg, sizeof(gscan_cfg));
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH] Documentation: dt-binding: net: wireless: add bcm43430-fmac
From: Chen-Yu Tsai @ 2017-08-30  2:28 UTC (permalink / raw)
  To: Antony Antony
  Cc: Kalle Valo, Rob Herring, Mark Rutland, Icenowy Zheng, devicetree,
	Hans de Goede, linux-wireless, Maxime Ripard, Chen-Yu Tsai
In-Reply-To: <20170829214309.34466-1-antony@phenome.org>

Hi,

On Wed, Aug 30, 2017 at 5:43 AM, Antony Antony <antony@phenome.org> wrote:
> Add device tree binding documentation for Broadcom BCM43430
> AMPAK AP6212A has this chip.
>
> e.g
> compatible = "brcm,bcm43430-fmac";
>
> NanoPi NEO Plus2 has an AMPAK AP6212A WiFi module
> with BCM43430 rev=1 inside.
> brcmf_chip_recognition found AXI chip: BCM43430, rev=1
> brcmf_ops_sdio_probe sdio vendor ID: 0x02d0
> brcmf_ops_sdio_probe sdio device ID: 0xa9a6
>
> Signed-off-by: Antony Antony <antony@phenome.org>
> ---
>  Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>  NanoPi Neo Plus2 Kernel DT propsed patch
>  https://patchwork.kernel.org/patch/9925387/
>
> diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
> index 590f622..9107e1a 100644
> --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
> +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
> @@ -6,7 +6,9 @@ connects the device to the system.
>
>  Required properties:
>
> - - compatible : Should be "brcm,bcm4329-fmac".
> + - compatible : should be one of the following:
> +       * "brcm,bcm4329-fmac"
> +       * "brcm,bcm43430-fmac"

You updated the bindings, but not the driver. So it's not actually
going to work. More specifically, OOB interrupts won't work.

IIRC, The compatible string for this particular case, as it was
originally proposed, only serves as a placeholder for the driver
to check against. None of the instances in sunxi device trees
match the actual chip model. Actual model matching is done
through SDIO, as you've already seen.

ChenYu


>
>  Optional properties:
>   - brcm,drive-strength : drive strength used for SDIO pins on device in mA
> --
> 2.9.3
>

^ permalink raw reply

* Re: [PATCH 3/5] qtnfmac: modify qtnf_map_bar not to return NULL
From: Igor Mitsyanko @ 2017-08-30  2:14 UTC (permalink / raw)
  To: Sergey Matyukevich; +Cc: linux-wireless, Avinash Patil
In-Reply-To: <20170829121623.24761-4-sergey.matyukevich.os@quantenna.com>

On 08/29/2017 05:16 AM, Sergey Matyukevich wrote:
> NULL is not a special type of success here but a error pointer.
> So it makes sense to check against NULL in qtnf_map_bar
> and return error code.
> 
> Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
> ---

On a first glance not immediately obvious what is logically changed 
here, is it so that pr_debug() would not print NULL pointer?

^ permalink raw reply

* Re: [PATCH 3/5] qtnfmac: modify qtnf_map_bar not to return NULL
From: Igor Mitsyanko @ 2017-08-30  2:13 UTC (permalink / raw)
  To: Sergey Matyukevich; +Cc: linux-wireless, Avinash Patil
In-Reply-To: <20170829121623.24761-4-sergey.matyukevich.os@quantenna.com>

On 08/29/2017 05:16 AM, Sergey Matyukevich wrote:
> NULL is not a special type of success here but a error pointer.
> So it makes sense to check against NULL in qtnf_map_bar
> and return error code.
> 
> Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
> ---

On a first glance not immediately obvious what is logically changed 
here, is it so that pr_debug() would not print NULL pointer?

^ permalink raw reply

* Re: [PATCH 14/27] qtnfmac: do not cache CSA chandef info
From: Igor Mitsyanko @ 2017-08-30  1:48 UTC (permalink / raw)
  To: sergey.matyukevich.os@quantenna.com; +Cc: linux-wireless, avinashp, johannes
In-Reply-To: <20170829154455.j2qrxcu35mwkwzcl@bars>

On 08/29/2017 08:44 AM, Sergey Matyukevich wrote:
> I am ok with removal of CSA chandef info. It was kept mainly to warn
> about channel switch to the frequency that differs from original
> CSA request.
> 
>> -	if (vif->vifid != 0) {
>> -		if (!(mac->status & QTNF_MAC_CSA_ACTIVE))
>> -			return -EOPNOTSUPP;
>> -
>> -		if (!cfg80211_chandef_identical(&params->chandef,
>> -						&mac->csa_chandef))
>> -			return -EINVAL;
>> -
>> -		return 0;
>> -	}
> 
> 
> This particular CSA_ACTIVE status check was introduced for compatibility with
> hostapd behaviour. Currently hostapd goes through all the virtual interfaces
> and sends CSA for each of them. So the idea was to send CSA for primary
> interface and confirm success for the others. If this snipped is dropped
> then we end up in multiple identical CSA requests queued in firmware.
> 
> I suggest to remove chandef_identical check, but to keep the logic for
> secondary virtual interface handling.
> 
> Regards,
> Sergey
> 

The idea was that driver doesn't have to keep track of this, but instead 
it will just forward directly to card, and card will return success for 
CSA request to the same channel, because card knows that already.

As a bonus, in case it will ever support virtual concurrent (virtual 
interfaces on different physical channels), no changes to driver will be 
required.

^ permalink raw reply

* Re: [PATCH 02/27] qtnfmac: make "Channel change" event report full channel info
From: Igor Mitsyanko @ 2017-08-30  1:45 UTC (permalink / raw)
  To: sergey.matyukevich.os; +Cc: linux-wireless, avinashp, johannes
In-Reply-To: <20170829143146.ersgkofruzdpta6y@bars>

On 08/29/2017 07:31 AM, Sergey Matyukevich wrote:
>>   static int
>>   qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
>> @@ -358,41 +359,36 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
>>   			      u16 len)
>>   {
>>   	struct wiphy *wiphy = priv_to_wiphy(mac);
>> -	struct cfg80211_chan_def chandef;
>> -	struct ieee80211_channel *chan;
>> +	struct cfg80211_chan_def chdef;
>>   	struct qtnf_vif *vif;
>> -	int freq;
>>   	int i;
> 
> Original variable name 'chandef' was easier to spell on the phone :)

Will return)

> 
> ...
> 
>> +	qlink_chandef_q2cfg(wiphy, &data->chan, &chdef);
>> +
>> +	if (!cfg80211_chandef_valid(&chdef)) {
>> +		pr_err("MAC%u: bad channel freq1=%u bw=%u\n", mac->macid,
>> +		       chdef.center_freq1, chdef.width);
>>   		return -EINVAL;
>>   	}
> 
> Lets keep both freq1 and freq2 in error message.

Ok

> 
> ...
> 
>> +void qlink_chandef_q2cfg(struct wiphy *wiphy,
>> +			 const struct qlink_chandef *qch,
>> +			 struct cfg80211_chan_def *chdef)
>> +{
>> +	chdef->center_freq1 = le16_to_cpu(qch->center_freq1);
>> +	chdef->center_freq2 = le16_to_cpu(qch->center_freq2);
>> +	chdef->width = qlink_chanwidth_to_nl(qch->width);
>> +
>> +	switch (chdef->width) {
>> +	case NL80211_CHAN_WIDTH_20_NOHT:
>> +	case NL80211_CHAN_WIDTH_20:
>> +	case NL80211_CHAN_WIDTH_5:
>> +	case NL80211_CHAN_WIDTH_10:
>> +		chdef->chan = ieee80211_get_channel(wiphy, chdef->center_freq1);
>> +		break;
>> +	case NL80211_CHAN_WIDTH_40:
>> +	case NL80211_CHAN_WIDTH_80:
>> +	case NL80211_CHAN_WIDTH_80P80:
>> +	case NL80211_CHAN_WIDTH_160:
>> +		chdef->chan = ieee80211_get_channel(wiphy,
>> +						    chdef->center_freq1 - 10);
> 
> Do we have the same formula for 40MHz and 80MHz center frequency ?
> I thought we should be using the channel number for the left-most 20MHz band.

Here it should be no difference which channel number we're using as long 
as it falls within specified bandwidth. I mean, we can take (freq - 10), 
(freq + 10) for 40MHz, or (freq - 30) (freq + 30) for 80 MHz etc.

I don't see how we can identify which 20MHz channel is primary, with a 
chandef structure.

> 
>> +		break;
>> +	default:
>> +		chdef->chan = NULL;
>> +		break;
>> +	}
>> +}
> 
> Regards,
> Sergey
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox