By default normal mode is chosen when driver is loaded. This patch adds
a provision to choose manufacturing mode via module parameters.
Command to load driver in manufacturing mode
insmod mwifiex.ko mfg_mode=1 and mfg_firmware=mrvl/firmware.
Tested-by: chunfan chen <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 8 ++++++
drivers/net/wireless/marvell/mwifiex/init.c | 22 +++++++++++------
drivers/net/wireless/marvell/mwifiex/main.c | 35 ++++++++++++++++++++++++---
drivers/net/wireless/marvell/mwifiex/main.h | 4 +++
drivers/net/wireless/marvell/mwifiex/pcie.c | 2 +-
drivers/net/wireless/marvell/mwifiex/sdio.c | 2 +-
drivers/net/wireless/marvell/mwifiex/usb.c | 2 +-
7 files changed, 61 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index c29f26d..8d57493 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -581,6 +581,14 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
return -1;
}
}
+ /* We don't expect commands in manufacturing mode. They are cooked
+ * in application and ready to download buffer is passed to the driver
+ */
+ if (adapter->mfg_mode && cmd_no) {
+ dev_dbg(adapter->dev, "Ignoring commands in manufacturing mode\n");
+ return -1;
+ }
+
/* Get a new command node */
cmd_node = mwifiex_get_cmd_node(adapter);
diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
index 1489c90..82839d9 100644
--- a/drivers/net/wireless/marvell/mwifiex/init.c
+++ b/drivers/net/wireless/marvell/mwifiex/init.c
@@ -298,6 +298,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
adapter->arp_filter_size = 0;
adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
+ adapter->mfg_mode = mfg_mode;
adapter->key_api_major_ver = 0;
adapter->key_api_minor_ver = 0;
eth_broadcast_addr(adapter->perm_addr);
@@ -553,15 +554,22 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter)
return -1;
}
}
+ if (adapter->mfg_mode) {
+ adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+ ret = -EINPROGRESS;
+ } else {
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i]) {
+ ret = mwifiex_sta_init_cmd(adapter->priv[i],
+ first_sta, true);
+ if (ret == -1)
+ return -1;
+
+ first_sta = false;
+ }
+
- for (i = 0; i < adapter->priv_num; i++) {
- if (adapter->priv[i]) {
- ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta,
- true);
- if (ret == -1)
- return -1;
- first_sta = false;
}
}
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 0e280f8..b54edf4 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -36,6 +36,14 @@ static unsigned short driver_mode;
module_param(driver_mode, ushort, 0);
MODULE_PARM_DESC(driver_mode,
"station=0x1(default), ap-sta=0x3, station-p2p=0x5, ap-sta-p2p=0x7");
+bool mfg_mode;
+module_param(mfg_mode, bool, 0);
+MODULE_PARM_DESC(mfg_mode, "0:disable 1:enable (bool)");
+
+char *mfg_firmware = "";
+module_param(mfg_firmware, charp, 0);
+MODULE_PARM_DESC(mfg_firmware, "firmware path");
+
/*
* This function registers the device and performs all the necessary
@@ -559,10 +567,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
goto done;
}
/* Wait for mwifiex_init to complete */
- wait_event_interruptible(adapter->init_wait_q,
- adapter->init_wait_q_woken);
- if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
- goto err_init_fw;
+ if (!adapter->mfg_mode) {
+ wait_event_interruptible(adapter->init_wait_q,
+ adapter->init_wait_q_woken);
+ if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
+ goto err_init_fw;
+ }
priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
if (mwifiex_register_cfg80211(adapter)) {
@@ -666,6 +676,23 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
{
int ret;
+ if (mfg_mode && !strlen(mfg_firmware)) {
+ pr_err("%s: mfg firmware missing. Ignoring manufacturing mode\n",
+ __func__);
+ mfg_mode = false;
+ }
+
+ /* Override default firmware with manufacturing one if
+ * manufacturing mode is enabled
+ */
+ if (mfg_mode) {
+ if (strlcpy(adapter->fw_name, mfg_firmware,
+ sizeof(adapter->fw_name)) >=
+ sizeof(adapter->fw_name)) {
+ pr_err("%s: fw_name too long!\n", __func__);
+ return -1;
+ }
+ }
ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
adapter->dev, GFP_KERNEL, adapter,
mwifiex_fw_dpc);
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 9f6bb40..ee71e4a 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -58,6 +58,9 @@
#include "sdio.h"
extern const char driver_version[];
+extern bool mfg_mode;
+extern char *mfg_firmware;
+
struct mwifiex_adapter;
struct mwifiex_private;
@@ -989,6 +992,7 @@ struct mwifiex_adapter {
u32 drv_info_size;
bool scan_chan_gap_enabled;
struct sk_buff_head rx_data_q;
+ bool mfg_mode;
struct mwifiex_chan_stats *chan_stats;
u32 num_in_chan_stats;
int survey_idx;
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 22fe993..e54a98a 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -226,7 +226,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
if (!adapter || !adapter->priv_num)
return;
- if (user_rmmod) {
+ if (user_rmmod && !adapter->mfg_mode) {
#ifdef CONFIG_PM_SLEEP
if (adapter->is_suspended)
mwifiex_pcie_resume(&pdev->dev);
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index d3e1561..6dba409 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -289,7 +289,7 @@ mwifiex_sdio_remove(struct sdio_func *func)
mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);
- if (user_rmmod) {
+ if (user_rmmod && !adapter->mfg_mode) {
if (adapter->is_suspended)
mwifiex_sdio_resume(adapter->dev);
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index 0857575..ba616ec 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -611,7 +611,7 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
if (!adapter->priv_num)
return;
- if (user_rmmod) {
+ if (user_rmmod && !adapter->mfg_mode) {
#ifdef CONFIG_PM
if (adapter->is_suspended)
mwifiex_usb_resume(intf);
--
1.9.1
Hi Kalle,
> -----Original Message-----
> From: Kalle Valo [mailto:[email protected]]
> Sent: Wednesday, July 13, 2016 9:20 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam
> Subject: Re: [PATCH v3 1/2] mwifiex: add manufacturing mode support
>
> Amitkumar Karwar <[email protected]> writes:
>
> > By default normal mode is chosen when driver is loaded. This patch
> > adds a provision to choose manufacturing mode via module parameters.
> >
> > Command to load driver in manufacturing mode insmod mwifiex.ko
> > mfg_mode=1 and mfg_firmware=mrvl/firmware.
> >
> > Tested-by: chunfan chen <[email protected]>
> > Signed-off-by: Amitkumar Karwar <[email protected]>
>
> Why the mfg_firmware module parameter?
It's to specify a firmware name.
Regards,
Amitkumar Karwar
Amitkumar Karwar <[email protected]> writes:
> Hi Kalle,
>
>> -----Original Message-----
>> From: Kalle Valo [mailto:[email protected]]
>> Sent: Wednesday, July 13, 2016 9:20 PM
>> To: Amitkumar Karwar
>> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam
>> Subject: Re: [PATCH v3 1/2] mwifiex: add manufacturing mode support
>>
>> Amitkumar Karwar <[email protected]> writes:
>>
>> > By default normal mode is chosen when driver is loaded. This patch
>> > adds a provision to choose manufacturing mode via module parameters.
>> >
>> > Command to load driver in manufacturing mode insmod mwifiex.ko
>> > mfg_mode=1 and mfg_firmware=mrvl/firmware.
>> >
>> > Tested-by: chunfan chen <[email protected]>
>> > Signed-off-by: Amitkumar Karwar <[email protected]>
>>
>> Why the mfg_firmware module parameter?
>
> It's to specify a firmware name.
Yeah, I got that. But why do you need that? Why not just hardcode the
firmware name in the driver, which is the normal thing to do?
--
Kalle Valo
Amitkumar Karwar <[email protected]> writes:
> By default normal mode is chosen when driver is loaded. This patch adds
> a provision to choose manufacturing mode via module parameters.
>
> Command to load driver in manufacturing mode
> insmod mwifiex.ko mfg_mode=1 and mfg_firmware=mrvl/firmware.
>
> Tested-by: chunfan chen <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>
Why the mfg_firmware module parameter?
--
Kalle Valo
Hi Kalle,
> -----Original Message-----
> From: Kalle Valo [mailto:[email protected]]
> Sent: Wednesday, July 13, 2016 9:18 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam;
> Xinming Hu
> Subject: Re: [PATCH v3 2/2] mwifiex: add hostcmd wext ioctl support
>
> Amitkumar Karwar <[email protected]> writes:
>
> > Hi Kalle,
> >
> >> -----Original Message-----
> >> From: Kalle Valo [mailto:[email protected]]
> >> Sent: Wednesday, July 13, 2016 8:44 PM
> >> To: Amitkumar Karwar
> >> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam;
> >> Xinming Hu
> >> Subject: Re: [PATCH v3 2/2] mwifiex: add hostcmd wext ioctl support
> >>
> >> Amitkumar Karwar <[email protected]> writes:
> >>
> >> > From: Xinming Hu <[email protected]>
> >> >
> >> > This patch adds ndo_ioctl support to mwifiex netdev handlers.
> >> > This will be used to download hostcmds to firmware from userspace.
> >> > This is needed for manufacturing mode support in mwifiex. ndo_ioctl
> >> > is allowed only when mfg mode is enabled via module load
> parameters.
> >> >
> >> > Signed-off-by: Xinming Hu <[email protected]>
> >> > Signed-off-by: Amitkumar Karwar <[email protected]>
> >> > ---
> >> > v3: Add "select WIRELESS_EXT" in Kconfig to resolve kbuild test
> >> > robot
> >> errors.
> >> > WEXT_PRIV seems to have a dependency with WIRELESS_EXT.
> >> > v2: 1) Sequence of these two patches are changed to resolve
> >> compilation
> >> > error seen if only 1/2 is applied.
> >> > 2) Add "select WEXT_PRIV" in Kconfig to resolve warnings
> >> > reported
> >> by
> >> > kbuild test robot.
> >>
> >> Why can't you use nl80211 testmode interface?
> >
> > These two patches facilitates user to configure manufacturing mode. We
> > have a separate firmware for this mode. It's needed to run special
> > WiFi conductive and radiated tests at factory.
>
> This is exactly what nl80211 testmode is for.
>
> > The userspace tools used for this purpose expects WEXT interface.
>
> So convert them to use nl80211. I have done that myself, multiple times
> actually.
>
> And for wireless extensions, from my point of view it's dead and buried.
> I'm not going to take any new wireless extension related code.
Thanks for your feedback. We will change the tools and prepare driver patch using nl80211 testmode.
Regards,
Amitkumar
Hi,
[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on v4.7-rc7 next-20160715]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Amitkumar-Karwar/mwifiex-add-manufacturing-mode-support/20160713-221253
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: x86_64-randconfig-r0-07162143 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/net/wireless/marvell/mwifiex/main.c:1287:2: error: unknown field 'num_private_args' specified in initializer
.num_private_args = ARRAY_SIZE(mwifiex_iwpriv_args),
^
In file included from drivers/net/wireless/marvell/mwifiex/main.h:23:0,
from drivers/net/wireless/marvell/mwifiex/main.c:20:
include/linux/kernel.h:54:25: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
^
drivers/net/wireless/marvell/mwifiex/main.c:1287:22: note: in expansion of macro 'ARRAY_SIZE'
.num_private_args = ARRAY_SIZE(mwifiex_iwpriv_args),
^~~~~~~~~~
include/linux/kernel.h:54:25: note: (near initialization for 'mwifiex_iwpriv_handler_def.standard')
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
^
drivers/net/wireless/marvell/mwifiex/main.c:1287:22: note: in expansion of macro 'ARRAY_SIZE'
.num_private_args = ARRAY_SIZE(mwifiex_iwpriv_args),
^~~~~~~~~~
drivers/net/wireless/marvell/mwifiex/main.c:1288:2: error: unknown field 'private_args' specified in initializer
.private_args = (struct iw_priv_args *)mwifiex_iwpriv_args,
^
drivers/net/wireless/marvell/mwifiex/main.c:1288:18: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
.private_args = (struct iw_priv_args *)mwifiex_iwpriv_args,
^
drivers/net/wireless/marvell/mwifiex/main.c:1288:18: note: (near initialization for 'mwifiex_iwpriv_handler_def.num_standard')
drivers/net/wireless/marvell/mwifiex/main.c:1288:18: error: initializer element is not computable at load time
drivers/net/wireless/marvell/mwifiex/main.c:1288:18: note: (near initialization for 'mwifiex_iwpriv_handler_def.num_standard')
drivers/net/wireless/marvell/mwifiex/main.c: In function 'mwifiex_init_priv_params':
>> drivers/net/wireless/marvell/mwifiex/main.c:1316:5: error: 'struct net_device' has no member named 'wireless_handlers'; did you mean 'rx_handler'?
dev->wireless_handlers = &mwifiex_iwpriv_handler_def;
^~
vim +1316 drivers/net/wireless/marvell/mwifiex/main.c
1282 "hostcmd"
1283 },
1284 };
1285
1286 static struct iw_handler_def mwifiex_iwpriv_handler_def = {
1287 .num_private_args = ARRAY_SIZE(mwifiex_iwpriv_args),
> 1288 .private_args = (struct iw_priv_args *)mwifiex_iwpriv_args,
1289 };
1290
1291 /*
1292 * This function initializes the private structure parameters.
1293 *
1294 * The following wait queues are initialized -
1295 * - IOCTL wait queue
1296 * - Command wait queue
1297 * - Statistics wait queue
1298 *
1299 * ...and the following default parameters are set -
1300 * - Current key index : Set to 0
1301 * - Rate index : Set to auto
1302 * - Media connected : Set to disconnected
1303 * - Adhoc link sensed : Set to false
1304 * - Nick name : Set to null
1305 * - Number of Tx timeout : Set to 0
1306 * - Device address : Set to current address
1307 * - Rx histogram statistc : Set to 0
1308 *
1309 * In addition, the CFG80211 work queue is also created.
1310 */
1311 void mwifiex_init_priv_params(struct mwifiex_private *priv,
1312 struct net_device *dev)
1313 {
1314 dev->netdev_ops = &mwifiex_netdev_ops;
1315 dev->destructor = free_netdev;
> 1316 dev->wireless_handlers = &mwifiex_iwpriv_handler_def;
1317 /* Initialize private structure */
1318 priv->current_key_index = 0;
1319 priv->media_connected = false;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Kalle,
> -----Original Message-----
> From: Kalle Valo [mailto:[email protected]]
> Sent: Wednesday, July 13, 2016 8:44 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam;
> Xinming Hu
> Subject: Re: [PATCH v3 2/2] mwifiex: add hostcmd wext ioctl support
>
> Amitkumar Karwar <[email protected]> writes:
>
> > From: Xinming Hu <[email protected]>
> >
> > This patch adds ndo_ioctl support to mwifiex netdev handlers.
> > This will be used to download hostcmds to firmware from userspace.
> > This is needed for manufacturing mode support in mwifiex. ndo_ioctl is
> > allowed only when mfg mode is enabled via module load parameters.
> >
> > Signed-off-by: Xinming Hu <[email protected]>
> > Signed-off-by: Amitkumar Karwar <[email protected]>
> > ---
> > v3: Add "select WIRELESS_EXT" in Kconfig to resolve kbuild test robot
> errors.
> > WEXT_PRIV seems to have a dependency with WIRELESS_EXT.
> > v2: 1) Sequence of these two patches are changed to resolve
> compilation
> > error seen if only 1/2 is applied.
> > 2) Add "select WEXT_PRIV" in Kconfig to resolve warnings reported
> by
> > kbuild test robot.
>
> Why can't you use nl80211 testmode interface?
These two patches facilitates user to configure manufacturing mode. We have a separate firmware for this mode.
It's needed to run special WiFi conductive and radiated tests at factory. The userspace tools used for this purpose expects WEXT interface.
Regards,
Amitkumar
Amitkumar Karwar <[email protected]> writes:
> Hi Kalle,
>
>> -----Original Message-----
>> From: Kalle Valo [mailto:[email protected]]
>> Sent: Wednesday, July 13, 2016 8:44 PM
>> To: Amitkumar Karwar
>> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam;
>> Xinming Hu
>> Subject: Re: [PATCH v3 2/2] mwifiex: add hostcmd wext ioctl support
>>
>> Amitkumar Karwar <[email protected]> writes:
>>
>> > From: Xinming Hu <[email protected]>
>> >
>> > This patch adds ndo_ioctl support to mwifiex netdev handlers.
>> > This will be used to download hostcmds to firmware from userspace.
>> > This is needed for manufacturing mode support in mwifiex. ndo_ioctl is
>> > allowed only when mfg mode is enabled via module load parameters.
>> >
>> > Signed-off-by: Xinming Hu <[email protected]>
>> > Signed-off-by: Amitkumar Karwar <[email protected]>
>> > ---
>> > v3: Add "select WIRELESS_EXT" in Kconfig to resolve kbuild test robot
>> errors.
>> > WEXT_PRIV seems to have a dependency with WIRELESS_EXT.
>> > v2: 1) Sequence of these two patches are changed to resolve
>> compilation
>> > error seen if only 1/2 is applied.
>> > 2) Add "select WEXT_PRIV" in Kconfig to resolve warnings reported
>> by
>> > kbuild test robot.
>>
>> Why can't you use nl80211 testmode interface?
>
> These two patches facilitates user to configure manufacturing mode. We
> have a separate firmware for this mode. It's needed to run special
> WiFi conductive and radiated tests at factory.
This is exactly what nl80211 testmode is for.
> The userspace tools used for this purpose expects WEXT interface.
So convert them to use nl80211. I have done that myself, multiple times
actually.
And for wireless extensions, from my point of view it's dead and buried.
I'm not going to take any new wireless extension related code.
--
Kalle Valo
From: Xinming Hu <[email protected]>
This patch adds ndo_ioctl support to mwifiex netdev handlers.
This will be used to download hostcmds to firmware from userspace.
This is needed for manufacturing mode support in mwifiex. ndo_ioctl
is allowed only when mfg mode is enabled via module load parameters.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
v3: Add "select WIRELESS_EXT" in Kconfig to resolve kbuild test robot errors.
WEXT_PRIV seems to have a dependency with WIRELESS_EXT.
v2: 1) Sequence of these two patches are changed to resolve compilation
error seen if only 1/2 is applied.
2) Add "select WEXT_PRIV" in Kconfig to resolve warnings reported by
kbuild test robot.
---
drivers/net/wireless/marvell/mwifiex/Kconfig | 6 +++
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 59 +++++++++++++++++++++++++++
drivers/net/wireless/marvell/mwifiex/main.c | 38 +++++++++++++++++
drivers/net/wireless/marvell/mwifiex/main.h | 9 +++-
4 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/Kconfig b/drivers/net/wireless/marvell/mwifiex/Kconfig
index 279167d..aed32ce 100644
--- a/drivers/net/wireless/marvell/mwifiex/Kconfig
+++ b/drivers/net/wireless/marvell/mwifiex/Kconfig
@@ -13,6 +13,8 @@ config MWIFIEX_SDIO
depends on MWIFIEX && MMC
select FW_LOADER
select WANT_DEV_COREDUMP
+ select WIRELESS_EXT
+ select WEXT_PRIV
---help---
This adds support for wireless adapters based on Marvell
8786/8787/8797/8887/8897/8997 chipsets with SDIO interface.
@@ -25,6 +27,8 @@ config MWIFIEX_PCIE
depends on MWIFIEX && PCI
select FW_LOADER
select WANT_DEV_COREDUMP
+ select WIRELESS_EXT
+ select WEXT_PRIV
---help---
This adds support for wireless adapters based on Marvell
8766/8897/8997 chipsets with PCIe interface.
@@ -36,6 +40,8 @@ config MWIFIEX_USB
tristate "Marvell WiFi-Ex Driver for USB8766/8797/8997"
depends on MWIFIEX && USB
select FW_LOADER
+ select WIRELESS_EXT
+ select WEXT_PRIV
---help---
This adds support for wireless adapters based on Marvell
8797/8997 chipset with USB interface.
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 8d57493..d961305 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -826,6 +826,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
hostcmd = adapter->curr_cmd->data_buf;
hostcmd->len = size;
memcpy(hostcmd->cmd, resp, size);
+ adapter->hostcmd_resp_data.len = size;
+ memcpy(adapter->hostcmd_resp_data.cmd, resp, size);
}
}
orig_cmdresp_no = le16_to_cpu(resp->command);
@@ -1208,6 +1210,63 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
false);
}
EXPORT_SYMBOL_GPL(mwifiex_process_hs_config);
+/* This function get hostcmd data from userspace and construct a cmd
+ * to be download to FW.
+ */
+int mwifiex_process_host_command(struct mwifiex_private *priv,
+ struct iwreq *wrq)
+{
+ struct mwifiex_ds_misc_cmd *hostcmd_buf;
+ struct host_cmd_ds_command *cmd;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ int ret;
+
+ hostcmd_buf = kzalloc(sizeof(*hostcmd_buf), GFP_KERNEL);
+ if (!hostcmd_buf)
+ return -ENOMEM;
+
+ cmd = (void *)hostcmd_buf->cmd;
+
+ if (copy_from_user(cmd, wrq->u.data.pointer,
+ sizeof(cmd->command) + sizeof(cmd->size))) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ hostcmd_buf->len = le16_to_cpu(cmd->size);
+ if (hostcmd_buf->len > MWIFIEX_SIZE_OF_CMD_BUFFER) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (copy_from_user(cmd, wrq->u.data.pointer, hostcmd_buf->len)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ if (mwifiex_send_cmd(priv, 0, 0, 0, hostcmd_buf, true)) {
+ dev_err(priv->adapter->dev, "Failed to process hostcmd\n");
+ ret = -EFAULT;
+ goto done;
+ }
+
+ if (adapter->hostcmd_resp_data.len > hostcmd_buf->len) {
+ ret = -EFBIG;
+ goto done;
+ }
+
+ if (copy_to_user(wrq->u.data.pointer, adapter->hostcmd_resp_data.cmd,
+ adapter->hostcmd_resp_data.len)) {
+ ret = -EFAULT;
+ goto done;
+ }
+ wrq->u.data.length = adapter->hostcmd_resp_data.len;
+
+ ret = 0;
+done:
+ kfree(hostcmd_buf);
+ return ret;
+}
/*
* This function handles the command response of a sleep confirm command.
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index b54edf4..e3e1fe9 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1238,17 +1238,54 @@ mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
return mwifiex_1d_to_wmm_queue[skb->priority];
}
+static int mwifiex_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct iwreq *wrq = (struct iwreq *)req;
+ int ret;
+
+ if (!priv->adapter->mfg_mode)
+ return -EINVAL;
+
+ dev_dbg(priv->adapter->dev, "ioctl cmd = 0x%x\n", cmd);
+
+ switch (cmd) {
+ case MWIFIEX_HOSTCMD_IOCTL:
+ ret = mwifiex_process_host_command(priv, wrq);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
/* Network device handlers */
static const struct net_device_ops mwifiex_netdev_ops = {
.ndo_open = mwifiex_open,
.ndo_stop = mwifiex_close,
.ndo_start_xmit = mwifiex_hard_start_xmit,
.ndo_set_mac_address = mwifiex_set_mac_address,
+ .ndo_do_ioctl = mwifiex_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = mwifiex_tx_timeout,
.ndo_get_stats = mwifiex_get_stats,
.ndo_set_rx_mode = mwifiex_set_multicast_list,
.ndo_select_queue = mwifiex_netdev_select_wmm_queue,
+ };
+
+static const struct iw_priv_args mwifiex_iwpriv_args[] = {
+ { MWIFIEX_HOSTCMD_IOCTL,
+ IW_PRIV_TYPE_BYTE | 2047,
+ IW_PRIV_TYPE_BYTE | 2047,
+ "hostcmd"
+ },
+};
+
+static struct iw_handler_def mwifiex_iwpriv_handler_def = {
+ .num_private_args = ARRAY_SIZE(mwifiex_iwpriv_args),
+ .private_args = (struct iw_priv_args *)mwifiex_iwpriv_args,
};
/*
@@ -1276,6 +1313,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
{
dev->netdev_ops = &mwifiex_netdev_ops;
dev->destructor = free_netdev;
+ dev->wireless_handlers = &mwifiex_iwpriv_handler_def;
/* Initialize private structure */
priv->current_key_index = 0;
priv->media_connected = false;
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index ee71e4a..5713fe5 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -48,6 +48,8 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/of_irq.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
#include "decl.h"
#include "ioctl.h"
@@ -160,6 +162,9 @@ enum {
/* Threshold for tx_timeout_cnt before we trigger a card reset */
#define TX_TIMEOUT_THRESHOLD 6
+/* IOCTL number used for hostcmd process*/
+#define MWIFIEX_HOSTCMD_IOCTL (SIOCIWFIRSTPRIV + 17)
+
#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000
/* Address alignment */
@@ -895,6 +900,7 @@ struct mwifiex_adapter {
u8 event_received;
u8 data_received;
u16 seq_num;
+ struct mwifiex_ds_misc_cmd hostcmd_resp_data;
struct cmd_ctrl_node *cmd_pool;
struct cmd_ctrl_node *curr_cmd;
/* spin lock for command */
@@ -1557,7 +1563,8 @@ bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
u32 pri_chan, u8 chan_bw);
int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter);
-
+int mwifiex_process_host_command(struct mwifiex_private *priv,
+ struct iwreq *wrq);
int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb);
void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv);
void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv,
--
1.9.1
Amitkumar Karwar <[email protected]> writes:
> From: Xinming Hu <[email protected]>
>
> This patch adds ndo_ioctl support to mwifiex netdev handlers.
> This will be used to download hostcmds to firmware from userspace.
> This is needed for manufacturing mode support in mwifiex. ndo_ioctl
> is allowed only when mfg mode is enabled via module load parameters.
>
> Signed-off-by: Xinming Hu <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> ---
> v3: Add "select WIRELESS_EXT" in Kconfig to resolve kbuild test robot errors.
> WEXT_PRIV seems to have a dependency with WIRELESS_EXT.
> v2: 1) Sequence of these two patches are changed to resolve compilation
> error seen if only 1/2 is applied.
> 2) Add "select WEXT_PRIV" in Kconfig to resolve warnings reported by
> kbuild test robot.
Why can't you use nl80211 testmode interface?
--
Kalle Valo
Hi Kalle,
> -----Original Message-----
> From: Kalle Valo [mailto:[email protected]]
> Sent: Wednesday, July 13, 2016 10:01 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam
> Subject: Re: [PATCH v3 1/2] mwifiex: add manufacturing mode support
>
> Amitkumar Karwar <[email protected]> writes:
>
> > Hi Kalle,
> >
> >> -----Original Message-----
> >> From: Kalle Valo [mailto:[email protected]]
> >> Sent: Wednesday, July 13, 2016 9:20 PM
> >> To: Amitkumar Karwar
> >> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam
> >> Subject: Re: [PATCH v3 1/2] mwifiex: add manufacturing mode support
> >>
> >> Amitkumar Karwar <[email protected]> writes:
> >>
> >> > By default normal mode is chosen when driver is loaded. This patch
> >> > adds a provision to choose manufacturing mode via module
> parameters.
> >> >
> >> > Command to load driver in manufacturing mode insmod mwifiex.ko
> >> > mfg_mode=1 and mfg_firmware=mrvl/firmware.
> >> >
> >> > Tested-by: chunfan chen <[email protected]>
> >> > Signed-off-by: Amitkumar Karwar <[email protected]>
> >>
> >> Why the mfg_firmware module parameter?
> >
> > It's to specify a firmware name.
>
> Yeah, I got that. But why do you need that? Why not just hardcode the
> firmware name in the driver, which is the normal thing to do?
Ok. I will do this in updated version.
Regards,
Amitkumar