Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/7] brcmfmac: sync firmware event list
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

Update event list to keep sync with firmware development. Use calculated event
mask length instead of hard-coded value.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h  |    2 --
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h |    5 ++++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 2eb9e64..4de9aac 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -97,8 +97,6 @@
 #define	WLC_PHY_TYPE_LCN	8
 #define	WLC_PHY_TYPE_NULL	0xf
 
-#define BRCMF_EVENTING_MASK_LEN	16
-
 #define TOE_TX_CSUM_OL		0x00000001
 #define TOE_RX_CSUM_OL		0x00000002
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index e679214..9ee5c51 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -102,7 +102,8 @@ struct brcmf_event;
 	BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
 	BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
 	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
-	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
+	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
+	BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
 
 #define BRCMF_ENUM_DEF(id, val) \
 	BRCMF_E_##id = (val),
@@ -114,6 +115,8 @@ enum brcmf_fweh_event_code {
 };
 #undef BRCMF_ENUM_DEF
 
+#define BRCMF_EVENTING_MASK_LEN		(roundup(BRCMF_E_LAST, 8)/8)
+
 /* flags field values in struct brcmf_event_msg */
 #define BRCMF_EVENT_MSG_LINK		0x01
 #define BRCMF_EVENT_MSG_FLUSHTXQ	0x02
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 5/7] brcmfmac: fix sparse error 'bad constant expression'
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

The definition of BRCMF_EVENTING_MASK_LEN results in a sparse
error message

.../fweh.c:331:22: error: bad constant expression
.../fweh.c:388:22: error: bad constant expression
.../dhd_common.c:256:22: error: bad constant expression

This is caused by the use of roundup() in BRCMF_EVENTING_MASK_LEN
and it is used to allocate an array variable on the stack. Better
use DIV_ROUND_UP() macro.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 9ee5c51..14bc24d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -115,7 +115,7 @@ enum brcmf_fweh_event_code {
 };
 #undef BRCMF_ENUM_DEF
 
-#define BRCMF_EVENTING_MASK_LEN		(roundup(BRCMF_E_LAST, 8)/8)
+#define BRCMF_EVENTING_MASK_LEN		DIV_ROUND_UP(BRCMF_E_LAST, 8)
 
 /* flags field values in struct brcmf_event_msg */
 #define BRCMF_EVENT_MSG_LINK		0x01
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 2/7] brcmfmac: add BCM4339 SDIO interface support
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

BCM4339 is an a/b/g/n/ac 1x1 WiFi chip. This patch adds support for it through
SDIO interface.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c   |   11 +++--------
 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c  |   18 ++++++++++++++++++
 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h  |    8 ++++++++
 drivers/net/wireless/brcm80211/include/brcm_hw_ids.h |    1 +
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 64f4a2b..f849d73 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -34,6 +34,7 @@
 #include <brcmu_utils.h>
 #include <brcmu_wifi.h>
 #include "sdio_host.h"
+#include "sdio_chip.h"
 #include "dhd_dbg.h"
 #include "dhd_bus.h"
 
@@ -41,13 +42,6 @@
 
 #define DMA_ALIGN_MASK	0x03
 
-#define SDIO_DEVICE_ID_BROADCOM_43143	43143
-#define SDIO_DEVICE_ID_BROADCOM_43241	0x4324
-#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
-#define SDIO_DEVICE_ID_BROADCOM_4330	0x4330
-#define SDIO_DEVICE_ID_BROADCOM_4334	0x4334
-#define SDIO_DEVICE_ID_BROADCOM_4335	0x4335
-
 #define SDIO_FUNC1_BLOCKSIZE		64
 #define SDIO_FUNC2_BLOCKSIZE		512
 
@@ -58,7 +52,8 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
 	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
 	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
 	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335)},
+	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
+		     SDIO_DEVICE_ID_BROADCOM_4335_4339)},
 	{ /* end: all zeroes */ },
 };
 MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index ca72177..023ddcb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
 #include <linux/ssb/ssb_regs.h>
 #include <linux/bcma/bcma.h>
 
@@ -444,6 +445,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
 				   NULL);
 	ci->chip = regdata & CID_ID_MASK;
 	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
+	if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
+	    ci->chiprev >= 2)
+		ci->chip = BCM4339_CHIP_ID;
 	ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 
 	brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
@@ -541,6 +545,20 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
 		ci->ramsize = 0xc0000;
 		ci->rambase = 0x180000;
 		break;
+	case BCM4339_CHIP_ID:
+		ci->c_inf[0].wrapbase = 0x18100000;
+		ci->c_inf[0].cib = 0x2e084411;
+		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
+		ci->c_inf[1].base = 0x18005000;
+		ci->c_inf[1].wrapbase = 0x18105000;
+		ci->c_inf[1].cib = 0x15004211;
+		ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
+		ci->c_inf[2].base = 0x18002000;
+		ci->c_inf[2].wrapbase = 0x18102000;
+		ci->c_inf[2].cib = 0x04084411;
+		ci->ramsize = 0xc0000;
+		ci->rambase = 0x180000;
+		break;
 	default:
 		brcmf_err("chipid 0x%x is not supported\n", ci->chip);
 		return -ENODEV;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
index 83c041f..076b83c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
@@ -54,6 +54,14 @@
 
 #define BRCMF_MAX_CORENUM	6
 
+/* SDIO device ID */
+#define SDIO_DEVICE_ID_BROADCOM_43143		43143
+#define SDIO_DEVICE_ID_BROADCOM_43241		0x4324
+#define SDIO_DEVICE_ID_BROADCOM_4329		0x4329
+#define SDIO_DEVICE_ID_BROADCOM_4330		0x4330
+#define SDIO_DEVICE_ID_BROADCOM_4334		0x4334
+#define SDIO_DEVICE_ID_BROADCOM_4335_4339	0x4335
+
 struct chip_core_info {
 	u16 id;
 	u16 rev;
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index c1fe245..84113ea 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -41,5 +41,6 @@
 #define BCM4331_CHIP_ID		0x4331
 #define BCM4334_CHIP_ID		0x4334
 #define BCM4335_CHIP_ID		0x4335
+#define BCM4339_CHIP_ID		0x4339
 
 #endif				/* _BRCM_HW_IDS_H_ */
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 3/7] brcmfmac: add valid core index check in related functions
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

Perform a valid check for core index to avoid illegal address access.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 023ddcb..2096a14 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -137,6 +137,8 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
 	u8 idx;
 
 	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
+	if (idx == BRCMF_MAX_CORENUM)
+		return false;
 
 	regdata = brcmf_sdio_regrl(sdiodev,
 				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
@@ -155,6 +157,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
 	bool ret;
 
 	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
+	if (idx == BRCMF_MAX_CORENUM)
+		return false;
 
 	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 				   NULL);
@@ -262,6 +266,8 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
 	u32 regdata;
 
 	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
+	if (idx == BRCMF_MAX_CORENUM)
+		return;
 
 	/* if core is already in reset, just return */
 	regdata = brcmf_sdio_regrl(sdiodev,
@@ -305,6 +311,8 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
 	u8 idx;
 
 	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
+	if (idx == BRCMF_MAX_CORENUM)
+		return;
 
 	/*
 	 * Must do the disable sequence first to work for
@@ -369,6 +377,8 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
 	u32 regdata;
 
 	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
+	if (idx == BRCMF_MAX_CORENUM)
+		return;
 
 	/* must disable first to work for arbitrary current core state */
 	brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 7/7] brcmfmac: rework rx path bus interface
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

The brcmfmac has common and bus specific part. The rx function api
was using sk_buff_head. Changed to sk_buff instead.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    2 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   38 +++++++++-----------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |   12 +++----
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    5 +--
 4 files changed, 22 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index f7c1985..200ee9b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -136,7 +136,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
 			 struct sk_buff *pkt, int prec);
 
 /* Receive frame for delivery to OS.  Callee disposes of rxp. */
-extern void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist);
+extern void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
 
 /* Indication from bus module regarding presence/insertion of dongle. */
 extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index e067aec..42bf19a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -509,9 +509,8 @@ netif_rx:
 	}
 }
 
-void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
 {
-	struct sk_buff *skb, *pnext;
 	struct brcmf_if *ifp;
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_pub *drvr = bus_if->drvr;
@@ -519,29 +518,24 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
 	u8 ifidx;
 	int ret;
 
-	brcmf_dbg(DATA, "Enter: %s: count=%u\n", dev_name(dev),
-		  skb_queue_len(skb_list));
+	brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
 
-	skb_queue_walk_safe(skb_list, skb, pnext) {
-		skb_unlink(skb, skb_list);
-
-		/* process and remove protocol-specific header */
-		ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
-		ifp = drvr->iflist[ifidx];
-
-		if (ret || !ifp || !ifp->ndev) {
-			if ((ret != -ENODATA) && ifp)
-				ifp->stats.rx_errors++;
-			brcmu_pkt_buf_free_skb(skb);
-			continue;
-		}
+	/* process and remove protocol-specific header */
+	ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
+	ifp = drvr->iflist[ifidx];
 
-		rd = (struct brcmf_skb_reorder_data *)skb->cb;
-		if (rd->reorder)
-			brcmf_rxreorder_process_info(ifp, rd->reorder, skb);
-		else
-			brcmf_netif_rx(ifp, skb);
+	if (ret || !ifp || !ifp->ndev) {
+		if ((ret != -ENODATA) && ifp)
+			ifp->stats.rx_errors++;
+		brcmu_pkt_buf_free_skb(skb);
+		return;
 	}
+
+	rd = (struct brcmf_skb_reorder_data *)skb->cb;
+	if (rd->reorder)
+		brcmf_rxreorder_process_info(ifp, rd->reorder, skb);
+	else
+		brcmf_netif_rx(ifp, skb);
 }
 
 void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 6e72b73..67f05db 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1492,13 +1492,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 					   bus->glom.qlen, pfirst, pfirst->data,
 					   pfirst->len, pfirst->next,
 					   pfirst->prev);
+			skb_unlink(pfirst, &bus->glom);
+			brcmf_rx_frame(bus->sdiodev->dev, pfirst);
+			bus->sdcnt.rxglompkts++;
 		}
-		/* sent any remaining packets up */
-		if (bus->glom.qlen)
-			brcmf_rx_frames(bus->sdiodev->dev, &bus->glom);
 
 		bus->sdcnt.rxglomframes++;
-		bus->sdcnt.rxglompkts += bus->glom.qlen;
 	}
 	return num;
 }
@@ -1643,7 +1642,6 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
 static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
 {
 	struct sk_buff *pkt;		/* Packet for event or data frames */
-	struct sk_buff_head pktlist;	/* needed for bus interface */
 	u16 pad;		/* Number of pad bytes to read */
 	uint rxleft = 0;	/* Remaining number of frames allowed */
 	int ret;		/* Return code from calls */
@@ -1845,9 +1843,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
 			continue;
 		}
 
-		skb_queue_head_init(&pktlist);
-		skb_queue_tail(&pktlist, pkt);
-		brcmf_rx_frames(bus->sdiodev->dev, &pktlist);
+		brcmf_rx_frame(bus->sdiodev->dev, pkt);
 	}
 
 	rxcount = maxframes - rxleft;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 39e01a7..bf6758d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -435,7 +435,6 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 	struct brcmf_usbreq  *req = (struct brcmf_usbreq *)urb->context;
 	struct brcmf_usbdev_info *devinfo = req->devinfo;
 	struct sk_buff *skb;
-	struct sk_buff_head skbq;
 
 	brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
 	brcmf_usb_del_fromq(devinfo, req);
@@ -450,10 +449,8 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 	}
 
 	if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
-		skb_queue_head_init(&skbq);
-		skb_queue_tail(&skbq, skb);
 		skb_put(skb, urb->actual_length);
-		brcmf_rx_frames(devinfo->dev, &skbq);
+		brcmf_rx_frame(devinfo->dev, skb);
 		brcmf_usb_rx_refill(devinfo, req);
 	} else {
 		brcmu_pkt_buf_free_skb(skb);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 0/7] brcmfmac: cleanup and new device support
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series has a few cleanup patches fixing a sparse error, cleaning
up the rx path and also changing the firmware filename approach after
getting feedback on this by Stephen Warren. The remaining patches are
adding support for the BCM4339 SDIO chipset.

This series is intended for v3.13 kernel and applies to the master
branch of the wireless-next repository.

Arend van Spriel (2):
  brcmfmac: fix sparse error 'bad constant expression'
  brcmfmac: rework rx path bus interface

Franky Lin (4):
  brcmfmac: sync firmware event list
  brcmfmac: add BCM4339 SDIO interface support
  brcmfmac: add valid core index check in related functions
  brcmfmac: reserve memory for bus layer in sk_buff::cb

Hante Meuleman (1):
  brcmfmac: Use fw filename and nvram based of devid for sdio.

 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   11 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |    2 -
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    2 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   38 ++--
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  234 ++++++++++++--------
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h     |    5 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |    2 +
 .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |   28 +++
 .../net/wireless/brcm80211/brcmfmac/sdio_chip.h    |    8 +
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    5 +-
 .../net/wireless/brcm80211/include/brcm_hw_ids.h   |    1 +
 11 files changed, 211 insertions(+), 125 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH 4/7] brcmfmac: reserve memory for bus layer in sk_buff::cb
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

Bus layer need to share sk_buff::cb with firmware signal feature. Reserve
necessary memory so they won't overwrite each other.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |   15 ++++++++++-----
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |    2 ++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 1aa75d5..f9ba4d0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1786,10 +1786,15 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
 	return;
 }
 
+/**
+ * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
+ * bus layer usage.
+ */
 /* flag marking a dummy skb added for DMA alignment requirement */
-#define DUMMY_SKB_FLAG		0x10000
+#define ALIGN_SKB_FLAG		0x8000
 /* bit mask of data length chopped from the previous packet */
-#define DUMMY_SKB_CHOP_LEN_MASK	0xffff
+#define ALIGN_SKB_CHOP_LEN_MASK	0x7fff
+
 /**
  * brcmf_sdio_txpkt_prep - packet preparation for transmit
  * @bus: brcmf_sdio structure pointer
@@ -1854,7 +1859,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
 		memcpy(pkt_new->data,
 		       pkt_next->data + pkt_next->len - tail_chop,
 		       tail_chop);
-		*(u32 *)(pkt_new->cb) = DUMMY_SKB_FLAG + tail_chop;
+		*(u32 *)(pkt_new->cb) = ALIGN_SKB_FLAG + tail_chop;
 		skb_trim(pkt_next, pkt_next->len - tail_chop);
 		__skb_queue_after(pktq, pkt_next, pkt_new);
 	} else {
@@ -1908,8 +1913,8 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
 
 	skb_queue_walk_safe(pktq, pkt_next, tmp) {
 		dummy_flags = *(u32 *)(pkt_next->cb);
-		if (dummy_flags & DUMMY_SKB_FLAG) {
-			chop_len = dummy_flags & DUMMY_SKB_CHOP_LEN_MASK;
+		if (dummy_flags & ALIGN_SKB_FLAG) {
+			chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
 			if (chop_len) {
 				pkt_prev = pkt_next->prev;
 				memcpy(pkt_prev->data + pkt_prev->len,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 82f9140..d0cd0bf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -168,6 +168,7 @@ enum brcmf_fws_skb_state {
 /**
  * struct brcmf_skbuff_cb - control buffer associated with skbuff.
  *
+ * @bus_flags: 2 bytes reserved for bus specific parameters
  * @if_flags: holds interface index and packet related flags.
  * @htod: host to device packet identifier (used in PKTTAG tlv).
  * @state: transmit state of the packet.
@@ -177,6 +178,7 @@ enum brcmf_fws_skb_state {
  * provides 48 bytes of storage so this structure should not exceed that.
  */
 struct brcmf_skbuff_cb {
+	u16 bus_flags;
 	u16 if_flags;
 	u32 htod;
 	enum brcmf_fws_skb_state state;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 6/7] brcmfmac: Use fw filename and nvram based of devid for sdio.
From: Arend van Spriel @ 2013-09-25 11:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel
In-Reply-To: <1380107146-24026-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

SDIO firmware download routines uses one name for firmware file
and nvram file for all sdio devices. This is not user friendly.
Use fw filename and nvram filename based upon chip id and revision.

Reported-by: Stephen Warren <swarren@wwwdotorg.org>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  207 +++++++++++++-------
 1 file changed, 133 insertions(+), 74 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f9ba4d0..6e72b73 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -275,11 +275,6 @@ struct rte_console {
 /* Flags for SDH calls */
 #define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
 
-#define BRCMF_SDIO_FW_NAME	"brcm/brcmfmac-sdio.bin"
-#define BRCMF_SDIO_NV_NAME	"brcm/brcmfmac-sdio.txt"
-MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
-MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
-
 #define BRCMF_IDLE_IMMEDIATE	(-1)	/* Enter idle immediately */
 #define BRCMF_IDLE_ACTIVE	0	/* Do not request any SD clock change
 					 * when idle
@@ -454,9 +449,6 @@ struct brcmf_sdio {
 	struct work_struct datawork;
 	atomic_t dpc_tskcnt;
 
-	const struct firmware *firmware;
-	u32 fw_ptr;
-
 	bool txoff;		/* Transmit flow-controlled */
 	struct brcmf_sdio_count sdcnt;
 	bool sr_enabled; /* SaveRestore enabled */
@@ -493,6 +485,100 @@ enum brcmf_sdio_frmtype {
 	BRCMF_SDIO_FT_SUB,
 };
 
+#define BCM43143_FIRMWARE_NAME		"brcm/brcmfmac43143-sdio.bin"
+#define BCM43143_NVRAM_NAME		"brcm/brcmfmac43143-sdio.txt"
+#define BCM43241B0_FIRMWARE_NAME	"brcm/brcmfmac43241b0-sdio.bin"
+#define BCM43241B0_NVRAM_NAME		"brcm/brcmfmac43241b0-sdio.txt"
+#define BCM43241B4_FIRMWARE_NAME	"brcm/brcmfmac43241b4-sdio.bin"
+#define BCM43241B4_NVRAM_NAME		"brcm/brcmfmac43241b4-sdio.txt"
+#define BCM4329_FIRMWARE_NAME		"brcm/brcmfmac4329-sdio.bin"
+#define BCM4329_NVRAM_NAME		"brcm/brcmfmac4329-sdio.txt"
+#define BCM4330_FIRMWARE_NAME		"brcm/brcmfmac4330-sdio.bin"
+#define BCM4330_NVRAM_NAME		"brcm/brcmfmac4330-sdio.txt"
+#define BCM4334_FIRMWARE_NAME		"brcm/brcmfmac4334-sdio.bin"
+#define BCM4334_NVRAM_NAME		"brcm/brcmfmac4334-sdio.txt"
+#define BCM4335_FIRMWARE_NAME		"brcm/brcmfmac4335-sdio.bin"
+#define BCM4335_NVRAM_NAME		"brcm/brcmfmac4335-sdio.txt"
+
+MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
+MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME);
+MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME);
+MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM4329_NVRAM_NAME);
+MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM4330_NVRAM_NAME);
+MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
+MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
+
+struct brcmf_firmware_names {
+	u32 chipid;
+	u32 revmsk;
+	const char *bin;
+	const char *nv;
+};
+
+enum brcmf_firmware_type {
+	BRCMF_FIRMWARE_BIN,
+	BRCMF_FIRMWARE_NVRAM
+};
+
+#define BRCMF_FIRMWARE_NVRAM(name) \
+	name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
+
+static const struct brcmf_firmware_names brcmf_fwname_data[] = {
+	{ BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
+	{ BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
+	{ BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
+	{ BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
+	{ BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
+	{ BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
+	{ BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }
+};
+
+
+static const struct firmware *brcmf_sdbrcm_get_fw(struct brcmf_sdio *bus,
+						  enum brcmf_firmware_type type)
+{
+	const struct firmware *fw;
+	const char *name;
+	int err, i;
+
+	for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
+		if (brcmf_fwname_data[i].chipid == bus->ci->chip &&
+		    brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) {
+			switch (type) {
+			case BRCMF_FIRMWARE_BIN:
+				name = brcmf_fwname_data[i].bin;
+				break;
+			case BRCMF_FIRMWARE_NVRAM:
+				name = brcmf_fwname_data[i].nv;
+				break;
+			default:
+				brcmf_err("invalid firmware type (%d)\n", type);
+				return NULL;
+			}
+			goto found;
+		}
+	}
+	brcmf_err("Unknown chipid %d [%d]\n",
+		  bus->ci->chip, bus->ci->chiprev);
+	return NULL;
+
+found:
+	err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev);
+	if ((err) || (!fw)) {
+		brcmf_err("fail to request firmware %s (%d)\n", name, err);
+		return NULL;
+	}
+
+	return fw;
+}
+
 static void pkt_align(struct sk_buff *p, int len, int align)
 {
 	uint datalign;
@@ -3042,69 +3128,43 @@ static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
 	return true;
 }
 
-static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus)
-{
-	if (bus->firmware->size < bus->fw_ptr + len)
-		len = bus->firmware->size - bus->fw_ptr;
-
-	memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
-	bus->fw_ptr += len;
-	return len;
-}
-
 static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
 {
+	const struct firmware *fw;
+	int err;
 	int offset;
-	uint len;
-	u8 *memblock = NULL, *memptr;
-	int ret;
-	u8 idx;
-
-	brcmf_dbg(INFO, "Enter\n");
-
-	ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
-			       &bus->sdiodev->func[2]->dev);
-	if (ret) {
-		brcmf_err("Fail to request firmware %d\n", ret);
-		return ret;
-	}
-	bus->fw_ptr = 0;
-
-	memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
-	if (memblock == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-	if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
-		memptr += (BRCMF_SDALIGN -
-			   ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
-
-	offset = bus->ci->rambase;
-
-	/* Download image */
-	len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus);
-	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4);
-	if (BRCMF_MAX_CORENUM != idx)
-		memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec));
-	while (len) {
-		ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len);
-		if (ret) {
+	int address;
+	int len;
+
+	fw = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_BIN);
+	if (fw == NULL)
+		return -ENOENT;
+
+	if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) !=
+	    BRCMF_MAX_CORENUM)
+		memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec));
+
+	err = 0;
+	offset = 0;
+	address = bus->ci->rambase;
+	while (offset < fw->size) {
+		len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
+		      fw->size - offset;
+		err = brcmf_sdio_ramrw(bus->sdiodev, true, address,
+				       (u8 *)&fw->data[offset], len);
+		if (err) {
 			brcmf_err("error %d on writing %d membytes at 0x%08x\n",
-				  ret, MEMBLOCK, offset);
-			goto err;
+				  err, len, address);
+			goto failure;
 		}
-
-		offset += MEMBLOCK;
-		len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus);
+		offset += len;
+		address += len;
 	}
 
-err:
-	kfree(memblock);
-
-	release_firmware(bus->firmware);
-	bus->fw_ptr = 0;
+failure:
+	release_firmware(fw);
 
-	return ret;
+	return err;
 }
 
 /*
@@ -3116,7 +3176,8 @@ err:
  * by two NULs.
 */
 
-static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
+static int brcmf_process_nvram_vars(struct brcmf_sdio *bus,
+				    const struct firmware *nv)
 {
 	char *varbuf;
 	char *dp;
@@ -3125,12 +3186,12 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
 	int ret = 0;
 	uint buf_len, n, len;
 
-	len = bus->firmware->size;
+	len = nv->size;
 	varbuf = vmalloc(len);
 	if (!varbuf)
 		return -ENOMEM;
 
-	memcpy(varbuf, bus->firmware->data, len);
+	memcpy(varbuf, nv->data, len);
 	dp = varbuf;
 
 	findNewline = false;
@@ -3182,18 +3243,16 @@ err:
 
 static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
 {
+	const struct firmware *nv;
 	int ret;
 
-	ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
-			       &bus->sdiodev->func[2]->dev);
-	if (ret) {
-		brcmf_err("Fail to request nvram %d\n", ret);
-		return ret;
-	}
+	nv = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
+	if (nv == NULL)
+		return -ENOENT;
 
-	ret = brcmf_process_nvram_vars(bus);
+	ret = brcmf_process_nvram_vars(bus, nv);
 
-	release_firmware(bus->firmware);
+	release_firmware(nv);
 
 	return ret;
 }
-- 
1.7.10.4



^ permalink raw reply related

* Re: [PATCH] ti-connectivity: add wl1251 firmware and license
From: Luca Coelho @ 2013-09-25 11:04 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: ben, Linux Kernel Mailing List, linux-wireless, Pavel Machek
In-Reply-To: <1380033894-5007-1-git-send-email-balbi@ti.com>

Hi dude,

Great, this is cool! Finally! :)

A few comments...


On Tue, 2013-09-24 at 09:44 -0500, Felipe Balbi wrote:
> It's way overdue that we send these firmware
> blobs upstream. Thanks for everybody involved
> in getting this sorted out.
> 
> Cc: Luciano Coelho <luca@coelho.fi>
> Cc: Pavel Machek <pavel@denx.de>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---

The commit message could be a bit more descriptive rather than
narrative?


>  ti-connectivity/license-wl1251.txt |  59 +++++++++++++++++++++++++++++++++++++

The license file should be in the root, together with the other licenses
and called LICENCE.wl1251 (note the en-GB spelling).  Also, this license
is *very* similar to the one for WiLink6/7/8 (LICENCE.ti-connectivity),
except for some very minor things and the formatting.  Couldn't the same
one be used, for the sake of simplicity and consistency?


>  ti-connectivity/wl1251-fw.bin      | Bin 0 -> 194180 bytes
>  ti-connectivity/wl1251-nvs.bin     | Bin 0 -> 752 bytes
>  3 files changed, 59 insertions(+)
>  create mode 100644 ti-connectivity/license-wl1251.txt
>  create mode 100644 ti-connectivity/wl1251-fw.bin
>  create mode 100644 ti-connectivity/wl1251-nvs.bin

When sending big binary blobs, it's generally better to send pull
requests instead of patches.  If you add the -p option when calling git
pull-request, the text will include all the readable parts but will omit
the binary stuff.

Thank you very much for following up on this!

--
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 08/13] ath10k: bring back the WMI path for mgmt frames
From: Michal Kazior @ 2013-09-25 10:46 UTC (permalink / raw)
  To: Bartosz Markowski; +Cc: ath10k, linux-wireless
In-Reply-To: <1380101891-18312-9-git-send-email-bartosz.markowski@tieto.com>

On 25 September 2013 11:38, Bartosz Markowski
<bartosz.markowski@tieto.com> wrote:
> @@ -1497,16 +1497,23 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
>                 goto exit;
>         }
>
> -       if (ieee80211_is_mgmt(hdr->frame_control))
> -               ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
> -       else if (ieee80211_is_nullfunc(hdr->frame_control))
> +       if (ieee80211_is_mgmt(hdr->frame_control)) {
> +               if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
> +                            ar->fw_features))
> +                       ret = ath10k_wmi_mgmt_tx(ar, skb);

Due to recent changes (WMI commands can block/sleep) this cannot be
so. ath10k_tx_htt() is called from an atomic context.

I'm seeing 2 aproaches here:
 a) management frame queue,
 b) use ieee80211_{stop,wake}_queues()

I'm worried (b) could degrade throughput. WMI endpoint has only 2 HTC
credits meaning management frame bursts will lock out data frame tx.


Michał.

^ permalink raw reply

* Re: [PATCH 12/13] ath10k: introduce dynamic pdev parameters
From: Michal Kazior @ 2013-09-25 10:39 UTC (permalink / raw)
  To: Bartosz Markowski; +Cc: ath10k, linux-wireless
In-Reply-To: <1380101891-18312-13-git-send-email-bartosz.markowski@tieto.com>

On 25 September 2013 11:38, Bartosz Markowski
<bartosz.markowski@tieto.com> wrote:
> +struct wmi_pdev_param_map {
> +       u32 wmi_pdev_param_tx_chain_mask;
> +       u32 wmi_pdev_param_rx_chain_mask;
> +       u32 wmi_pdev_param_txpower_limit2g;
> +       u32 wmi_pdev_param_txpower_limit5g;
> +       u32 wmi_pdev_param_txpower_scale;
> +       u32 wmi_pdev_param_beacon_gen_mode;
> +       u32 wmi_pdev_param_beacon_tx_mode;
> +       u32 wmi_pdev_param_resmgr_offchan_mode;
> +       u32 wmi_pdev_param_protection_mode;
> +       u32 wmi_pdev_param_dynamic_bw;
> +       u32 wmi_pdev_param_non_agg_sw_retry_th;
> +       u32 wmi_pdev_param_agg_sw_retry_th;
> +       u32 wmi_pdev_param_sta_kickout_th;
> +       u32 wmi_pdev_param_ac_aggrsize_scaling;
> +       u32 wmi_pdev_param_ltr_enable;
> +       u32 wmi_pdev_param_ltr_ac_latency_be;
> +       u32 wmi_pdev_param_ltr_ac_latency_bk;
> +       u32 wmi_pdev_param_ltr_ac_latency_vi;
> +       u32 wmi_pdev_param_ltr_ac_latency_vo;
> +       u32 wmi_pdev_param_ltr_ac_latency_timeout;
> +       u32 wmi_pdev_param_ltr_sleep_override;
> +       u32 wmi_pdev_param_ltr_rx_override;
> +       u32 wmi_pdev_param_ltr_tx_activity_timeout;
> +       u32 wmi_pdev_param_l1ss_enable;
> +       u32 wmi_pdev_param_dsleep_enable;
> +       u32 wmi_pdev_param_pcielp_txbuf_flush;
> +       u32 wmi_pdev_param_pcielp_txbuf_watermark;
> +       u32 wmi_pdev_param_pcielp_txbuf_tmo_en;
> +       u32 wmi_pdev_param_pcielp_txbuf_tmo_value;
> +       u32 wmi_pdev_param_pdev_stats_update_period;
> +       u32 wmi_pdev_param_vdev_stats_update_period;
> +       u32 wmi_pdev_param_peer_stats_update_period;
> +       u32 wmi_pdev_param_bcnflt_stats_update_period;
> +       u32 wmi_pdev_param_pmf_qos;
> +       u32 wmi_pdev_param_arp_ac_override;
> +       u32 wmi_pdev_param_arpdhcp_ac_override;
> +       u32 wmi_pdev_param_dcs;
> +       u32 wmi_pdev_param_ani_enable;
> +       u32 wmi_pdev_param_ani_poll_period;
> +       u32 wmi_pdev_param_ani_listen_period;
> +       u32 wmi_pdev_param_ani_ofdm_level;
> +       u32 wmi_pdev_param_ani_cck_level;
> +       u32 wmi_pdev_param_dyntxchain;
> +       u32 wmi_pdev_param_proxy_sta;
> +       u32 wmi_pdev_param_idle_ps_config;
> +       u32 wmi_pdev_param_power_gating_sleep;
> +       u32 wmi_pdev_param_fast_channel_reset;
> +       u32 wmi_pdev_param_burst_dur;
> +       u32 wmi_pdev_param_burst_enable;

Same as per vdev_param patch. I think there's no need for the
extraneous `wmi_pdev_param_`.


Michał.

^ permalink raw reply

* Re: [PATCH 11/13] ath10k: introduce dynamic vdev parameters
From: Michal Kazior @ 2013-09-25 10:38 UTC (permalink / raw)
  To: Bartosz Markowski; +Cc: ath10k, linux-wireless
In-Reply-To: <1380101891-18312-12-git-send-email-bartosz.markowski@tieto.com>

On 25 September 2013 11:38, Bartosz Markowski
<bartosz.markowski@tieto.com> wrote:
> +struct wmi_vdev_param_map {
> +       u32 wmi_vdev_param_rts_threshold;
> +       u32 wmi_vdev_param_fragmentation_threshold;
> +       u32 wmi_vdev_param_beacon_interval;
> +       u32 wmi_vdev_param_listen_interval;
> +       u32 wmi_vdev_param_multicast_rate;
> +       u32 wmi_vdev_param_mgmt_tx_rate;
> +       u32 wmi_vdev_param_slot_time;
> +       u32 wmi_vdev_param_preamble;
> +       u32 wmi_vdev_param_swba_time;
> +       u32 wmi_vdev_stats_update_period;
> +       u32 wmi_vdev_pwrsave_ageout_time;
> +       u32 wmi_vdev_host_swba_interval;
> +       u32 wmi_vdev_param_dtim_period;
> +       u32 wmi_vdev_oc_scheduler_air_time_limit;
> +       u32 wmi_vdev_param_wds;
> +       u32 wmi_vdev_param_atim_window;
> +       u32 wmi_vdev_param_bmiss_count_max;
> +       u32 wmi_vdev_param_bmiss_first_bcnt;
> +       u32 wmi_vdev_param_bmiss_final_bcnt;
> +       u32 wmi_vdev_param_feature_wmm;
> +       u32 wmi_vdev_param_chwidth;
> +       u32 wmi_vdev_param_chextoffset;
> +       u32 wmi_vdev_param_disable_htprotection;
> +       u32 wmi_vdev_param_sta_quickkickout;
> +       u32 wmi_vdev_param_mgmt_rate;
> +       u32 wmi_vdev_param_protection_mode;
> +       u32 wmi_vdev_param_fixed_rate;
> +       u32 wmi_vdev_param_sgi;
> +       u32 wmi_vdev_param_ldpc;
> +       u32 wmi_vdev_param_tx_stbc;
> +       u32 wmi_vdev_param_rx_stbc;
> +       u32 wmi_vdev_param_intra_bss_fwd;
> +       u32 wmi_vdev_param_def_keyid;
> +       u32 wmi_vdev_param_nss;
> +       u32 wmi_vdev_param_bcast_data_rate;
> +       u32 wmi_vdev_param_mcast_data_rate;
> +       u32 wmi_vdev_param_mcast_indicate;
> +       u32 wmi_vdev_param_dhcp_indicate;
> +       u32 wmi_vdev_param_unknown_dest_indicate;
> +       u32 wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs;
> +       u32 wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs;
> +       u32 wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs;
> +       u32 wmi_vdev_param_ap_enable_nawds;
> +       u32 wmi_vdev_param_mcast2ucast_set;
> +       u32 wmi_vdev_param_enable_rtscts;
> +       u32 wmi_vdev_param_txbf;
> +       u32 wmi_vdev_param_packet_powersave;
> +       u32 wmi_vdev_param_drop_unencry;
> +       u32 wmi_vdev_param_tx_encap_type;
> +       u32 wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs;

I don't think `wmi_vdev_param_` prefix is necessary here. Structure
already provides a prefix on it's own.


Michał.

^ permalink raw reply

* Re: [PATCH 01/13] ath10k: introduce dynamic WMI structures
From: Michal Kazior @ 2013-09-25 10:38 UTC (permalink / raw)
  To: Bartosz Markowski; +Cc: ath10k, linux-wireless
In-Reply-To: <1380101891-18312-2-git-send-email-bartosz.markowski@tieto.com>

On 25 September 2013 11:37, Bartosz Markowski
<bartosz.markowski@tieto.com> wrote:

> +struct wmi_cmd_map {
> +       u32 wmi_init_cmdid;
> +       u32 wmi_start_scan_cmdid;
> +       u32 wmi_stop_scan_cmdid;
> +       u32 wmi_scan_chan_list_cmdid;
> +       u32 wmi_scan_sch_prio_tbl_cmdid;
> +       u32 wmi_pdev_set_regdomain_cmdid;
> +       u32 wmi_pdev_set_channel_cmdid;
> +       u32 wmi_pdev_set_param_cmdid;
> +       u32 wmi_pdev_pktlog_enable_cmdid;
> +       u32 wmi_pdev_pktlog_disable_cmdid;
> +       u32 wmi_pdev_set_wmm_params_cmdid;
> +       u32 wmi_pdev_set_ht_cap_ie_cmdid;
> +       u32 wmi_pdev_set_vht_cap_ie_cmdid;
> +       u32 wmi_pdev_set_dscp_tid_map_cmdid;
> +       u32 wmi_pdev_set_quiet_mode_cmdid;
> +       u32 wmi_pdev_green_ap_ps_enable_cmdid;
> +       u32 wmi_pdev_get_tpc_config_cmdid;
> +       u32 wmi_pdev_set_base_macaddr_cmdid;
> +       u32 wmi_vdev_create_cmdid;
> +       u32 wmi_vdev_delete_cmdid;
> +       u32 wmi_vdev_start_request_cmdid;
> +       u32 wmi_vdev_restart_request_cmdid;
> +       u32 wmi_vdev_up_cmdid;
> +       u32 wmi_vdev_stop_cmdid;
> +       u32 wmi_vdev_down_cmdid;
> +       u32 wmi_vdev_set_param_cmdid;
> +       u32 wmi_vdev_install_key_cmdid;
> +       u32 wmi_peer_create_cmdid;
> +       u32 wmi_peer_delete_cmdid;
> +       u32 wmi_peer_flush_tids_cmdid;
> +       u32 wmi_peer_set_param_cmdid;
> +       u32 wmi_peer_assoc_cmdid;
> +       u32 wmi_peer_add_wds_entry_cmdid;
> +       u32 wmi_peer_remove_wds_entry_cmdid;
> +       u32 wmi_peer_mcast_group_cmdid;
> +       u32 wmi_bcn_tx_cmdid;
> +       u32 wmi_pdev_send_bcn_cmdid;
> +       u32 wmi_bcn_tmpl_cmdid;
> +       u32 wmi_bcn_filter_rx_cmdid;
> +       u32 wmi_prb_req_filter_rx_cmdid;
> +       u32 wmi_mgmt_tx_cmdid;
> +       u32 wmi_prb_tmpl_cmdid;
> +       u32 wmi_addba_clear_resp_cmdid;
> +       u32 wmi_addba_send_cmdid;
> +       u32 wmi_addba_status_cmdid;
> +       u32 wmi_delba_send_cmdid;
> +       u32 wmi_addba_set_resp_cmdid;
> +       u32 wmi_send_singleamsdu_cmdid;
> +       u32 wmi_sta_powersave_mode_cmdid;
> +       u32 wmi_sta_powersave_param_cmdid;
> +       u32 wmi_sta_mimo_ps_mode_cmdid;
> +       u32 wmi_pdev_dfs_enable_cmdid;
> +       u32 wmi_pdev_dfs_disable_cmdid;
> +       u32 wmi_roam_scan_mode;
> +       u32 wmi_roam_scan_rssi_threshold;
> +       u32 wmi_roam_scan_period;
> +       u32 wmi_roam_scan_rssi_change_threshold;
> +       u32 wmi_roam_ap_profile;
> +       u32 wmi_ofl_scan_add_ap_profile;
> +       u32 wmi_ofl_scan_remove_ap_profile;
> +       u32 wmi_ofl_scan_period;
> +       u32 wmi_p2p_dev_set_device_info;
> +       u32 wmi_p2p_dev_set_discoverability;
> +       u32 wmi_p2p_go_set_beacon_ie;
> +       u32 wmi_p2p_go_set_probe_resp_ie;
> +       u32 wmi_p2p_set_vendor_ie_data_cmdid;
> +       u32 wmi_ap_ps_peer_param_cmdid;
> +       u32 wmi_ap_ps_peer_uapsd_coex_cmdid;
> +       u32 wmi_peer_rate_retry_sched_cmdid;
> +       u32 wmi_wlan_profile_trigger_cmdid;
> +       u32 wmi_wlan_profile_set_hist_intvl_cmdid;
> +       u32 wmi_wlan_profile_get_profile_data_cmdid;
> +       u32 wmi_wlan_profile_enable_profile_id_cmdid;
> +       u32 wmi_wlan_profile_list_profile_id_cmdid;
> +       u32 wmi_pdev_suspend_cmdid;
> +       u32 wmi_pdev_resume_cmdid;
> +       u32 wmi_add_bcn_filter_cmdid;
> +       u32 wmi_rmv_bcn_filter_cmdid;
> +       u32 wmi_wow_add_wake_pattern_cmdid;
> +       u32 wmi_wow_del_wake_pattern_cmdid;
> +       u32 wmi_wow_enable_disable_wake_event_cmdid;
> +       u32 wmi_wow_enable_cmdid;
> +       u32 wmi_wow_hostwakeup_from_sleep_cmdid;
> +       u32 wmi_rtt_measreq_cmdid;
> +       u32 wmi_rtt_tsf_cmdid;
> +       u32 wmi_vdev_spectral_scan_configure_cmdid;
> +       u32 wmi_vdev_spectral_scan_enable_cmdid;
> +       u32 wmi_request_stats_cmdid;
> +       u32 wmi_set_arp_ns_offload_cmdid;
> +       u32 wmi_network_list_offload_config_cmdid;
> +       u32 wmi_gtk_offload_cmdid;
> +       u32 wmi_csa_offload_enable_cmdid;
> +       u32 wmi_csa_offload_chanswitch_cmdid;
> +       u32 wmi_chatter_set_mode_cmdid;
> +       u32 wmi_peer_tid_addba_cmdid;
> +       u32 wmi_peer_tid_delba_cmdid;
> +       u32 wmi_sta_dtim_ps_method_cmdid;
> +       u32 wmi_sta_uapsd_auto_trig_cmdid;
> +       u32 wmi_sta_keepalive_cmd;
> +       u32 wmi_echo_cmdid;
> +       u32 wmi_pdev_utf_cmdid;
> +       u32 wmi_dbglog_cfg_cmdid;
> +       u32 wmi_pdev_qvit_cmdid;
> +       u32 wmi_pdev_ftm_intg_cmdid;
> +       u32 wmi_vdev_set_keepalive_cmdid;
> +       u32 wmi_vdev_get_keepalive_cmdid;
> +       u32 wmi_force_fw_hang_cmdid;
> +       u32 wmi_gpio_config_cmdid;
> +       u32 wmi_gpio_output_cmdid;

I don't think the `wmi_` prefix is necessary here. Structure itself
already provides a prefix.


Michał.

^ permalink raw reply

* [PATCH for-3.12 1/3] brcmfmac: obtain platform data upon module initialization
From: Arend van Spriel @ 2013-09-25 10:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, stable
In-Reply-To: <1380103864-10447-1-git-send-email-arend@broadcom.com>

The driver uses platform_driver_probe() to obtain platform data
if any. However, that function is placed in the .init section so
it must be called upon driver module initialization.

The problem was reported by Fenguang Wu resulting in a kernel
oops because the .init section was already freed.

[   48.966342] Switched to clocksource tsc
[   48.970002] kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
[   48.970851] BUG: unable to handle kernel paging request at ffffffff82196446
[   48.970957] IP: [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957] PGD 1e76067 PUD 1e77063 PMD f388063 PTE 8000000002196163
[   48.970957] Oops: 0011 [#1]
[   48.970957] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 3.11.0-rc7-00444-gc52dd7f #23
[   48.970957] Workqueue: events brcmf_driver_init
[   48.970957] task: ffff8800001d2000 ti: ffff8800001d4000 task.ti: ffff8800001d4000
[   48.970957] RIP: 0010:[<ffffffff82196446>]  [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957] RSP: 0000:ffff8800001d5d40  EFLAGS: 00000286
[   48.970957] RAX: 0000000000000001 RBX: ffffffff820c5620 RCX: 0000000000000000
[   48.970957] RDX: 0000000000000001 RSI: ffffffff816f7380 RDI: ffffffff820c56c0
[   48.970957] RBP: ffff8800001d5d50 R08: ffff8800001d2508 R09: 0000000000000002
[   48.970957] R10: 0000000000000000 R11: 0001f7ce298c5620 R12: ffff8800001c76b0
[   48.970957] R13: ffffffff81e91d40 R14: 0000000000000000 R15: ffff88000e0ce300
[   48.970957] FS:  0000000000000000(0000) GS:ffffffff81e84000(0000) knlGS:0000000000000000
[   48.970957] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   48.970957] CR2: ffffffff82196446 CR3: 0000000001e75000 CR4: 00000000000006b0
[   48.970957] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   48.970957] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000
[   48.970957] Stack:
[   48.970957]  ffffffff816f7df8 ffffffff820c5620 ffff8800001d5d60 ffffffff816eeec9
[   48.970957]  ffff8800001d5de0 ffffffff81073dc5 ffffffff81073d68 ffff8800001d5db8
[   48.970957]  0000000000000086 ffffffff820c5620 ffffffff824f7fd0 0000000000000000
[   48.970957] Call Trace:
[   48.970957]  [<ffffffff816f7df8>] ? brcmf_sdio_init+0x18/0x70
[   48.970957]  [<ffffffff816eeec9>] brcmf_driver_init+0x9/0x10
[   48.970957]  [<ffffffff81073dc5>] process_one_work+0x1d5/0x480
[   48.970957]  [<ffffffff81073d68>] ? process_one_work+0x178/0x480
[   48.970957]  [<ffffffff81074188>] worker_thread+0x118/0x3a0
[   48.970957]  [<ffffffff81074070>] ? process_one_work+0x480/0x480
[   48.970957]  [<ffffffff8107aa17>] kthread+0xe7/0xf0
[   48.970957]  [<ffffffff810829f7>] ? finish_task_switch.constprop.57+0x37/0xd0
[   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
[   48.970957]  [<ffffffff81a6923a>] ret_from_fork+0x7a/0xb0
[   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
[   48.970957] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc cc cc <cc> cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
[   48.970957] RIP  [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957]  RSP <ffff8800001d5d40>
[   48.970957] CR2: ffffffff82196446
[   48.970957] ---[ end trace 62980817cd525f14 ]---

Cc: <stable@vger.kernel.org> # 3.10.x, 3.11.x
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Tested-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   28 +++++++++-----------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    3 ++-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   14 +++++-----
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    2 +-
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 64f4a2b..c3462b7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -464,8 +464,6 @@ static struct sdio_driver brcmf_sdmmc_driver = {
 
 static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 {
-	int ret;
-
 	brcmf_dbg(SDIO, "Enter\n");
 
 	brcmfmac_sdio_pdata = pdev->dev.platform_data;
@@ -473,11 +471,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 	if (brcmfmac_sdio_pdata->power_on)
 		brcmfmac_sdio_pdata->power_on();
 
-	ret = sdio_register_driver(&brcmf_sdmmc_driver);
-	if (ret)
-		brcmf_err("sdio_register_driver failed: %d\n", ret);
-
-	return ret;
+	return 0;
 }
 
 static int brcmf_sdio_pd_remove(struct platform_device *pdev)
@@ -500,6 +494,15 @@ static struct platform_driver brcmf_sdio_pd = {
 	}
 };
 
+void brcmf_sdio_register(void)
+{
+	int ret;
+
+	ret = sdio_register_driver(&brcmf_sdmmc_driver);
+	if (ret)
+		brcmf_err("sdio_register_driver failed: %d\n", ret);
+}
+
 void brcmf_sdio_exit(void)
 {
 	brcmf_dbg(SDIO, "Enter\n");
@@ -510,18 +513,13 @@ void brcmf_sdio_exit(void)
 		sdio_unregister_driver(&brcmf_sdmmc_driver);
 }
 
-void brcmf_sdio_init(void)
+void __init brcmf_sdio_init(void)
 {
 	int ret;
 
 	brcmf_dbg(SDIO, "Enter\n");
 
 	ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
-	if (ret == -ENODEV) {
-		brcmf_dbg(SDIO, "No platform data available, registering without.\n");
-		ret = sdio_register_driver(&brcmf_sdmmc_driver);
-	}
-
-	if (ret)
-		brcmf_err("driver registration failed: %d\n", ret);
+	if (ret == -ENODEV)
+		brcmf_dbg(SDIO, "No platform data available.\n");
 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index f7c1985..74156f8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -156,10 +156,11 @@ extern int brcmf_bus_start(struct device *dev);
 #ifdef CONFIG_BRCMFMAC_SDIO
 extern void brcmf_sdio_exit(void);
 extern void brcmf_sdio_init(void);
+extern void brcmf_sdio_register(void);
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
 extern void brcmf_usb_exit(void);
-extern void brcmf_usb_init(void);
+extern void brcmf_usb_register(void);
 #endif
 
 #endif				/* _BRCMF_BUS_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index e067aec..40e7f85 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1231,21 +1231,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
 	return bus->chip << 4 | bus->chiprev;
 }
 
-static void brcmf_driver_init(struct work_struct *work)
+static void brcmf_driver_register(struct work_struct *work)
 {
-	brcmf_debugfs_init();
-
 #ifdef CONFIG_BRCMFMAC_SDIO
-	brcmf_sdio_init();
+	brcmf_sdio_register();
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
-	brcmf_usb_init();
+	brcmf_usb_register();
 #endif
 }
-static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
+static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
 
 static int __init brcmfmac_module_init(void)
 {
+	brcmf_debugfs_init();
+#ifdef CONFIG_BRCMFMAC_SDIO
+	brcmf_sdio_init();
+#endif
 	if (!schedule_work(&brcmf_driver_work))
 		return -EBUSY;
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 39e01a7..f4aea47 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1539,7 +1539,7 @@ void brcmf_usb_exit(void)
 	brcmf_release_fw(&fw_image_list);
 }
 
-void brcmf_usb_init(void)
+void brcmf_usb_register(void)
 {
 	brcmf_dbg(USB, "Enter\n");
 	INIT_LIST_HEAD(&fw_image_list);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH for-3.12 3/3] brcmsmac: call bcma_core_pci_power_save() from non-atomic context
From: Arend van Spriel @ 2013-09-25 10:11 UTC (permalink / raw)
  To: John W. Linville
  Cc: linux-wireless, Arend van Spriel, stable, Tod Jackson,
	Joe Perches, Rafal Milecki, Hauke Mehrtens
In-Reply-To: <1380103864-10447-1-git-send-email-arend@broadcom.com>

This patch adds explicit call to bcma_core_pci_power_save() from
a non-atomic context resolving 'scheduling while atomic' issue.

[   13.224317] BUG: scheduling while atomic: dhcpcd/1800/0x00000202
[   13.224322] Modules linked in: brcmsmac nouveau coretemp kvm_intel kvm cordic brcmutil bcma dell_wmi atl1c ttm mxm_wmi wmi
[   13.224354] CPU: 0 PID: 1800 Comm: dhcpcd Tainted: G        W    3.11.0-wl #1
[   13.224359] Hardware name: Alienware M11x R2/M11x R2, BIOS A04 11/23/2010
[   13.224363]  ffff880177c12c40 ffff880170fd1968 ffffffff8169af5b 0000000000000007
[   13.224374]  ffff880170fd1ad0 ffff880170fd1978 ffffffff81697ee2 ffff880170fd19f8
[   13.224383]  ffffffff816a19f5 00000000000f4240 000000000000d080 ffff880170fd1fd8
[   13.224391] Call Trace:
[   13.224399]  [<ffffffff8169af5b>] dump_stack+0x4f/0x84
[   13.224403]  [<ffffffff81697ee2>] __schedule_bug+0x43/0x51
[   13.224409]  [<ffffffff816a19f5>] __schedule+0x6e5/0x810
[   13.224412]  [<ffffffff816a1c34>] schedule+0x24/0x70
[   13.224416]  [<ffffffff816a04fc>] schedule_hrtimeout_range_clock+0x10c/0x150
[   13.224420]  [<ffffffff810684e0>] ? update_rmtp+0x60/0x60
[   13.224424]  [<ffffffff8106915f>] ? hrtimer_start_range_ns+0xf/0x20
[   13.224429]  [<ffffffff816a054e>] schedule_hrtimeout_range+0xe/0x10
[   13.224432]  [<ffffffff8104f6fb>] usleep_range+0x3b/0x40
[   13.224437]  [<ffffffffa003733a>] bcma_pcie_mdio_read.isra.5+0x8a/0x100 [bcma]
[   13.224442]  [<ffffffffa00374a5>] bcma_pcie_mdio_writeread.isra.6.constprop.13+0x25/0x30 [bcma]
[   13.224448]  [<ffffffffa00374f9>] bcma_core_pci_power_save+0x49/0x80 [bcma]
[   13.224452]  [<ffffffffa003765d>] bcma_core_pci_up+0x2d/0x60 [bcma]
[   13.224460]  [<ffffffffa03dc17c>] brcms_c_up+0xfc/0x430 [brcmsmac]
[   13.224467]  [<ffffffffa03d1a7d>] brcms_up+0x1d/0x20 [brcmsmac]
[   13.224473]  [<ffffffffa03d2498>] brcms_ops_start+0x298/0x340 [brcmsmac]
[   13.224478]  [<ffffffff81600a12>] ? cfg80211_netdev_notifier_call+0xd2/0x5f0
[   13.224483]  [<ffffffff815fa53d>] ? packet_notifier+0xad/0x1d0
[   13.224487]  [<ffffffff81656e75>] ieee80211_do_open+0x325/0xf80
[   13.224491]  [<ffffffff8106ac09>] ? __raw_notifier_call_chain+0x9/0x10
[   13.224495]  [<ffffffff81657b41>] ieee80211_open+0x71/0x80
[   13.224498]  [<ffffffff81526267>] __dev_open+0x87/0xe0
[   13.224502]  [<ffffffff8152650c>] __dev_change_flags+0x9c/0x180
[   13.224505]  [<ffffffff815266a3>] dev_change_flags+0x23/0x70
[   13.224509]  [<ffffffff8158cd68>] devinet_ioctl+0x5b8/0x6a0
[   13.224512]  [<ffffffff8158d5c5>] inet_ioctl+0x75/0x90
[   13.224516]  [<ffffffff8150b38b>] sock_do_ioctl+0x2b/0x70
[   13.224519]  [<ffffffff8150b681>] sock_ioctl+0x71/0x2a0
[   13.224523]  [<ffffffff8114ed47>] do_vfs_ioctl+0x87/0x520
[   13.224528]  [<ffffffff8113f159>] ? ____fput+0x9/0x10
[   13.224533]  [<ffffffff8106228c>] ? task_work_run+0x9c/0xd0
[   13.224537]  [<ffffffff8114f271>] SyS_ioctl+0x91/0xb0
[   13.224541]  [<ffffffff816aa252>] system_call_fastpath+0x16/0x1b

Cc: <stable@vger.kernel.org> # 3.11.x
Cc: Tod Jackson <tod.jackson@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Rafal Milecki <zajec5@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 3a65447..edc5d10 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -457,6 +457,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
 	if (err != 0)
 		brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n",
 			  __func__, err);
+
+	bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, true);
 	return err;
 }
 
@@ -479,6 +481,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw)
 		return;
 	}
 
+	bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, false);
+
 	/* put driver in down state */
 	spin_lock_bh(&wl->lock);
 	brcms_down(wl);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH for-3.12 0/3] brcm80211: fixes for reported issues
From: Arend van Spriel @ 2013-09-25 10:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series contains a couple of fixes that have been reported by
users/developers.

This series is intended for v3.12 and applies to the master branch
of the wireless repository.

Regards,
Arend

Arend van Spriel (3):
  brcmfmac: obtain platform data upon module initialization
  bcma: make bcma_core_pci_{up,down}() callable from atomic context
  brcmsmac: call bcma_core_pci_power_save() from non-atomic context

 drivers/bcma/driver_pci.c                          |   49 +++++++++++---------
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   28 ++++++-----
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    3 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   14 +++---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    2 +-
 .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |    4 ++
 include/linux/bcma/bcma_driver_pci.h               |    1 +
 7 files changed, 55 insertions(+), 46 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH for-3.12 2/3] bcma: make bcma_core_pci_{up,down}() callable from atomic context
From: Arend van Spriel @ 2013-09-25 10:11 UTC (permalink / raw)
  To: John W. Linville
  Cc: linux-wireless, Arend van Spriel, stable, Tod Jackson,
	Joe Perches, Rafal Milecki, Hauke Mehrtens
In-Reply-To: <1380103864-10447-1-git-send-email-arend@broadcom.com>

This patch removes the bcma_core_pci_power_save() call from
the bcma_core_pci_{up,down}() functions as it tries to schedule
thus requiring to call them from non-atomic context. The function
bcma_core_pci_power_save() is now exported so the calling module
can explicitly use it in non-atomic context. This fixes the
'scheduling while atomic' issue reported by Tod Jackson and
Joe Perches.

[   13.210710] BUG: scheduling while atomic: dhcpcd/1800/0x00000202
[   13.210718] Modules linked in: brcmsmac nouveau coretemp kvm_intel kvm cordic brcmutil bcma dell_wmi atl1c ttm mxm_wmi wmi
[   13.210756] CPU: 2 PID: 1800 Comm: dhcpcd Not tainted 3.11.0-wl #1
[   13.210762] Hardware name: Alienware M11x R2/M11x R2, BIOS A04 11/23/2010
[   13.210767]  ffff880177c92c40 ffff880170fd1948 ffffffff8169af5b 0000000000000007
[   13.210777]  ffff880170fd1ab0 ffff880170fd1958 ffffffff81697ee2 ffff880170fd19d8
[   13.210785]  ffffffff816a19f5 00000000000f4240 000000000000d080 ffff880170fd1fd8
[   13.210794] Call Trace:
[   13.210813]  [<ffffffff8169af5b>] dump_stack+0x4f/0x84
[   13.210826]  [<ffffffff81697ee2>] __schedule_bug+0x43/0x51
[   13.210837]  [<ffffffff816a19f5>] __schedule+0x6e5/0x810
[   13.210845]  [<ffffffff816a1c34>] schedule+0x24/0x70
[   13.210855]  [<ffffffff816a04fc>] schedule_hrtimeout_range_clock+0x10c/0x150
[   13.210867]  [<ffffffff810684e0>] ? update_rmtp+0x60/0x60
[   13.210877]  [<ffffffff8106915f>] ? hrtimer_start_range_ns+0xf/0x20
[   13.210887]  [<ffffffff816a054e>] schedule_hrtimeout_range+0xe/0x10
[   13.210897]  [<ffffffff8104f6fb>] usleep_range+0x3b/0x40
[   13.210910]  [<ffffffffa00371af>] bcma_pcie_mdio_set_phy.isra.3+0x4f/0x80 [bcma]
[   13.210921]  [<ffffffffa003729f>] bcma_pcie_mdio_write.isra.4+0xbf/0xd0 [bcma]
[   13.210932]  [<ffffffffa0037498>] bcma_pcie_mdio_writeread.isra.6.constprop.13+0x18/0x30 [bcma]
[   13.210942]  [<ffffffffa00374ee>] bcma_core_pci_power_save+0x3e/0x80 [bcma]
[   13.210953]  [<ffffffffa003765d>] bcma_core_pci_up+0x2d/0x60 [bcma]
[   13.210975]  [<ffffffffa03dc17c>] brcms_c_up+0xfc/0x430 [brcmsmac]
[   13.210989]  [<ffffffffa03d1a7d>] brcms_up+0x1d/0x20 [brcmsmac]
[   13.211003]  [<ffffffffa03d2498>] brcms_ops_start+0x298/0x340 [brcmsmac]
[   13.211020]  [<ffffffff81600a12>] ? cfg80211_netdev_notifier_call+0xd2/0x5f0
[   13.211030]  [<ffffffff815fa53d>] ? packet_notifier+0xad/0x1d0
[   13.211064]  [<ffffffff81656e75>] ieee80211_do_open+0x325/0xf80
[   13.211076]  [<ffffffff8106ac09>] ? __raw_notifier_call_chain+0x9/0x10
[   13.211086]  [<ffffffff81657b41>] ieee80211_open+0x71/0x80
[   13.211101]  [<ffffffff81526267>] __dev_open+0x87/0xe0
[   13.211109]  [<ffffffff8152650c>] __dev_change_flags+0x9c/0x180
[   13.211117]  [<ffffffff815266a3>] dev_change_flags+0x23/0x70
[   13.211127]  [<ffffffff8158cd68>] devinet_ioctl+0x5b8/0x6a0
[   13.211136]  [<ffffffff8158d5c5>] inet_ioctl+0x75/0x90
[   13.211147]  [<ffffffff8150b38b>] sock_do_ioctl+0x2b/0x70
[   13.211155]  [<ffffffff8150b681>] sock_ioctl+0x71/0x2a0
[   13.211169]  [<ffffffff8114ed47>] do_vfs_ioctl+0x87/0x520
[   13.211180]  [<ffffffff8113f159>] ? ____fput+0x9/0x10
[   13.211198]  [<ffffffff8106228c>] ? task_work_run+0x9c/0xd0
[   13.211202]  [<ffffffff8114f271>] SyS_ioctl+0x91/0xb0
[   13.211208]  [<ffffffff816aa252>] system_call_fastpath+0x16/0x1b
[   13.211217] NOHZ: local_softirq_pending 202

The issue was introduced in v3.11 kernel by following commit:

commit aa51e598d04c6acf5477934cd6383f5a17ce9029
Author: Hauke Mehrtens <hauke@hauke-m.de>
Date:   Sat Aug 24 00:32:31 2013 +0200

    brcmsmac: use bcma PCIe up and down functions

    replace the calls to bcma_core_pci_extend_L1timer() by calls to the
    newly introduced bcma_core_pci_ip() and bcma_core_pci_down()

    Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
    Cc: Arend van Spriel <arend@broadcom.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

This fix has been discussed with Hauke Mehrtens [1] selection
option 3) and is intended for v3.12.

Ref:
[1] http://mid.gmane.org/5239B12D.3040206@hauke-m.de

Cc: <stable@vger.kernel.org> # 3.11.x
Cc: Tod Jackson <tod.jackson@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Rafal Milecki <zajec5@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/bcma/driver_pci.c            |   49 ++++++++++++++++++----------------
 include/linux/bcma/bcma_driver_pci.h |    1 +
 2 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index c9fd694..50329d1 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -210,25 +210,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
 	}
 }
 
-static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up)
-{
-	u16 data;
-
-	if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
-		data = up ? 0x74 : 0x7C;
-		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
-					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
-		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
-					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
-	} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
-		data = up ? 0x75 : 0x7D;
-		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
-					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
-		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
-					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
-	}
-}
-
 /**************************************************
  * Init.
  **************************************************/
@@ -255,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
 		bcma_core_pci_clientmode_init(pc);
 }
 
+void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
+{
+	struct bcma_drv_pci *pc;
+	u16 data;
+
+	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
+		return;
+
+	pc = &bus->drv_pci[0];
+
+	if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
+		data = up ? 0x74 : 0x7C;
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
+	} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
+		data = up ? 0x75 : 0x7D;
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
+	}
+}
+EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
+
 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
 			  bool enable)
 {
@@ -310,8 +317,6 @@ void bcma_core_pci_up(struct bcma_bus *bus)
 
 	pc = &bus->drv_pci[0];
 
-	bcma_core_pci_power_save(pc, true);
-
 	bcma_core_pci_extend_L1timer(pc, true);
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_up);
@@ -326,7 +331,5 @@ void bcma_core_pci_down(struct bcma_bus *bus)
 	pc = &bus->drv_pci[0];
 
 	bcma_core_pci_extend_L1timer(pc, false);
-
-	bcma_core_pci_power_save(pc, false);
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_down);
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index d66033f..0333e60 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -242,6 +242,7 @@ extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
 				 struct bcma_device *core, bool enable);
 extern void bcma_core_pci_up(struct bcma_bus *bus);
 extern void bcma_core_pci_down(struct bcma_bus *bus);
+extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
 
 extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
 extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 12/13] ath10k: introduce dynamic pdev parameters
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

This is done exactly the same way as for vdev.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.h |    1 +
 drivers/net/wireless/ath/ath10k/mac.c  |   13 +--
 drivers/net/wireless/ath/ath10k/wmi.c  |  144 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/wmi.h  |  148 +++++++++++++++++++++++++++++++-
 4 files changed, 297 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index c9ad626..d5e4d55 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -118,6 +118,7 @@ struct ath10k_wmi {
 	wait_queue_head_t tx_credits_wq;
 	struct wmi_cmd_map *cmd;
 	struct wmi_vdev_param_map *vdev_param;
+	struct wmi_pdev_param_map *pdev_param;
 
 	u32 num_mem_chunks;
 	struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS];
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ea11a03..d846594 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1816,6 +1816,7 @@ static int ath10k_start(struct ieee80211_hw *hw)
 {
 	struct ath10k *ar = hw->priv;
 	int ret = 0;
+	u32 pdev_param;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -1845,12 +1846,14 @@ static int ath10k_start(struct ieee80211_hw *hw)
 	else if (ar->state == ATH10K_STATE_RESTARTING)
 		ar->state = ATH10K_STATE_RESTARTED;
 
-	ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1);
+	pdev_param = ar->wmi.pdev_param->wmi_pdev_param_pmf_qos;
+	ret = ath10k_wmi_pdev_set_param(ar, pdev_param, 1);
 	if (ret)
 		ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n",
 			    ret);
 
-	ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_DYNAMIC_BW, 0);
+	pdev_param = ar->wmi.pdev_param->wmi_pdev_param_dynamic_bw;
+	ret = ath10k_wmi_pdev_set_param(ar, pdev_param, 0);
 	if (ret)
 		ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
 			    ret);
@@ -2169,7 +2172,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 	struct ath10k *ar = hw->priv;
 	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
 	int ret = 0;
-	u32 vdev_param;
+	u32 vdev_param, pdev_param;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -2195,8 +2198,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 			   "vdev %d set beacon tx mode to staggered\n",
 			   arvif->vdev_id);
 
-		ret = ath10k_wmi_pdev_set_param(ar,
-						WMI_PDEV_PARAM_BEACON_TX_MODE,
+		pdev_param = ar->wmi.pdev_param->wmi_pdev_param_beacon_tx_mode;
+		ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
 						WMI_BEACON_STAGGERED_MODE);
 		if (ret)
 			ath10k_warn("Failed to set beacon mode for VDEV: %d\n",
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 44ed523..2a55bc8 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -399,6 +399,140 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
 		WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
 };
 
+static struct wmi_pdev_param_map wmi_pdev_param_map = {
+	.wmi_pdev_param_tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK,
+	.wmi_pdev_param_rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK,
+	.wmi_pdev_param_txpower_limit2g = WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
+	.wmi_pdev_param_txpower_limit5g = WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
+	.wmi_pdev_param_txpower_scale = WMI_PDEV_PARAM_TXPOWER_SCALE,
+	.wmi_pdev_param_beacon_gen_mode = WMI_PDEV_PARAM_BEACON_GEN_MODE,
+	.wmi_pdev_param_beacon_tx_mode = WMI_PDEV_PARAM_BEACON_TX_MODE,
+	.wmi_pdev_param_resmgr_offchan_mode =
+					WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
+	.wmi_pdev_param_protection_mode = WMI_PDEV_PARAM_PROTECTION_MODE,
+	.wmi_pdev_param_dynamic_bw = WMI_PDEV_PARAM_DYNAMIC_BW,
+	.wmi_pdev_param_non_agg_sw_retry_th =
+					WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
+	.wmi_pdev_param_agg_sw_retry_th = WMI_PDEV_PARAM_AGG_SW_RETRY_TH,
+	.wmi_pdev_param_sta_kickout_th = WMI_PDEV_PARAM_STA_KICKOUT_TH,
+	.wmi_pdev_param_ac_aggrsize_scaling =
+					WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING,
+	.wmi_pdev_param_ltr_enable = WMI_PDEV_PARAM_LTR_ENABLE,
+	.wmi_pdev_param_ltr_ac_latency_be = WMI_PDEV_PARAM_LTR_AC_LATENCY_BE,
+	.wmi_pdev_param_ltr_ac_latency_bk = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK,
+	.wmi_pdev_param_ltr_ac_latency_vi = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI,
+	.wmi_pdev_param_ltr_ac_latency_vo = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO,
+	.wmi_pdev_param_ltr_ac_latency_timeout =
+					WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
+	.wmi_pdev_param_ltr_sleep_override = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
+	.wmi_pdev_param_ltr_rx_override = WMI_PDEV_PARAM_LTR_RX_OVERRIDE,
+	.wmi_pdev_param_ltr_tx_activity_timeout =
+					WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
+	.wmi_pdev_param_l1ss_enable = WMI_PDEV_PARAM_L1SS_ENABLE,
+	.wmi_pdev_param_dsleep_enable = WMI_PDEV_PARAM_DSLEEP_ENABLE,
+	.wmi_pdev_param_pcielp_txbuf_flush = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
+	.wmi_pdev_param_pcielp_txbuf_watermark =
+					WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
+	.wmi_pdev_param_pcielp_txbuf_tmo_en =
+					WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
+	.wmi_pdev_param_pcielp_txbuf_tmo_value =
+					WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
+	.wmi_pdev_param_pdev_stats_update_period =
+					WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_vdev_stats_update_period =
+					WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_peer_stats_update_period =
+					WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_bcnflt_stats_update_period =
+				WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_pmf_qos = WMI_PDEV_PARAM_PMF_QOS,
+	.wmi_pdev_param_arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
+	.wmi_pdev_param_arpdhcp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_dcs = WMI_PDEV_PARAM_DCS,
+	.wmi_pdev_param_ani_enable = WMI_PDEV_PARAM_ANI_ENABLE,
+	.wmi_pdev_param_ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD,
+	.wmi_pdev_param_ani_listen_period = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
+	.wmi_pdev_param_ani_ofdm_level = WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
+	.wmi_pdev_param_ani_cck_level = WMI_PDEV_PARAM_ANI_CCK_LEVEL,
+	.wmi_pdev_param_dyntxchain = WMI_PDEV_PARAM_DYNTXCHAIN,
+	.wmi_pdev_param_proxy_sta = WMI_PDEV_PARAM_PROXY_STA,
+	.wmi_pdev_param_idle_ps_config = WMI_PDEV_PARAM_IDLE_PS_CONFIG,
+	.wmi_pdev_param_power_gating_sleep = WMI_PDEV_PARAM_POWER_GATING_SLEEP,
+	.wmi_pdev_param_fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_burst_dur = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_burst_enable = WMI_PDEV_PARAM_UNSUPPORTED,
+};
+
+static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
+	.wmi_pdev_param_tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK,
+	.wmi_pdev_param_rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK,
+	.wmi_pdev_param_txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G,
+	.wmi_pdev_param_txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G,
+	.wmi_pdev_param_txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE,
+	.wmi_pdev_param_beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE,
+	.wmi_pdev_param_beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE,
+	.wmi_pdev_param_resmgr_offchan_mode =
+					WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
+	.wmi_pdev_param_protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE,
+	.wmi_pdev_param_dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW,
+	.wmi_pdev_param_non_agg_sw_retry_th =
+					WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
+	.wmi_pdev_param_agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH,
+	.wmi_pdev_param_sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH,
+	.wmi_pdev_param_ac_aggrsize_scaling =
+					WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING,
+	.wmi_pdev_param_ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE,
+	.wmi_pdev_param_ltr_ac_latency_be =
+					WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE,
+	.wmi_pdev_param_ltr_ac_latency_bk =
+					WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK,
+	.wmi_pdev_param_ltr_ac_latency_vi =
+					WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI,
+	.wmi_pdev_param_ltr_ac_latency_vo =
+					WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO,
+	.wmi_pdev_param_ltr_ac_latency_timeout =
+				WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
+	.wmi_pdev_param_ltr_sleep_override =
+					WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
+	.wmi_pdev_param_ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE,
+	.wmi_pdev_param_ltr_tx_activity_timeout =
+				WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
+	.wmi_pdev_param_l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE,
+	.wmi_pdev_param_dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE,
+	.wmi_pdev_param_pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_pdev_stats_update_period =
+				WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_vdev_stats_update_period =
+				WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_peer_stats_update_period =
+				WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_bcnflt_stats_update_period =
+				WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
+	.wmi_pdev_param_pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
+	.wmi_pdev_param_arp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_arpdhcp_ac_override =
+					WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
+	.wmi_pdev_param_dcs = WMI_10X_PDEV_PARAM_DCS,
+	.wmi_pdev_param_ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
+	.wmi_pdev_param_ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
+	.wmi_pdev_param_ani_listen_period =
+					WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD,
+	.wmi_pdev_param_ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL,
+	.wmi_pdev_param_ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL,
+	.wmi_pdev_param_dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN,
+	.wmi_pdev_param_proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED,
+	.wmi_pdev_param_fast_channel_reset =
+					WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
+	.wmi_pdev_param_burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR,
+	.wmi_pdev_param_burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE,
+
+};
+
 int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
 {
 	int ret;
@@ -1886,10 +2020,12 @@ int ath10k_wmi_attach(struct ath10k *ar)
 		ath10k_warn("Firmware 10.X is not yet supported\n");
 		ar->wmi.cmd = &wmi_10x_cmd_map;
 		ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
+		ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
 		ret = -ENOTSUPP;
 	} else {
 		ar->wmi.cmd = &wmi_cmd_map;
 		ar->wmi.vdev_param = &wmi_vdev_param_map;
+		ar->wmi.pdev_param = &wmi_pdev_param_map;
 		ret = 0;
 	}
 
@@ -2027,12 +2163,16 @@ int ath10k_wmi_pdev_resume_target(struct ath10k *ar)
 				   ar->wmi.cmd->wmi_pdev_resume_cmdid);
 }
 
-int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id,
-			      u32 value)
+int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
 {
 	struct wmi_pdev_set_param_cmd *cmd;
 	struct sk_buff *skb;
 
+	if (id == WMI_PDEV_PARAM_UNSUPPORTED) {
+		ath10k_warn("pdev param %d not supported by firmware\n", id);
+		return -EINVAL;
+	}
+
 	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
 	if (!skb)
 		return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index fbff5cb..fcada27 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2072,6 +2072,60 @@ struct wmi_csa_event {
 #define VDEV_DEFAULT_STATS_UPDATE_PERIOD    500
 #define PEER_DEFAULT_STATS_UPDATE_PERIOD    500
 
+struct wmi_pdev_param_map {
+	u32 wmi_pdev_param_tx_chain_mask;
+	u32 wmi_pdev_param_rx_chain_mask;
+	u32 wmi_pdev_param_txpower_limit2g;
+	u32 wmi_pdev_param_txpower_limit5g;
+	u32 wmi_pdev_param_txpower_scale;
+	u32 wmi_pdev_param_beacon_gen_mode;
+	u32 wmi_pdev_param_beacon_tx_mode;
+	u32 wmi_pdev_param_resmgr_offchan_mode;
+	u32 wmi_pdev_param_protection_mode;
+	u32 wmi_pdev_param_dynamic_bw;
+	u32 wmi_pdev_param_non_agg_sw_retry_th;
+	u32 wmi_pdev_param_agg_sw_retry_th;
+	u32 wmi_pdev_param_sta_kickout_th;
+	u32 wmi_pdev_param_ac_aggrsize_scaling;
+	u32 wmi_pdev_param_ltr_enable;
+	u32 wmi_pdev_param_ltr_ac_latency_be;
+	u32 wmi_pdev_param_ltr_ac_latency_bk;
+	u32 wmi_pdev_param_ltr_ac_latency_vi;
+	u32 wmi_pdev_param_ltr_ac_latency_vo;
+	u32 wmi_pdev_param_ltr_ac_latency_timeout;
+	u32 wmi_pdev_param_ltr_sleep_override;
+	u32 wmi_pdev_param_ltr_rx_override;
+	u32 wmi_pdev_param_ltr_tx_activity_timeout;
+	u32 wmi_pdev_param_l1ss_enable;
+	u32 wmi_pdev_param_dsleep_enable;
+	u32 wmi_pdev_param_pcielp_txbuf_flush;
+	u32 wmi_pdev_param_pcielp_txbuf_watermark;
+	u32 wmi_pdev_param_pcielp_txbuf_tmo_en;
+	u32 wmi_pdev_param_pcielp_txbuf_tmo_value;
+	u32 wmi_pdev_param_pdev_stats_update_period;
+	u32 wmi_pdev_param_vdev_stats_update_period;
+	u32 wmi_pdev_param_peer_stats_update_period;
+	u32 wmi_pdev_param_bcnflt_stats_update_period;
+	u32 wmi_pdev_param_pmf_qos;
+	u32 wmi_pdev_param_arp_ac_override;
+	u32 wmi_pdev_param_arpdhcp_ac_override;
+	u32 wmi_pdev_param_dcs;
+	u32 wmi_pdev_param_ani_enable;
+	u32 wmi_pdev_param_ani_poll_period;
+	u32 wmi_pdev_param_ani_listen_period;
+	u32 wmi_pdev_param_ani_ofdm_level;
+	u32 wmi_pdev_param_ani_cck_level;
+	u32 wmi_pdev_param_dyntxchain;
+	u32 wmi_pdev_param_proxy_sta;
+	u32 wmi_pdev_param_idle_ps_config;
+	u32 wmi_pdev_param_power_gating_sleep;
+	u32 wmi_pdev_param_fast_channel_reset;
+	u32 wmi_pdev_param_burst_dur;
+	u32 wmi_pdev_param_burst_enable;
+};
+
+#define WMI_PDEV_PARAM_UNSUPPORTED 0
+
 enum wmi_pdev_param {
 	/* TX chian mask */
 	WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1,
@@ -2171,6 +2225,97 @@ enum wmi_pdev_param {
 	WMI_PDEV_PARAM_POWER_GATING_SLEEP,
 };
 
+enum wmi_10x_pdev_param {
+	/* TX chian mask */
+	WMI_10X_PDEV_PARAM_TX_CHAIN_MASK = 0x1,
+	/* RX chian mask */
+	WMI_10X_PDEV_PARAM_RX_CHAIN_MASK,
+	/* TX power limit for 2G Radio */
+	WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G,
+	/* TX power limit for 5G Radio */
+	WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G,
+	/* TX power scale */
+	WMI_10X_PDEV_PARAM_TXPOWER_SCALE,
+	/* Beacon generation mode . 0: host, 1: target   */
+	WMI_10X_PDEV_PARAM_BEACON_GEN_MODE,
+	/* Beacon generation mode . 0: staggered 1: bursted   */
+	WMI_10X_PDEV_PARAM_BEACON_TX_MODE,
+	/*
+	 * Resource manager off chan mode .
+	 * 0: turn off off chan mode. 1: turn on offchan mode
+	 */
+	WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
+	/*
+	 * Protection mode:
+	 * 0: no protection 1:use CTS-to-self 2: use RTS/CTS
+	 */
+	WMI_10X_PDEV_PARAM_PROTECTION_MODE,
+	/* Dynamic bandwidth 0: disable 1: enable */
+	WMI_10X_PDEV_PARAM_DYNAMIC_BW,
+	/* Non aggregrate/ 11g sw retry threshold.0-disable */
+	WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
+	/* aggregrate sw retry threshold. 0-disable*/
+	WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH,
+	/* Station kickout threshold (non of consecutive failures).0-disable */
+	WMI_10X_PDEV_PARAM_STA_KICKOUT_TH,
+	/* Aggerate size scaling configuration per AC */
+	WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING,
+	/* LTR enable */
+	WMI_10X_PDEV_PARAM_LTR_ENABLE,
+	/* LTR latency for BE, in us */
+	WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE,
+	/* LTR latency for BK, in us */
+	WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK,
+	/* LTR latency for VI, in us */
+	WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI,
+	/* LTR latency for VO, in us  */
+	WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO,
+	/* LTR AC latency timeout, in ms */
+	WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
+	/* LTR platform latency override, in us */
+	WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
+	/* LTR-RX override, in us */
+	WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE,
+	/* Tx activity timeout for LTR, in us */
+	WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
+	/* L1SS state machine enable */
+	WMI_10X_PDEV_PARAM_L1SS_ENABLE,
+	/* Deep sleep state machine enable */
+	WMI_10X_PDEV_PARAM_DSLEEP_ENABLE,
+	/* pdev level stats update period in ms */
+	WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
+	/* vdev level stats update period in ms */
+	WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
+	/* peer level stats update period in ms */
+	WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
+	/* beacon filter status update period */
+	WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
+	/* QOS Mgmt frame protection MFP/PMF 0: disable, 1: enable */
+	WMI_10X_PDEV_PARAM_PMF_QOS,
+	/* Access category on which ARP and DHCP frames are sent */
+	WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
+	/* DCS configuration */
+	WMI_10X_PDEV_PARAM_DCS,
+	/* Enable/Disable ANI on target */
+	WMI_10X_PDEV_PARAM_ANI_ENABLE,
+	/* configure the ANI polling period */
+	WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
+	/* configure the ANI listening period */
+	WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD,
+	/* configure OFDM immunity level */
+	WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL,
+	/* configure CCK immunity level */
+	WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL,
+	/* Enable/Disable CDD for 1x1 STAs in rate control module */
+	WMI_10X_PDEV_PARAM_DYNTXCHAIN,
+	/* Enable/Disable Fast channel reset*/
+	WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
+	/* Set Bursting DUR */
+	WMI_10X_PDEV_PARAM_BURST_DUR,
+	/* Set Bursting Enable*/
+	WMI_10X_PDEV_PARAM_BURST_ENABLE,
+};
+
 struct wmi_pdev_set_param_cmd {
 	__le32 param_id;
 	__le32 param_value;
@@ -3797,8 +3942,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar);
 int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
 int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
 				  u16 rd5g, u16 ctl2g, u16 ctl5g);
-int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id,
-			      u32 value);
+int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
 int ath10k_wmi_cmd_init(struct ath10k *ar);
 int ath10k_wmi_10x_cmd_init(struct ath10k *ar);
 int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
-- 
1.7.10


^ permalink raw reply related

* [PATCH 10/13] ath10k: add TARGET values for 10.x firmware
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

Introduce all TARGET specific values for 10.x firmware.
Some of them are common for both firmwares we will support,
but to avoid confusion, define everything with prefix 10X_.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/hw.h  |   31 ++++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi.c |   58 ++++++++++++++++-----------------
 2 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 1b3cf01..6cc3453 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -53,6 +53,7 @@ enum ath10k_mcast2ucast_mode {
 	ATH10K_MCAST2UCAST_ENABLED = 1,
 };
 
+/* Target specific defines for MAIN firmware */
 #define TARGET_NUM_VDEVS			8
 #define TARGET_NUM_PEER_AST			2
 #define TARGET_NUM_WDS_ENTRIES			32
@@ -83,6 +84,36 @@ enum ath10k_mcast2ucast_mode {
 #define TARGET_NUM_MSDU_DESC			(1024 + 400)
 #define TARGET_MAX_FRAG_ENTRIES			0
 
+/* Target specific defines for 10.X firmware */
+#define TARGET_10X_NUM_VDEVS			16
+#define TARGET_10X_NUM_PEER_AST			2
+#define TARGET_10X_NUM_WDS_ENTRIES		32
+#define TARGET_10X_DMA_BURST_SIZE		0
+#define TARGET_10X_MAC_AGGR_DELIM		0
+#define TARGET_10X_AST_SKID_LIMIT		16
+#define TARGET_10X_NUM_PEERS			(128 + (TARGET_10X_NUM_VDEVS))
+#define TARGET_10X_NUM_OFFLOAD_PEERS		0
+#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS	0
+#define TARGET_10X_NUM_PEER_KEYS		2
+#define TARGET_10X_NUM_TIDS			256
+#define TARGET_10X_TX_CHAIN_MASK		(BIT(0) | BIT(1) | BIT(2))
+#define TARGET_10X_RX_CHAIN_MASK		(BIT(0) | BIT(1) | BIT(2))
+#define TARGET_10X_RX_TIMEOUT_LO_PRI		100
+#define TARGET_10X_RX_TIMEOUT_HI_PRI		40
+#define TARGET_10X_RX_DECAP_MODE		ATH10K_HW_TXRX_ETHERNET
+#define TARGET_10X_SCAN_MAX_PENDING_REQS	4
+#define TARGET_10X_BMISS_OFFLOAD_MAX_VDEV	2
+#define TARGET_10X_ROAM_OFFLOAD_MAX_VDEV	2
+#define TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES	8
+#define TARGET_10X_GTK_OFFLOAD_MAX_VDEV		3
+#define TARGET_10X_NUM_MCAST_GROUPS		0
+#define TARGET_10X_NUM_MCAST_TABLE_ELEMS	0
+#define TARGET_10X_MCAST2UCAST_MODE		ATH10K_MCAST2UCAST_DISABLED
+#define TARGET_10X_TX_DBG_LOG_SIZE		1024
+#define TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
+#define TARGET_10X_VOW_CONFIG			0
+#define TARGET_10X_NUM_MSDU_DESC		(1024 + 400)
+#define TARGET_10X_MAX_FRAG_ENTRIES		0
 
 /* Number of Copy Engines supported */
 #define CE_COUNT 8
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index f88a1d3..f0e1ea9 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1458,9 +1458,9 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
 				 * peers, 1 extra for self peer on target */
 				/* this needs to be tied, host and target
 				 * can get out of sync */
-				num_units = TARGET_NUM_PEERS + 1;
+				num_units = TARGET_10X_NUM_PEERS + 1;
 			if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS)
-				num_units = TARGET_NUM_VDEVS + 1;
+				num_units = TARGET_10X_NUM_VDEVS + 1;
 		}
 
 		ath10k_dbg(ATH10K_DBG_WMI,
@@ -2027,48 +2027,48 @@ int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
 	u32 len, val;
 	int i;
 
-	config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
-	config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS);
-	config.num_peer_keys = __cpu_to_le32(TARGET_NUM_PEER_KEYS);
-	config.num_tids = __cpu_to_le32(TARGET_NUM_TIDS);
-	config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT);
-	config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK);
-	config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK);
-	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
-	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
-	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
-	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_RX_TIMEOUT_HI_PRI);
-	config.rx_decap_mode = __cpu_to_le32(TARGET_RX_DECAP_MODE);
+	config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
+	config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
+	config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS);
+	config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS);
+	config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT);
+	config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK);
+	config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK);
+	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI);
+	config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE);
 
 	config.scan_max_pending_reqs =
-		__cpu_to_le32(TARGET_SCAN_MAX_PENDING_REQS);
+		__cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS);
 
 	config.bmiss_offload_max_vdev =
-		__cpu_to_le32(TARGET_BMISS_OFFLOAD_MAX_VDEV);
+		__cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV);
 
 	config.roam_offload_max_vdev =
-		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_VDEV);
+		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV);
 
 	config.roam_offload_max_ap_profiles =
-		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES);
+		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES);
 
-	config.num_mcast_groups = __cpu_to_le32(TARGET_NUM_MCAST_GROUPS);
+	config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS);
 	config.num_mcast_table_elems =
-		__cpu_to_le32(TARGET_NUM_MCAST_TABLE_ELEMS);
+		__cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS);
 
-	config.mcast2ucast_mode = __cpu_to_le32(TARGET_MCAST2UCAST_MODE);
-	config.tx_dbg_log_size = __cpu_to_le32(TARGET_TX_DBG_LOG_SIZE);
-	config.num_wds_entries = __cpu_to_le32(TARGET_NUM_WDS_ENTRIES);
-	config.dma_burst_size = __cpu_to_le32(TARGET_DMA_BURST_SIZE);
-	config.mac_aggr_delim = __cpu_to_le32(TARGET_MAC_AGGR_DELIM);
+	config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE);
+	config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE);
+	config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES);
+	config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE);
+	config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM);
 
-	val = TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
+	val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
 	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
 
-	config.vow_config = __cpu_to_le32(TARGET_VOW_CONFIG);
+	config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG);
 
-	config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC);
-	config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES);
+	config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC);
+	config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES);
 
 	len = sizeof(*cmd) +
 	      (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
-- 
1.7.10


^ permalink raw reply related

* [PATCH 13/13] ath10k: handle FW API differences for scan structures
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

The wmi_start_scan_cmd has an extra filed in our main
firmware track, reflact that to not have a mismatch in
case of 10.x track.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c |   19 ++++++--
 drivers/net/wireless/ath/ath10k/wmi.h |   82 +++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 2a55bc8..d4ba78546 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2377,11 +2377,15 @@ out:
 	return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->wmi_init_cmdid);
 }
 
-static int ath10k_wmi_start_scan_calc_len(const struct wmi_start_scan_arg *arg)
+static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar,
+					  const struct wmi_start_scan_arg *arg)
 {
 	int len;
 
-	len = sizeof(struct wmi_start_scan_cmd);
+	if (test_bit(ATH10K_FW_FEATURE_10X, ar->fw_features))
+		len = sizeof(struct wmi_start_scan_cmd_10x);
+	else
+		len = sizeof(struct wmi_start_scan_cmd);
 
 	if (arg->ie_len) {
 		if (!arg->ie)
@@ -2441,7 +2445,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar,
 	int len = 0;
 	int i;
 
-	len = ath10k_wmi_start_scan_calc_len(arg);
+	len = ath10k_wmi_start_scan_calc_len(ar, arg);
 	if (len < 0)
 		return len; /* len contains error code here */
 
@@ -2473,7 +2477,14 @@ int ath10k_wmi_start_scan(struct ath10k *ar,
 	cmd->scan_ctrl_flags    = __cpu_to_le32(arg->scan_ctrl_flags);
 
 	/* TLV list starts after fields included in the struct */
-	off = sizeof(*cmd);
+	/* There's just one filed that differes the two start_scan
+	 * structures - burst_duration, which we are not using btw,
+	   no point to make the split here, just shift the buffer to fit with
+	   given FW */
+	if (test_bit(ATH10K_FW_FEATURE_10X, ar->fw_features))
+		off = sizeof(struct wmi_start_scan_cmd_10x);
+	else
+		off = sizeof(struct wmi_start_scan_cmd);
 
 	if (arg->n_channels) {
 		channels = (void *)skb->data + off;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index fcada27..75b9978 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1715,6 +1715,88 @@ struct wmi_start_scan_cmd {
 	 */
 } __packed;
 
+/* This is the definition from 10.X firmware branch */
+struct wmi_start_scan_cmd_10x {
+	/* Scan ID */
+	__le32 scan_id;
+
+	/* Scan requestor ID */
+	__le32 scan_req_id;
+
+	/* VDEV id(interface) that is requesting scan */
+	__le32 vdev_id;
+
+	/* Scan Priority, input to scan scheduler */
+	__le32 scan_priority;
+
+	/* Scan events subscription */
+	__le32 notify_scan_events;
+
+	/* dwell time in msec on active channels */
+	__le32 dwell_time_active;
+
+	/* dwell time in msec on passive channels */
+	__le32 dwell_time_passive;
+
+	/*
+	 * min time in msec on the BSS channel,only valid if atleast one
+	 * VDEV is active
+	 */
+	__le32 min_rest_time;
+
+	/*
+	 * max rest time in msec on the BSS channel,only valid if at least
+	 * one VDEV is active
+	 */
+	/*
+	 * the scanner will rest on the bss channel at least min_rest_time
+	 * after min_rest_time the scanner will start checking for tx/rx
+	 * activity on all VDEVs. if there is no activity the scanner will
+	 * switch to off channel. if there is activity the scanner will let
+	 * the radio on the bss channel until max_rest_time expires.at
+	 * max_rest_time scanner will switch to off channel irrespective of
+	 * activity. activity is determined by the idle_time parameter.
+	 */
+	__le32 max_rest_time;
+
+	/*
+	 * time before sending next set of probe requests.
+	 * The scanner keeps repeating probe requests transmission with
+	 * period specified by repeat_probe_time.
+	 * The number of probe requests specified depends on the ssid_list
+	 * and bssid_list
+	 */
+	__le32 repeat_probe_time;
+
+	/* time in msec between 2 consequetive probe requests with in a set. */
+	__le32 probe_spacing_time;
+
+	/*
+	 * data inactivity time in msec on bss channel that will be used by
+	 * scanner for measuring the inactivity.
+	 */
+	__le32 idle_time;
+
+	/* maximum time in msec allowed for scan  */
+	__le32 max_scan_time;
+
+	/*
+	 * delay in msec before sending first probe request after switching
+	 * to a channel
+	 */
+	__le32 probe_delay;
+
+	/* Scan control flags */
+	__le32 scan_ctrl_flags;
+
+	/*
+	 * TLV (tag length value )  paramerters follow the scan_cmd structure.
+	 * TLV can contain channel list, bssid list, ssid list and
+	 * ie. the TLV tags are defined above;
+	 */
+} __packed;
+
+
 struct wmi_ssid_arg {
 	int len;
 	const u8 *ssid;
-- 
1.7.10


^ permalink raw reply related

* [PATCH 09/13] ath10k: split wmi_cmd_init path
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

Due to API differences in initialization structures for
main and 10.x firmwares we need to split the wmi_init_cmd
and wmi_resource_config  structures.

This will be usefull also when setting the correct TARGET values,
like: number of peers, vdevs, pdevs etc.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.c |    6 +-
 drivers/net/wireless/ath/ath10k/wmi.c  |   91 +++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h  |  196 ++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 31860a6..3a56715 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -595,7 +595,11 @@ int ath10k_core_start(struct ath10k *ar)
 
 	ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version);
 
-	status = ath10k_wmi_cmd_init(ar);
+	if (test_bit(ATH10K_FW_FEATURE_10X, ar->fw_features))
+		status = ath10k_wmi_10x_cmd_init(ar);
+	else
+		status = ath10k_wmi_cmd_init(ar);
+
 	if (status) {
 		ath10k_err("could not send WMI init command (%d)\n", status);
 		goto err_disconnect_htc;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 4992ad1..f88a1d3 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2019,6 +2019,97 @@ out:
 	return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->wmi_init_cmdid);
 }
 
+int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
+{
+	struct wmi_init_cmd_10x *cmd;
+	struct sk_buff *buf;
+	struct wmi_resource_config_10x config = {};
+	u32 len, val;
+	int i;
+
+	config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
+	config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS);
+	config.num_peer_keys = __cpu_to_le32(TARGET_NUM_PEER_KEYS);
+	config.num_tids = __cpu_to_le32(TARGET_NUM_TIDS);
+	config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT);
+	config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK);
+	config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK);
+	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_RX_TIMEOUT_HI_PRI);
+	config.rx_decap_mode = __cpu_to_le32(TARGET_RX_DECAP_MODE);
+
+	config.scan_max_pending_reqs =
+		__cpu_to_le32(TARGET_SCAN_MAX_PENDING_REQS);
+
+	config.bmiss_offload_max_vdev =
+		__cpu_to_le32(TARGET_BMISS_OFFLOAD_MAX_VDEV);
+
+	config.roam_offload_max_vdev =
+		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_VDEV);
+
+	config.roam_offload_max_ap_profiles =
+		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES);
+
+	config.num_mcast_groups = __cpu_to_le32(TARGET_NUM_MCAST_GROUPS);
+	config.num_mcast_table_elems =
+		__cpu_to_le32(TARGET_NUM_MCAST_TABLE_ELEMS);
+
+	config.mcast2ucast_mode = __cpu_to_le32(TARGET_MCAST2UCAST_MODE);
+	config.tx_dbg_log_size = __cpu_to_le32(TARGET_TX_DBG_LOG_SIZE);
+	config.num_wds_entries = __cpu_to_le32(TARGET_NUM_WDS_ENTRIES);
+	config.dma_burst_size = __cpu_to_le32(TARGET_DMA_BURST_SIZE);
+	config.mac_aggr_delim = __cpu_to_le32(TARGET_MAC_AGGR_DELIM);
+
+	val = TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
+	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
+
+	config.vow_config = __cpu_to_le32(TARGET_VOW_CONFIG);
+
+	config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC);
+	config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES);
+
+	len = sizeof(*cmd) +
+	      (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
+
+	buf = ath10k_wmi_alloc_skb(len);
+	if (!buf)
+		return -ENOMEM;
+
+	cmd = (struct wmi_init_cmd_10x *)buf->data;
+
+	if (ar->wmi.num_mem_chunks == 0) {
+		cmd->num_host_mem_chunks = 0;
+		goto out;
+	}
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
+		   __cpu_to_le32(ar->wmi.num_mem_chunks));
+
+	cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
+
+	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
+		cmd->host_mem_chunks[i].ptr =
+			__cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
+		cmd->host_mem_chunks[i].size =
+			__cpu_to_le32(ar->wmi.mem_chunks[i].len);
+		cmd->host_mem_chunks[i].req_id =
+			__cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
+
+		ath10k_dbg(ATH10K_DBG_WMI,
+			   "wmi chunk %d len %d requested, addr 0x%x\n",
+			   i,
+			   cmd->host_mem_chunks[i].size,
+			   cmd->host_mem_chunks[i].ptr);
+	}
+out:
+	memcpy(&cmd->resource_config, &config, sizeof(config));
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi init 10x\n");
+	return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->wmi_init_cmdid);
+}
+
 static int ath10k_wmi_start_scan_calc_len(const struct wmi_start_scan_arg *arg)
 {
 	int len;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 8c67fb4..2f18349 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1377,6 +1377,189 @@ struct wmi_resource_config {
 	__le32 max_frag_entries;
 } __packed;
 
+struct wmi_resource_config_10x {
+	/* number of virtual devices (VAPs) to support */
+	__le32 num_vdevs;
+
+	/* number of peer nodes to support */
+	__le32 num_peers;
+
+	/* number of keys per peer */
+	__le32 num_peer_keys;
+
+	/* total number of TX/RX data TIDs */
+	__le32 num_tids;
+
+	/*
+	 * max skid for resolving hash collisions
+	 *
+	 *   The address search table is sparse, so that if two MAC addresses
+	 *   result in the same hash value, the second of these conflicting
+	 *   entries can slide to the next index in the address search table,
+	 *   and use it, if it is unoccupied.  This ast_skid_limit parameter
+	 *   specifies the upper bound on how many subsequent indices to search
+	 *   over to find an unoccupied space.
+	 */
+	__le32 ast_skid_limit;
+
+	/*
+	 * the nominal chain mask for transmit
+	 *
+	 *   The chain mask may be modified dynamically, e.g. to operate AP
+	 *   tx with a reduced number of chains if no clients are associated.
+	 *   This configuration parameter specifies the nominal chain-mask that
+	 *   should be used when not operating with a reduced set of tx chains.
+	 */
+	__le32 tx_chain_mask;
+
+	/*
+	 * the nominal chain mask for receive
+	 *
+	 *   The chain mask may be modified dynamically, e.g. for a client
+	 *   to use a reduced number of chains for receive if the traffic to
+	 *   the client is low enough that it doesn't require downlink MIMO
+	 *   or antenna diversity.
+	 *   This configuration parameter specifies the nominal chain-mask that
+	 *   should be used when not operating with a reduced set of rx chains.
+	 */
+	__le32 rx_chain_mask;
+
+	/*
+	 * what rx reorder timeout (ms) to use for the AC
+	 *
+	 *   Each WMM access class (voice, video, best-effort, background) will
+	 *   have its own timeout value to dictate how long to wait for missing
+	 *   rx MPDUs to arrive before flushing subsequent MPDUs that have
+	 *   already been received.
+	 *   This parameter specifies the timeout in milliseconds for each
+	 *   class.
+	 */
+	__le32 rx_timeout_pri_vi;
+	__le32 rx_timeout_pri_vo;
+	__le32 rx_timeout_pri_be;
+	__le32 rx_timeout_pri_bk;
+
+	/*
+	 * what mode the rx should decap packets to
+	 *
+	 *   MAC can decap to RAW (no decap), native wifi or Ethernet types
+	 *   THis setting also determines the default TX behavior, however TX
+	 *   behavior can be modified on a per VAP basis during VAP init
+	 */
+	__le32 rx_decap_mode;
+
+	/* what is the maximum scan requests than can be queued */
+	__le32 scan_max_pending_reqs;
+
+	/* maximum VDEV that could use BMISS offload */
+	__le32 bmiss_offload_max_vdev;
+
+	/* maximum VDEV that could use offload roaming */
+	__le32 roam_offload_max_vdev;
+
+	/* maximum AP profiles that would push to offload roaming */
+	__le32 roam_offload_max_ap_profiles;
+
+	/*
+	 * how many groups to use for mcast->ucast conversion
+	 *
+	 *   The target's WAL maintains a table to hold information regarding
+	 *   which peers belong to a given multicast group, so that if
+	 *   multicast->unicast conversion is enabled, the target can convert
+	 *   multicast tx frames to a series of unicast tx frames, to each
+	 *   peer within the multicast group.
+	     This num_mcast_groups configuration parameter tells the target how
+	 *   many multicast groups to provide storage for within its multicast
+	 *   group membership table.
+	 */
+	__le32 num_mcast_groups;
+
+	/*
+	 * size to alloc for the mcast membership table
+	 *
+	 *   This num_mcast_table_elems configuration parameter tells the
+	 *   target how many peer elements it needs to provide storage for in
+	 *   its multicast group membership table.
+	 *   These multicast group membership table elements are shared by the
+	 *   multicast groups stored within the table.
+	 */
+	__le32 num_mcast_table_elems;
+
+	/*
+	 * whether/how to do multicast->unicast conversion
+	 *
+	 *   This configuration parameter specifies whether the target should
+	 *   perform multicast --> unicast conversion on transmit, and if so,
+	 *   what to do if it finds no entries in its multicast group
+	 *   membership table for the multicast IP address in the tx frame.
+	 *   Configuration value:
+	 *   0 -> Do not perform multicast to unicast conversion.
+	 *   1 -> Convert multicast frames to unicast, if the IP multicast
+	 *        address from the tx frame is found in the multicast group
+	 *        membership table.  If the IP multicast address is not found,
+	 *        drop the frame.
+	 *   2 -> Convert multicast frames to unicast, if the IP multicast
+	 *        address from the tx frame is found in the multicast group
+	 *        membership table.  If the IP multicast address is not found,
+	 *        transmit the frame as multicast.
+	 */
+	__le32 mcast2ucast_mode;
+
+	/*
+	 * how much memory to allocate for a tx PPDU dbg log
+	 *
+	 *   This parameter controls how much memory the target will allocate
+	 *   to store a log of tx PPDU meta-information (how large the PPDU
+	 *   was, when it was sent, whether it was successful, etc.)
+	 */
+	__le32 tx_dbg_log_size;
+
+	/* how many AST entries to be allocated for WDS */
+	__le32 num_wds_entries;
+
+	/*
+	 * MAC DMA burst size, e.g., For target PCI limit can be
+	 * 0 -default, 1 256B
+	 */
+	__le32 dma_burst_size;
+
+	/*
+	 * Fixed delimiters to be inserted after every MPDU to
+	 * account for interface latency to avoid underrun.
+	 */
+	__le32 mac_aggr_delim;
+
+	/*
+	 *   determine whether target is responsible for detecting duplicate
+	 *   non-aggregate MPDU and timing out stale fragments.
+	 *
+	 *   A-MPDU reordering is always performed on the target.
+	 *
+	 *   0: target responsible for frag timeout and dup checking
+	 *   1: host responsible for frag timeout and dup checking
+	 */
+	__le32 rx_skip_defrag_timeout_dup_detection_check;
+
+	/*
+	 * Configuration for VoW :
+	 * No of Video Nodes to be supported
+	 * and Max no of descriptors for each Video link (node).
+	 */
+	__le32 vow_config;
+
+	/* Number of msdu descriptors target should use */
+	__le32 num_msdu_desc;
+
+	/*
+	 * Max. number of Tx fragments per MSDU
+	 *  This parameter controls the max number of Tx fragments per MSDU.
+	 *  This is sent by the target as part of the WMI_SERVICE_READY event
+	 *  and is overriden by the OS shim as required.
+	 */
+	__le32 max_frag_entries;
+} __packed;
+
+
 #define NUM_UNITS_IS_NUM_VDEVS   0x1
 #define NUM_UNITS_IS_NUM_PEERS   0x2
 
@@ -1401,6 +1584,18 @@ struct wmi_init_cmd {
 	struct host_memory_chunk host_mem_chunks[1];
 } __packed;
 
+/* _10x stucture is from 10.X FW API */
+struct wmi_init_cmd_10x {
+	struct wmi_resource_config_10x resource_config;
+	__le32 num_host_mem_chunks;
+
+	/*
+	 * variable number of host memory chunks.
+	 * This should be the last element in the structure
+	 */
+	struct host_memory_chunk host_mem_chunks[1];
+} __packed;
+
 /* TLV for channel list */
 struct wmi_chan_list {
 	__le32 tag; /* WMI_CHAN_LIST_TAG */
@@ -3435,6 +3630,7 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
 int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id,
 			      u32 value);
 int ath10k_wmi_cmd_init(struct ath10k *ar);
+int ath10k_wmi_10x_cmd_init(struct ath10k *ar);
 int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
 void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *);
 int ath10k_wmi_stop_scan(struct ath10k *ar,
-- 
1.7.10


^ permalink raw reply related

* [PATCH 08/13] ath10k: bring back the WMI path for mgmt frames
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

This is still used by the 10.X firmware.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.h   |    5 ++-
 drivers/net/wireless/ath/ath10k/htt_tx.c |    4 +--
 drivers/net/wireless/ath/ath10k/mac.c    |   27 ++++++++++------
 drivers/net/wireless/ath/ath10k/wmi.c    |   49 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h    |    1 +
 5 files changed, 73 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 0c9e6f3..377560d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -49,9 +49,9 @@ struct ath10k_skb_cb {
 	dma_addr_t paddr;
 	bool is_mapped;
 	bool is_aborted;
+	u8 vdev_id;
 
 	struct {
-		u8 vdev_id;
 		u8 tid;
 		bool is_offchan;
 
@@ -284,6 +284,9 @@ enum ath10k_fw_features {
 	/* firmware from 10X branch */
 	ATH10K_FW_FEATURE_10X = 1,
 
+	/* firmware support tx frame management over WMI, otherwise it's HTT */
+	ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2,
+
 	/* keep last */
 	ATH10K_FW_FEATURE_COUNT,
 };
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 3b93c6a..d9335e9 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -308,7 +308,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	struct sk_buff *txdesc = NULL;
 	struct htt_cmd *cmd;
 	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
-	u8 vdev_id = skb_cb->htt.vdev_id;
+	u8 vdev_id = skb_cb->vdev_id;
 	int len = 0;
 	int msdu_id = -1;
 	int res;
@@ -384,7 +384,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
 	struct sk_buff *txdesc = NULL;
 	bool use_frags;
-	u8 vdev_id = ATH10K_SKB_CB(msdu)->htt.vdev_id;
+	u8 vdev_id = ATH10K_SKB_CB(msdu)->vdev_id;
 	u8 tid;
 	int prefetch_len, desc_len;
 	int msdu_id = -1;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 99a9bad..18fae5e 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1489,7 +1489,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb)
 static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	int ret;
+	int ret = 0;
 
 	if (ar->htt.target_version_major >= 3) {
 		/* Since HTT 3.0 there is no separate mgmt tx command */
@@ -1497,16 +1497,23 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
 		goto exit;
 	}
 
-	if (ieee80211_is_mgmt(hdr->frame_control))
-		ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-	else if (ieee80211_is_nullfunc(hdr->frame_control))
+	if (ieee80211_is_mgmt(hdr->frame_control)) {
+		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
+			     ar->fw_features))
+			ret = ath10k_wmi_mgmt_tx(ar, skb);
+		else
+			ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
+	} else if (!test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
+			     ar->fw_features) &&
+		   ieee80211_is_nullfunc(hdr->frame_control)) {
 		/* FW does not report tx status properly for NullFunc frames
 		 * unless they are sent through mgmt tx path. mac80211 sends
-		 * those frames when it detects link/beacon loss and depends on
-		 * the tx status to be correct. */
+		 * those frames when it detects link/beacon loss and depends
+		 * on the tx status to be correct. */
 		ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-	else
+	} else {
 		ret = ath10k_htt_tx(&ar->htt, skb);
+	}
 
 exit:
 	if (ret) {
@@ -1557,7 +1564,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 
 		hdr = (struct ieee80211_hdr *)skb->data;
 		peer_addr = ieee80211_get_DA(hdr);
-		vdev_id = ATH10K_SKB_CB(skb)->htt.vdev_id;
+		vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
 
 		spin_lock_bh(&ar->data_lock);
 		peer = ath10k_peer_find(ar, vdev_id, peer_addr);
@@ -1757,14 +1764,14 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 		ath10k_tx_h_seq_no(skb);
 	}
 
+	ATH10K_SKB_CB(skb)->vdev_id = vdev_id;
 	ATH10K_SKB_CB(skb)->htt.is_offchan = false;
-	ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id;
 	ATH10K_SKB_CB(skb)->htt.tid = tid;
 
 	if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
 		spin_lock_bh(&ar->data_lock);
 		ATH10K_SKB_CB(skb)->htt.is_offchan = true;
-		ATH10K_SKB_CB(skb)->htt.vdev_id = ar->scan.vdev_id;
+		ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
 		spin_unlock_bh(&ar->data_lock);
 
 		ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 3b1ae88..4992ad1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -418,6 +418,55 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
 	return ret;
 }
 
+int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
+{
+	int ret = 0;
+	struct wmi_mgmt_tx_cmd *cmd;
+	struct ieee80211_hdr *hdr;
+	struct sk_buff *wmi_skb;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	int len;
+	u16 fc;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
+
+	if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
+		return -EINVAL;
+
+	len = sizeof(cmd->hdr) + skb->len;
+	len = round_up(len, 4);
+
+	wmi_skb = ath10k_wmi_alloc_skb(len);
+	if (!wmi_skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data;
+
+	cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id);
+	cmd->hdr.tx_rate = 0;
+	cmd->hdr.tx_power = 0;
+	cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len));
+
+	memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN);
+	memcpy(cmd->buf, skb->data, skb->len);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
+		   wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE,
+		   fc & IEEE80211_FCTL_STYPE);
+
+	/* Send the management frame buffer to the target */
+	ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->wmi_mgmt_tx_cmdid);
+	if (ret)
+		return ret;
+
+	/* TODO: report tx status to mac80211 - temporary just ACK */
+	info->flags |= IEEE80211_TX_STAT_ACK;
+	ieee80211_tx_status_irqsafe(ar->hw, skb);
+
+	return ret;
+}
+
 static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
 {
 	struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3825937..8c67fb4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3483,5 +3483,6 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
 int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
 int ath10k_wmi_force_fw_hang(struct ath10k *ar,
 			     enum wmi_force_fw_hang_type type, u32 delay_ms);
+int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
 
 #endif /* _WMI_H_ */
-- 
1.7.10


^ permalink raw reply related

* [PATCH 11/13] ath10k: introduce dynamic vdev parameters
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

Both firmwares (main and 10.x) have different set of vdev
parameters. To stay in sync with FW API, this patch introduces
a dynamic registering method.

ath10k_wmi_vdev_set_param() takes now indirect u32 value
to identify the Vdev parameter it want's to set.

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.h |    1 +
 drivers/net/wireless/ath/ath10k/mac.c  |   55 +++++-----
 drivers/net/wireless/ath/ath10k/wmi.c  |  136 ++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/wmi.h  |  172 +++++++++++++++++++++++++++++++-
 4 files changed, 339 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 377560d..c9ad626 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -117,6 +117,7 @@ struct ath10k_wmi {
 	struct completion unified_ready;
 	wait_queue_head_t tx_credits_wq;
 	struct wmi_cmd_map *cmd;
+	struct wmi_vdev_param_map *vdev_param;
 
 	u32 num_mem_chunks;
 	struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS];
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 18fae5e..ea11a03 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -334,25 +334,29 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
 
 static int  ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
 {
+	struct ath10k *ar = arvif->ar;
+	u32 vdev_param;
+
 	if (value != 0xFFFFFFFF)
 		value = min_t(u32, arvif->ar->hw->wiphy->rts_threshold,
 			      ATH10K_RTS_MAX);
 
-	return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
-					 WMI_VDEV_PARAM_RTS_THRESHOLD,
-					 value);
+	vdev_param = ar->wmi.vdev_param->wmi_vdev_param_rts_threshold;
+	return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
 }
 
 static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value)
 {
+	struct ath10k *ar = arvif->ar;
+	u32 vdev_param;
+
 	if (value != 0xFFFFFFFF)
 		value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold,
 				ATH10K_FRAGMT_THRESHOLD_MIN,
 				ATH10K_FRAGMT_THRESHOLD_MAX);
 
-	return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
-					 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
-					 value);
+	vdev_param = ar->wmi.vdev_param->wmi_vdev_param_fragmentation_threshold;
+	return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
 }
 
 static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
@@ -677,6 +681,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
 				struct ieee80211_bss_conf *info,
 				const u8 self_peer[ETH_ALEN])
 {
+	u32 vdev_param;
 	int ret = 0;
 
 	lockdep_assert_held(&arvif->ar->conf_mutex);
@@ -710,8 +715,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
 		return;
 	}
 
-	ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
-					WMI_VDEV_PARAM_ATIM_WINDOW,
+	vdev_param = arvif->ar->wmi.vdev_param->wmi_vdev_param_atim_window;
+	ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
 					ATH10K_DEFAULT_ATIM);
 	if (ret)
 		ath10k_warn("Failed to set IBSS ATIM for VDEV:%d ret:%d\n",
@@ -1433,6 +1438,7 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
 	struct ath10k *ar = arvif->ar;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_key_conf *key = info->control.hw_key;
+	u32 vdev_param;
 	int ret;
 
 	if (!ieee80211_has_protected(hdr->frame_control))
@@ -1451,8 +1457,8 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
 	ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d keyidx %d\n",
 		   arvif->vdev_id, key->keyidx);
 
-	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-					WMI_VDEV_PARAM_DEF_KEYID,
+	vdev_param = ar->wmi.vdev_param->wmi_vdev_param_def_keyid;
+	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 					key->keyidx);
 	if (ret) {
 		ath10k_warn("could not update wep keyidx (%d)\n", ret);
@@ -1943,6 +1949,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
 	int ret = 0;
 	u32 value;
 	int bit;
+	u32 vdev_param;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -2004,13 +2011,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
 		goto exit;
 	}
 
-	ret = ath10k_wmi_vdev_set_param(ar, 0, WMI_VDEV_PARAM_DEF_KEYID,
+	vdev_param = ar->wmi.vdev_param->wmi_vdev_param_def_keyid;
+	ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param,
 					arvif->def_wep_key_index);
 	if (ret)
 		ath10k_warn("Failed to set default keyid: %d\n", ret);
 
-	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-					WMI_VDEV_PARAM_TX_ENCAP_TYPE,
+	vdev_param = ar->wmi.vdev_param->wmi_vdev_param_tx_encap_type;
+	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 					ATH10K_HW_TXRX_NATIVE_WIFI);
 	if (ret)
 		ath10k_warn("Failed to set TX encap: %d\n", ret);
@@ -2161,6 +2169,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 	struct ath10k *ar = hw->priv;
 	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
 	int ret = 0;
+	u32 vdev_param;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -2169,8 +2178,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
 		arvif->beacon_interval = info->beacon_int;
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-						WMI_VDEV_PARAM_BEACON_INTERVAL,
+		vdev_param = ar->wmi.vdev_param->wmi_vdev_param_beacon_interval;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 						arvif->beacon_interval);
 		ath10k_dbg(ATH10K_DBG_MAC,
 			   "mac vdev %d beacon_interval %d\n",
@@ -2201,8 +2210,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 			   "mac vdev %d dtim_period %d\n",
 			   arvif->vdev_id, arvif->dtim_period);
 
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-						WMI_VDEV_PARAM_DTIM_PERIOD,
+		vdev_param = ar->wmi.vdev_param->wmi_vdev_param_dtim_period;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 						arvif->dtim_period);
 		if (ret)
 			ath10k_warn("Failed to set dtim period for VDEV: %d\n",
@@ -2269,8 +2278,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 		ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
 			   arvif->vdev_id, cts_prot);
 
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-						WMI_VDEV_PARAM_ENABLE_RTSCTS,
+		vdev_param = ar->wmi.vdev_param->wmi_vdev_param_enable_rtscts;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 						cts_prot);
 		if (ret)
 			ath10k_warn("Failed to set CTS prot for VDEV: %d\n",
@@ -2288,8 +2297,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 		ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
 			   arvif->vdev_id, slottime);
 
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-						WMI_VDEV_PARAM_SLOT_TIME,
+		vdev_param = ar->wmi.vdev_param->wmi_vdev_param_slot_time;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 						slottime);
 		if (ret)
 			ath10k_warn("Failed to set erp slot for VDEV: %d\n",
@@ -2307,8 +2316,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 			   "mac vdev %d preamble %dn",
 			   arvif->vdev_id, preamble);
 
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-						WMI_VDEV_PARAM_PREAMBLE,
+		vdev_param = ar->wmi.vdev_param->wmi_vdev_param_preamble;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 						preamble);
 		if (ret)
 			ath10k_warn("Failed to set preamble for VDEV: %d\n",
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index f0e1ea9..44ed523 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -274,6 +274,131 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
 	.wmi_gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
 };
 
+/* MAIN WMI VDEV param map */
+static struct wmi_vdev_param_map wmi_vdev_param_map = {
+	.wmi_vdev_param_rts_threshold = WMI_VDEV_PARAM_RTS_THRESHOLD,
+	.wmi_vdev_param_fragmentation_threshold =
+				WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+	.wmi_vdev_param_beacon_interval = WMI_VDEV_PARAM_BEACON_INTERVAL,
+	.wmi_vdev_param_listen_interval = WMI_VDEV_PARAM_LISTEN_INTERVAL,
+	.wmi_vdev_param_multicast_rate = WMI_VDEV_PARAM_MULTICAST_RATE,
+	.wmi_vdev_param_mgmt_tx_rate = WMI_VDEV_PARAM_MGMT_TX_RATE,
+	.wmi_vdev_param_slot_time = WMI_VDEV_PARAM_SLOT_TIME,
+	.wmi_vdev_param_preamble = WMI_VDEV_PARAM_PREAMBLE,
+	.wmi_vdev_param_swba_time = WMI_VDEV_PARAM_SWBA_TIME,
+	.wmi_vdev_stats_update_period = WMI_VDEV_STATS_UPDATE_PERIOD,
+	.wmi_vdev_pwrsave_ageout_time = WMI_VDEV_PWRSAVE_AGEOUT_TIME,
+	.wmi_vdev_host_swba_interval = WMI_VDEV_HOST_SWBA_INTERVAL,
+	.wmi_vdev_param_dtim_period = WMI_VDEV_PARAM_DTIM_PERIOD,
+	.wmi_vdev_oc_scheduler_air_time_limit =
+					WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
+	.wmi_vdev_param_wds = WMI_VDEV_PARAM_WDS,
+	.wmi_vdev_param_atim_window = WMI_VDEV_PARAM_ATIM_WINDOW,
+	.wmi_vdev_param_bmiss_count_max = WMI_VDEV_PARAM_BMISS_COUNT_MAX,
+	.wmi_vdev_param_bmiss_first_bcnt = WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
+	.wmi_vdev_param_bmiss_final_bcnt = WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
+	.wmi_vdev_param_feature_wmm = WMI_VDEV_PARAM_FEATURE_WMM,
+	.wmi_vdev_param_chwidth = WMI_VDEV_PARAM_CHWIDTH,
+	.wmi_vdev_param_chextoffset = WMI_VDEV_PARAM_CHEXTOFFSET,
+	.wmi_vdev_param_disable_htprotection =
+					WMI_VDEV_PARAM_DISABLE_HTPROTECTION,
+	.wmi_vdev_param_sta_quickkickout = WMI_VDEV_PARAM_DISABLE_HTPROTECTION,
+	.wmi_vdev_param_mgmt_rate = WMI_VDEV_PARAM_MGMT_RATE,
+	.wmi_vdev_param_protection_mode = WMI_VDEV_PARAM_PROTECTION_MODE,
+	.wmi_vdev_param_fixed_rate = WMI_VDEV_PARAM_FIXED_RATE,
+	.wmi_vdev_param_sgi = WMI_VDEV_PARAM_SGI,
+	.wmi_vdev_param_ldpc = WMI_VDEV_PARAM_LDPC,
+	.wmi_vdev_param_tx_stbc = WMI_VDEV_PARAM_TX_STBC,
+	.wmi_vdev_param_rx_stbc = WMI_VDEV_PARAM_RX_STBC,
+	.wmi_vdev_param_intra_bss_fwd = WMI_VDEV_PARAM_INTRA_BSS_FWD,
+	.wmi_vdev_param_def_keyid = WMI_VDEV_PARAM_DEF_KEYID,
+	.wmi_vdev_param_nss = WMI_VDEV_PARAM_NSS,
+	.wmi_vdev_param_bcast_data_rate = WMI_VDEV_PARAM_BCAST_DATA_RATE,
+	.wmi_vdev_param_mcast_data_rate = WMI_VDEV_PARAM_MCAST_DATA_RATE,
+	.wmi_vdev_param_mcast_indicate = WMI_VDEV_PARAM_MCAST_INDICATE,
+	.wmi_vdev_param_dhcp_indicate = WMI_VDEV_PARAM_DHCP_INDICATE,
+	.wmi_vdev_param_unknown_dest_indicate =
+			WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
+	.wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs =
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+	.wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs =
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+	.wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs =
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+	.wmi_vdev_param_ap_enable_nawds = WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
+	.wmi_vdev_param_mcast2ucast_set = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_enable_rtscts = WMI_VDEV_PARAM_ENABLE_RTSCTS,
+	.wmi_vdev_param_txbf = WMI_VDEV_PARAM_TXBF,
+	.wmi_vdev_param_packet_powersave = WMI_VDEV_PARAM_PACKET_POWERSAVE,
+	.wmi_vdev_param_drop_unencry = WMI_VDEV_PARAM_DROP_UNENCRY,
+	.wmi_vdev_param_tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE,
+	.wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs =
+		WMI_VDEV_PARAM_UNSUPPORTED,
+};
+
+/* 10.X WMI VDEV param map */
+static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
+	.wmi_vdev_param_rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD,
+	.wmi_vdev_param_fragmentation_threshold =
+				WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+	.wmi_vdev_param_beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL,
+	.wmi_vdev_param_listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL,
+	.wmi_vdev_param_multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE,
+	.wmi_vdev_param_mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE,
+	.wmi_vdev_param_slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME,
+	.wmi_vdev_param_preamble = WMI_10X_VDEV_PARAM_PREAMBLE,
+	.wmi_vdev_param_swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME,
+	.wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD,
+	.wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME,
+	.wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL,
+	.wmi_vdev_param_dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD,
+	.wmi_vdev_oc_scheduler_air_time_limit =
+				WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
+	.wmi_vdev_param_wds = WMI_10X_VDEV_PARAM_WDS,
+	.wmi_vdev_param_atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW,
+	.wmi_vdev_param_bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX,
+	.wmi_vdev_param_bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM,
+	.wmi_vdev_param_chwidth = WMI_10X_VDEV_PARAM_CHWIDTH,
+	.wmi_vdev_param_chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET,
+	.wmi_vdev_param_disable_htprotection =
+					WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
+	.wmi_vdev_param_sta_quickkickout =
+					WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
+	.wmi_vdev_param_mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE,
+	.wmi_vdev_param_protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE,
+	.wmi_vdev_param_fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE,
+	.wmi_vdev_param_sgi = WMI_10X_VDEV_PARAM_SGI,
+	.wmi_vdev_param_ldpc = WMI_10X_VDEV_PARAM_LDPC,
+	.wmi_vdev_param_tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC,
+	.wmi_vdev_param_rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC,
+	.wmi_vdev_param_intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD,
+	.wmi_vdev_param_def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID,
+	.wmi_vdev_param_nss = WMI_10X_VDEV_PARAM_NSS,
+	.wmi_vdev_param_bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE,
+	.wmi_vdev_param_mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE,
+	.wmi_vdev_param_mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE,
+	.wmi_vdev_param_dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE,
+	.wmi_vdev_param_unknown_dest_indicate =
+			WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
+	.wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs =
+		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+	.wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs =
+		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+	.wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs =
+		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+	.wmi_vdev_param_ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS,
+	.wmi_vdev_param_mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET,
+	.wmi_vdev_param_enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS,
+	.wmi_vdev_param_txbf = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED,
+	.wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs =
+		WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
+};
+
 int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
 {
 	int ret;
@@ -1760,9 +1885,11 @@ int ath10k_wmi_attach(struct ath10k *ar)
 	if (test_bit(ATH10K_FW_FEATURE_10X, ar->fw_features)) {
 		ath10k_warn("Firmware 10.X is not yet supported\n");
 		ar->wmi.cmd = &wmi_10x_cmd_map;
+		ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
 		ret = -ENOTSUPP;
 	} else {
 		ar->wmi.cmd = &wmi_cmd_map;
+		ar->wmi.vdev_param = &wmi_vdev_param_map;
 		ret = 0;
 	}
 
@@ -2520,11 +2647,18 @@ int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id)
 }
 
 int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
-			      enum wmi_vdev_param param_id, u32 param_value)
+			      u32 param_id, u32 param_value)
 {
 	struct wmi_vdev_set_param_cmd *cmd;
 	struct sk_buff *skb;
 
+	if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) {
+		ath10k_dbg(ATH10K_DBG_WMI,
+			   "vdev param %d not supported by firmware\n",
+			    param_id);
+		return -EINVAL;
+	}
+
 	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
 	if (!skb)
 		return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 2f18349..fbff5cb 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2695,6 +2695,61 @@ enum wmi_rate_preamble {
 /* Value to disable fixed rate setting */
 #define WMI_FIXED_RATE_NONE    (0xff)
 
+struct wmi_vdev_param_map {
+	u32 wmi_vdev_param_rts_threshold;
+	u32 wmi_vdev_param_fragmentation_threshold;
+	u32 wmi_vdev_param_beacon_interval;
+	u32 wmi_vdev_param_listen_interval;
+	u32 wmi_vdev_param_multicast_rate;
+	u32 wmi_vdev_param_mgmt_tx_rate;
+	u32 wmi_vdev_param_slot_time;
+	u32 wmi_vdev_param_preamble;
+	u32 wmi_vdev_param_swba_time;
+	u32 wmi_vdev_stats_update_period;
+	u32 wmi_vdev_pwrsave_ageout_time;
+	u32 wmi_vdev_host_swba_interval;
+	u32 wmi_vdev_param_dtim_period;
+	u32 wmi_vdev_oc_scheduler_air_time_limit;
+	u32 wmi_vdev_param_wds;
+	u32 wmi_vdev_param_atim_window;
+	u32 wmi_vdev_param_bmiss_count_max;
+	u32 wmi_vdev_param_bmiss_first_bcnt;
+	u32 wmi_vdev_param_bmiss_final_bcnt;
+	u32 wmi_vdev_param_feature_wmm;
+	u32 wmi_vdev_param_chwidth;
+	u32 wmi_vdev_param_chextoffset;
+	u32 wmi_vdev_param_disable_htprotection;
+	u32 wmi_vdev_param_sta_quickkickout;
+	u32 wmi_vdev_param_mgmt_rate;
+	u32 wmi_vdev_param_protection_mode;
+	u32 wmi_vdev_param_fixed_rate;
+	u32 wmi_vdev_param_sgi;
+	u32 wmi_vdev_param_ldpc;
+	u32 wmi_vdev_param_tx_stbc;
+	u32 wmi_vdev_param_rx_stbc;
+	u32 wmi_vdev_param_intra_bss_fwd;
+	u32 wmi_vdev_param_def_keyid;
+	u32 wmi_vdev_param_nss;
+	u32 wmi_vdev_param_bcast_data_rate;
+	u32 wmi_vdev_param_mcast_data_rate;
+	u32 wmi_vdev_param_mcast_indicate;
+	u32 wmi_vdev_param_dhcp_indicate;
+	u32 wmi_vdev_param_unknown_dest_indicate;
+	u32 wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs;
+	u32 wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs;
+	u32 wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs;
+	u32 wmi_vdev_param_ap_enable_nawds;
+	u32 wmi_vdev_param_mcast2ucast_set;
+	u32 wmi_vdev_param_enable_rtscts;
+	u32 wmi_vdev_param_txbf;
+	u32 wmi_vdev_param_packet_powersave;
+	u32 wmi_vdev_param_drop_unencry;
+	u32 wmi_vdev_param_tx_encap_type;
+	u32 wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs;
+};
+
+#define WMI_VDEV_PARAM_UNSUPPORTED 0
+
 /* the definition of different VDEV parameters */
 enum wmi_vdev_param {
 	/* RTS Threshold */
@@ -2826,6 +2881,121 @@ enum wmi_vdev_param {
 	WMI_VDEV_PARAM_TX_ENCAP_TYPE,
 };
 
+/* the definition of different VDEV parameters */
+enum wmi_10x_vdev_param {
+	/* RTS Threshold */
+	WMI_10X_VDEV_PARAM_RTS_THRESHOLD = 0x1,
+	/* Fragmentation threshold */
+	WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+	/* beacon interval in TUs */
+	WMI_10X_VDEV_PARAM_BEACON_INTERVAL,
+	/* Listen interval in TUs */
+	WMI_10X_VDEV_PARAM_LISTEN_INTERVAL,
+	/* muticast rate in Mbps */
+	WMI_10X_VDEV_PARAM_MULTICAST_RATE,
+	/* management frame rate in Mbps */
+	WMI_10X_VDEV_PARAM_MGMT_TX_RATE,
+	/* slot time (long vs short) */
+	WMI_10X_VDEV_PARAM_SLOT_TIME,
+	/* preamble (long vs short) */
+	WMI_10X_VDEV_PARAM_PREAMBLE,
+	/* SWBA time (time before tbtt in msec) */
+	WMI_10X_VDEV_PARAM_SWBA_TIME,
+	/* time period for updating VDEV stats */
+	WMI_10X_VDEV_STATS_UPDATE_PERIOD,
+	/* age out time in msec for frames queued for station in power save */
+	WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME,
+	/*
+	 * Host SWBA interval (time in msec before tbtt for SWBA event
+	 * generation).
+	 */
+	WMI_10X_VDEV_HOST_SWBA_INTERVAL,
+	/* DTIM period (specified in units of num beacon intervals) */
+	WMI_10X_VDEV_PARAM_DTIM_PERIOD,
+	/*
+	 * scheduler air time limit for this VDEV. used by off chan
+	 * scheduler.
+	 */
+	WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
+	/* enable/dsiable WDS for this VDEV  */
+	WMI_10X_VDEV_PARAM_WDS,
+	/* ATIM Window */
+	WMI_10X_VDEV_PARAM_ATIM_WINDOW,
+	/* BMISS max */
+	WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX,
+	/* WMM enables/disabled */
+	WMI_10X_VDEV_PARAM_FEATURE_WMM,
+	/* Channel width */
+	WMI_10X_VDEV_PARAM_CHWIDTH,
+	/* Channel Offset */
+	WMI_10X_VDEV_PARAM_CHEXTOFFSET,
+	/* Disable HT Protection */
+	WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
+	/* Quick STA Kickout */
+	WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT,
+	/* Rate to be used with Management frames */
+	WMI_10X_VDEV_PARAM_MGMT_RATE,
+	/* Protection Mode */
+	WMI_10X_VDEV_PARAM_PROTECTION_MODE,
+	/* Fixed rate setting */
+	WMI_10X_VDEV_PARAM_FIXED_RATE,
+	/* Short GI Enable/Disable */
+	WMI_10X_VDEV_PARAM_SGI,
+	/* Enable LDPC */
+	WMI_10X_VDEV_PARAM_LDPC,
+	/* Enable Tx STBC */
+	WMI_10X_VDEV_PARAM_TX_STBC,
+	/* Enable Rx STBC */
+	WMI_10X_VDEV_PARAM_RX_STBC,
+	/* Intra BSS forwarding  */
+	WMI_10X_VDEV_PARAM_INTRA_BSS_FWD,
+	/* Setting Default xmit key for Vdev */
+	WMI_10X_VDEV_PARAM_DEF_KEYID,
+	/* NSS width */
+	WMI_10X_VDEV_PARAM_NSS,
+	/* Set the custom rate for the broadcast data frames */
+	WMI_10X_VDEV_PARAM_BCAST_DATA_RATE,
+	/* Set the custom rate (rate-code) for multicast data frames */
+	WMI_10X_VDEV_PARAM_MCAST_DATA_RATE,
+	/* Tx multicast packet indicate Enable/Disable */
+	WMI_10X_VDEV_PARAM_MCAST_INDICATE,
+	/* Tx DHCP packet indicate Enable/Disable */
+	WMI_10X_VDEV_PARAM_DHCP_INDICATE,
+	/* Enable host inspection of Tx unicast packet to unknown destination */
+	WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
+
+	/* The minimum amount of time AP begins to consider STA inactive */
+	WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+
+	/*
+	 * An associated STA is considered inactive when there is no recent
+	 * TX/RX activity and no downlink frames are buffered for it. Once a
+	 * STA exceeds the maximum idle inactive time, the AP will send an
+	 * 802.11 data-null as a keep alive to verify the STA is still
+	 * associated. If the STA does ACK the data-null, or if the data-null
+	 * is buffered and the STA does not retrieve it, the STA will be
+	 * considered unresponsive
+	 * (see WMI_10X_VDEV_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS).
+	 */
+	WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+
+	/*
+	 * An associated STA is considered unresponsive if there is no recent
+	 * TX/RX activity and downlink frames are buffered for it. Once a STA
+	 * exceeds the maximum unresponsive time, the AP will send a
+	 * WMI_10X_STA_KICKOUT event to the host so the STA can be deleted. */
+	WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+
+	/* Enable NAWDS : MCAST INSPECT Enable, NAWDS Flag set */
+	WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS,
+
+	WMI_10X_VDEV_PARAM_MCAST2UCAST_SET,
+	/* Enable/Disable RTS-CTS */
+	WMI_10X_VDEV_PARAM_ENABLE_RTSCTS,
+
+	WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
+};
+
 /* slot time long */
 #define WMI_VDEV_SLOT_TIME_LONG		0x1
 /* slot time short */
@@ -3649,7 +3819,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
 		       const u8 *bssid);
 int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id);
 int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
-			      enum wmi_vdev_param param_id, u32 param_value);
+			      u32 param_id, u32 param_value);
 int ath10k_wmi_vdev_install_key(struct ath10k *ar,
 				const struct wmi_vdev_install_key_arg *arg);
 int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
-- 
1.7.10


^ permalink raw reply related

* [PATCH 06/13] ath10k: drop the fw versioning sanity check
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

It was corrupted and leading to compilation warning
core.c: In function 'ath10k_check_fw_version':
core.c:79: warning: comparison is always true due to limited range of data type

Since we are going to support new FW track in the driver,
the sanity check for fw version number would be an overkill
then. This is just for information purposes anyway.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.c |   25 -------------------------
 drivers/net/wireless/ath/ath10k/hw.h   |    6 ------
 2 files changed, 31 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 76906d5..31860a6 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -59,27 +59,6 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
 	wake_up(&ar->event_queue);
 }
 
-static int ath10k_check_fw_version(struct ath10k *ar)
-{
-	char version[32];
-
-	if (ar->fw_version_major >= SUPPORTED_FW_MAJOR &&
-	    ar->fw_version_minor >= SUPPORTED_FW_MINOR &&
-	    ar->fw_version_release >= SUPPORTED_FW_RELEASE &&
-	    ar->fw_version_build >= SUPPORTED_FW_BUILD)
-		return 0;
-
-	snprintf(version, sizeof(version), "%u.%u.%u.%u",
-		 SUPPORTED_FW_MAJOR, SUPPORTED_FW_MINOR,
-		 SUPPORTED_FW_RELEASE, SUPPORTED_FW_BUILD);
-
-	ath10k_warn("WARNING: Firmware version %s is not officially supported.\n",
-		    ar->hw->wiphy->fw_version);
-	ath10k_warn("Please upgrade to version %s (or newer)\n", version);
-
-	return 0;
-}
-
 static int ath10k_init_connect_htc(struct ath10k *ar)
 {
 	int status;
@@ -616,10 +595,6 @@ int ath10k_core_start(struct ath10k *ar)
 
 	ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version);
 
-	status = ath10k_check_fw_version(ar);
-	if (status)
-		goto err_disconnect_htc;
-
 	status = ath10k_wmi_cmd_init(ar);
 	if (status) {
 		ath10k_err("could not send WMI init command (%d)\n", status);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 643f0c9..1b3cf01 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -20,12 +20,6 @@
 
 #include "targaddrs.h"
 
-/* Supported FW version */
-#define SUPPORTED_FW_MAJOR	1
-#define SUPPORTED_FW_MINOR	0
-#define SUPPORTED_FW_RELEASE	0
-#define SUPPORTED_FW_BUILD	636
-
 /* QCA988X 1.0 definitions (unsupported) */
 #define QCA988X_HW_1_0_CHIP_ID_REV	0x0
 
-- 
1.7.10


^ permalink raw reply related

* [PATCH 05/13] ath10k: split ath10k_wmi_service_ready_event_rx
From: Bartosz Markowski @ 2013-09-25  9:38 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1380101891-18312-1-git-send-email-bartosz.markowski@tieto.com>

Since the both firmwares we are going to support,
have significantly different APIs (WMI and shared
structures), it's easier to actually split the whole
event handling functions, instead cutting them inside.

The fork starts now on ath10k_wmi_process_rx().

Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c |   66 ++++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/wmi.h |   40 ++++++++++++++++++++
 2 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 7bbe51f..f87e79a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1309,6 +1309,70 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
 	complete(&ar->wmi.service_ready);
 }
 
+static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
+						  struct sk_buff *skb)
+{
+	struct wmi_service_ready_event_10x *ev = (void *)skb->data;
+
+	if (skb->len < sizeof(*ev)) {
+		ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
+			    skb->len, sizeof(*ev));
+		return;
+	}
+
+	ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power);
+	ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power);
+	ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info);
+	ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info);
+	ar->fw_version_major =
+		(__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24;
+	ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff);
+	ar->phy_capability = __le32_to_cpu(ev->phy_capability);
+	ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
+
+	if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) {
+		ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n",
+			    ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM);
+		ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM;
+	}
+
+	ar->ath_common.regulatory.current_rd =
+		__le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
+
+	ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap,
+				      sizeof(ev->wmi_service_bitmap));
+
+	if (strlen(ar->hw->wiphy->fw_version) == 0) {
+		snprintf(ar->hw->wiphy->fw_version,
+			 sizeof(ar->hw->wiphy->fw_version),
+			 "%u.%u",
+			 ar->fw_version_major,
+			 ar->fw_version_minor);
+	}
+
+	/* FIXME: it probably should be better to support this.
+	   TODO: Next patch introduce memory chunks. It's a must for 10.x FW */
+	if (__le32_to_cpu(ev->num_mem_reqs) > 0) {
+		ath10k_warn("target requested %d memory chunks; ignoring\n",
+			    __le32_to_cpu(ev->num_mem_reqs));
+	}
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n",
+		   __le32_to_cpu(ev->sw_version),
+		   __le32_to_cpu(ev->abi_version),
+		   __le32_to_cpu(ev->phy_capability),
+		   __le32_to_cpu(ev->ht_cap_info),
+		   __le32_to_cpu(ev->vht_cap_info),
+		   __le32_to_cpu(ev->vht_supp_mcs),
+		   __le32_to_cpu(ev->sys_cap_info),
+		   __le32_to_cpu(ev->num_mem_reqs),
+		   __le32_to_cpu(ev->num_rf_chains));
+
+	complete(&ar->wmi.service_ready);
+}
+
+
 static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
 {
 	struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data;
@@ -1545,7 +1609,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
 		ath10k_wmi_event_vdev_resume_req(ar, skb);
 		break;
 	case WMI_10X_SERVICE_READY_EVENTID:
-		ath10k_wmi_service_ready_event_rx(ar, skb);
+		ath10k_wmi_10x_service_ready_event_rx(ar, skb);
 		break;
 	case WMI_10X_READY_EVENTID:
 		ath10k_wmi_ready_event_rx(ar, skb);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index c23d070..d309b8b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1130,6 +1130,46 @@ struct wmi_service_ready_event {
 	struct wlan_host_mem_req mem_reqs[1];
 } __packed;
 
+/* This is the definition from 10.X firmware branch */
+struct wmi_service_ready_event_10x {
+	__le32 sw_version;
+	__le32 abi_version;
+
+	/* WMI_PHY_CAPABILITY */
+	__le32 phy_capability;
+
+	/* Maximum number of frag table entries that SW will populate less 1 */
+	__le32 max_frag_entry;
+	__le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
+	__le32 num_rf_chains;
+
+	/*
+	 * The following field is only valid for service type
+	 * WMI_SERVICE_11AC
+	 */
+	__le32 ht_cap_info; /* WMI HT Capability */
+	__le32 vht_cap_info; /* VHT capability info field of 802.11ac */
+	__le32 vht_supp_mcs; /* VHT Supported MCS Set field Rx/Tx same */
+	__le32 hw_min_tx_power;
+	__le32 hw_max_tx_power;
+
+	struct hal_reg_capabilities hal_reg_capabilities;
+
+	__le32 sys_cap_info;
+	__le32 min_pkt_size_enable; /* Enterprise mode short pkt enable */
+
+	/*
+	 * request to host to allocate a chuck of memory and pss it down to FW
+	 * via WM_INIT. FW uses this as FW extesnsion memory for saving its
+	 * data structures. Only valid for low latency interfaces like PCIE
+	 * where FW can access this memory directly (or) by DMA.
+	 */
+	__le32 num_mem_reqs;
+
+	struct wlan_host_mem_req mem_reqs[1];
+} __packed;
+
+
 #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ)
 #define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ)
 
-- 
1.7.10


^ permalink raw reply related


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