Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Williams @ 2019-06-26 16:02 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Philip Rakity, libertas-dev, kernel-janitors, linux-wireless,
	Lubomir Rintel, Kalle Valo, Allison Randal
In-Reply-To: <20190626132340.GE28859@kadam>

On Wed, 2019-06-26 at 16:23 +0300, Dan Carpenter wrote:
> Yeah.  That looks nicer.  Could you send it as a proper patch and
> give
> me Reported-by credit?

Will do.

Dan


^ permalink raw reply

* pull-request: wireless-drivers-next 2019-06-26
From: Kalle Valo @ 2019-06-26 15:59 UTC (permalink / raw)
  To: David Miller; +Cc: linux-wireless, netdev, linux-kernel

Hi Dave,

here's a pull request to net-next for 5.3, more info below. Please let
me know if there are any problems.

Kalle

The following changes since commit f4aa80129ff71909380ee0bde8be36c5cc031d4c:

  cxgb4: Make t4_get_tp_e2c_map static (2019-05-26 22:16:26 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git tags/wireless-drivers-next-for-davem-2019-06-26

for you to fetch changes up to e5db0ad7563c38b7b329504836c9a64ae025a47a:

  airo: switch to skcipher interface (2019-06-25 08:12:20 +0300)

----------------------------------------------------------------
wireless-drivers-next patches for 5.3

First set of patches for 5.3, but not that many patches this time.

This pull request fails to compile with the tip tree due to
ktime_get_boot_ns() API changes there. It should be easy for Linus to
fix it in p54 driver once he pulls this, an example resolution here:

https://lkml.kernel.org/r/20190625160432.533aa140@canb.auug.org.au

Major changes:

airo

* switch to use skcipher interface

p54

* support boottime in scan results

rtw88

* add fast xmit support

* add random mac address on scan support

rt2x00

* add software watchdog to detect hangs, it's disabled by default

----------------------------------------------------------------
Ahmad Masri (1):
      wil6210: fix overwriting max_assoc_sta module param

Alagu Sankar (3):
      ath10k: htt: don't use txdone_fifo with SDIO
      ath10k: htt: support MSDU ids with SDIO
      ath10k: add initialization of HTC header

Alan Stern (1):
      p54usb: Fix race between disconnect and firmware loading

Alexei Avshalom Lazar (1):
      wil6210: fix _desc access in __wil_tx_vring_tso

Anilkumar Kolli (1):
      ath: DFS JP domain W56 fixed pulse type 3 RADAR detection

Ard Biesheuvel (1):
      airo: switch to skcipher interface

Arend van Spriel (6):
      brcm80211: switch common header files to using SPDX license identifier
      brcmutil: switch source files to using SPDX license identifier
      brcmsmac: switch phy source files to using SPDX license identifier
      brcmfmac: switch source files to using SPDX license identifier
      brcmfmac: use separate Kconfig file for brcmfmac
      brcm80211: select WANT_DEV_COREDUMP conditionally for brcmfmac

Arnd Bergmann (1):
      wireless: carl9170: fix clang build warning

Balaji Pothunoori (1):
      ath10k: rx_duration update for fw_stats debugfs entry

Brandon Huang (1):
      ath10k: Fix the tx stats bytes & packets parsing

Brian Norris (2):
      mwifiex: drop 'set_consistent_dma_mask' log message
      mwifiex: print PCI mmap with %pK

Chien-Hsun Liao (2):
      rtw88: 8822c: add rf write protection when switching channel
      rtw88: 8822c: update channel and bandwidth BB setting

Chin-Yen Lee (1):
      rtw88: add beacon function setting

Christian Lamparter (3):
      p54: fix crash during initialization
      p54: Support boottime in scan results
      p54: remove dead branch in op_conf_tx callback

Colin Ian King (5):
      ath6kl: remove redundant check of status != 0
      libertas: fix spelling mistake "Donwloading" -> "Downloading"
      rtlwifi: remove redundant assignment to variable badworden
      rtlwifi: remove redundant assignment to variable k
      rtlwifi: rtl8188ee: remove redundant assignment to rtstatus

Dan Carpenter (1):
      ath6kl: add some bounds checking

Dedy Lansky (3):
      wil6210: add printout of platform capabilities
      wil6210: enhancements for descriptor and status ring debugfs
      wil6210: check rx_buff_mgmt before accessing it

Erik Stromdahl (1):
      ath10k: sdio: add missing error check

Govind Singh (2):
      ath10k: Move board id and fw version logging to info level
      ath10k: Modify CE4 src buffer entries to 2048 for WCN3990

Greg Kroah-Hartman (2):
      iwlegacy: 3945: no need to check return value of debugfs_create functions
      iwlegacy: 4965: no need to check return value of debugfs_create functions

Gustavo A. R. Silva (6):
      ath6kl: debug: Use struct_size() helper
      ath6kl: wmi: use struct_size() helper
      wil6210: fix potential out-of-bounds read
      ath10k: Use struct_size() helper
      ath10k: coredump: use struct_size() helper
      qtnfmac: Use struct_size() in kzalloc()

Jia-Ju Bai (1):
      b43: Avoid possible double calls to b43_one_core_detach()

Kalle Valo (3):
      ath10k: initialise struct ath10k_bus params to zero
      ath10k: fix use-after-free on SDIO data frames
      Merge ath-next from git://git.kernel.org/.../kvalo/ath.git

Larry Finger (4):
      rtlwifi: rtl8821ae: Remove unused GET_XXX and SET_XXX descriptor macros
      rtlwifi: rtl8821ae: Replace local bit manipulation macros
      rtlwifi: rtl8821ae: Convert macros that set descriptor
      rtlwifi: rtl8821ae: Convert inline routines to little-endian words

Lorenzo Bianconi (2):
      mt7601u: do not schedule rx_tasklet when the device has been disconnected
      mt7601u: fix possible memory leak when the device is disconnected

Maharaja Kennadyrajan (2):
      ath10k: Extended the HTT stats support to retrieve Mu-MIMO related stats
      ath10k: Added support to reset HTT stats in debugfs

Maya Erez (4):
      wil6210: fix spurious interrupts in 3-msi
      wil6210: add support for multiple sections in brd file
      wil6210: fix missed MISC mbox interrupt
      wil6210: remove HALP for Talyn devices

Michael Buesch (1):
      ssb/gpio: Remove unnecessary WARN_ON from driver_gpio

Neo Jou (1):
      brcmfmac: use strlcpy() instead of strcpy()

Ping-Ke Shih (5):
      rtlwifi: 8192de: Reduce indentation and fix coding style
      rtlwifi: 8192de: make tables to be 'static const'
      rtlwifi: 8192de: Fix used uninitialized variables in power tracking
      rtlwifi: 8192de: use le32 to access cckswing tables
      rtlwifi: rtl8192cu: fix error handle when usb probe failed

Pradeep kumar Chitrapu (1):
      ath10k: fix incorrect multicast/broadcast rate setting

Rakesh Pillai (1):
      ath10k: Fix encoding for protected management frames

Sharvari Harisangam (1):
      mwifiex: update set_mac_address logic

Stanislaw Gruszka (7):
      rt2x00: allow to specify watchdog interval
      rt2800: add helpers for reading dma done index
      rt2800: initial watchdog implementation
      rt2800: add pre_reset_hw callback
      rt2800: do not nullify initialization vector data
      rt2x00: add restart hw
      rt2800: do not enable watchdog by default

Surabhi Vishnoi (4):
      ath10k: Fix the wrong value of enums for wmi tlv stats id
      ath10k: Add wmi tlv vdev subtype for mesh in WCN3990
      ath10k: Do not send probe response template for mesh
      ath10k: Add wmi tlv service map for mesh 11s

Sven Eckelmann (1):
      ath9k: Differentiate between max combined and per chain power

Swati Kushwaha (1):
      mwifiex: ignore processing invalid command response

Tim Schumacher (1):
      ath9k: Check for errors when reading SREV register

Toke Høiland-Jørgensen (1):
      ath9k: Don't trust TX status TID number when reporting airtime

Tomislav Požega (2):
      ath: drop duplicated define
      ath9k: drop redundant code in ar9003_hw_set_channel

Tzu-En Huang (1):
      rtw88: fix typo rtw_writ16_set

Weitao Hou (1):
      brcmfmac: fix typos in code comments

Wen Gong (9):
      ath10k: sdio: workaround firmware UART pin configuration bug
      ath10k: don't disable interrupts in ath10k_sdio_remove()
      ath10k: add struct for high latency PN replay protection
      ath10k: add handler for HTT_T2H_MSG_TYPE_SEC_IND event
      ath10k: add PN replay protection for high latency devices
      ath10k: add fragmentation handler for high latency devices
      ath10k: enable QCA6174 hw3.2 SDIO hardware
      ath10k: change swap mail box config for UTF mode of SDIO
      ath10k: add peer id check in ath10k_peer_find_by_id

Yan-Hsuan Chuang (10):
      rtw88: pci: use ieee80211_ac_numbers instead of 0-3
      rtw88: pci: check if queue mapping exceeds size of ac_to_hwq
      rtw88: more descriptions about LPS
      rtw88: add fast xmit support
      rtw88: add support for random mac scan
      rtw88: 8822c: disable rx clock gating before counter reset
      rtw88: 8822c: use more accurate ofdm fa counting
      rtw88: power on again if it was already on
      rtw88: restore DACK results to save time
      rtw88: rsvd page should go though management queue

Yingying Tang (1):
      ath10k: Check tx_stats before use it

YueHaibing (4):
      ath9k: Remove some set but not used variables
      rtlwifi: rtl8821ae: Remove set but not used variables 'cur_txokcnt' and 'b_last_is_cur_rdl_state'
      rtlwifi: btcoex: Remove set but not used variable 'len' and 'asso_type_v2'
      rtlwifi: btcoex: remove unused function exhalbtc_stack_operation_notify

 drivers/net/wireless/ath/ath10k/ahb.c              |   2 +-
 drivers/net/wireless/ath/ath10k/core.c             |  48 +-
 drivers/net/wireless/ath/ath10k/core.h             |  12 +-
 drivers/net/wireless/ath/ath10k/coredump.c         |   4 +-
 drivers/net/wireless/ath/ath10k/debug.c            |  50 +-
 drivers/net/wireless/ath/ath10k/debugfs_sta.c      |   7 +
 drivers/net/wireless/ath/ath10k/htc.c              |   1 +
 drivers/net/wireless/ath/ath10k/htt.h              |  60 +-
 drivers/net/wireless/ath/ath10k/htt_rx.c           | 387 ++++++++++-
 drivers/net/wireless/ath/ath10k/htt_tx.c           |  29 +-
 drivers/net/wireless/ath/ath10k/hw.h               |   6 +
 drivers/net/wireless/ath/ath10k/mac.c              |  14 +-
 drivers/net/wireless/ath/ath10k/pci.c              |   2 +-
 drivers/net/wireless/ath/ath10k/qmi.c              |  15 +-
 drivers/net/wireless/ath/ath10k/sdio.c             |  18 +-
 drivers/net/wireless/ath/ath10k/snoc.c             |   4 +-
 drivers/net/wireless/ath/ath10k/txrx.c             |   3 +
 drivers/net/wireless/ath/ath10k/usb.c              |   2 +-
 drivers/net/wireless/ath/ath10k/wmi-tlv.c          |  28 +-
 drivers/net/wireless/ath/ath10k/wmi-tlv.h          |  12 +
 drivers/net/wireless/ath/ath10k/wmi.c              |  37 +-
 drivers/net/wireless/ath/ath10k/wmi.h              |   7 +-
 drivers/net/wireless/ath/ath6kl/debug.c            |   3 +-
 drivers/net/wireless/ath/ath6kl/htc_pipe.c         |   3 -
 drivers/net/wireless/ath/ath6kl/wmi.c              |  13 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        |  24 +-
 drivers/net/wireless/ath/ath9k/eeprom.c            |   2 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |   1 +
 drivers/net/wireless/ath/ath9k/hw.c                |  40 +-
 drivers/net/wireless/ath/ath9k/hw.h                |   1 +
 drivers/net/wireless/ath/ath9k/init.c              |   2 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |  18 +-
 drivers/net/wireless/ath/carl9170/mac.c            |   2 +-
 drivers/net/wireless/ath/carl9170/rx.c             |   2 +-
 drivers/net/wireless/ath/dfs_pattern_detector.c    |   2 +-
 drivers/net/wireless/ath/regd.h                    |   1 -
 drivers/net/wireless/ath/wil6210/cfg80211.c        |   4 +-
 drivers/net/wireless/ath/wil6210/debugfs.c         |  70 +-
 drivers/net/wireless/ath/wil6210/fw.h              |  11 +-
 drivers/net/wireless/ath/wil6210/fw_inc.c          | 148 +++--
 drivers/net/wireless/ath/wil6210/interrupt.c       |  67 +-
 drivers/net/wireless/ath/wil6210/main.c            |  18 +-
 drivers/net/wireless/ath/wil6210/pcie_bus.c        |   2 +
 drivers/net/wireless/ath/wil6210/rx_reorder.c      |   2 +-
 drivers/net/wireless/ath/wil6210/txrx.c            |  26 +-
 drivers/net/wireless/ath/wil6210/txrx_edma.c       |  10 +-
 drivers/net/wireless/ath/wil6210/wil6210.h         |  33 +-
 drivers/net/wireless/ath/wil6210/wmi.c             |  14 +-
 drivers/net/wireless/broadcom/b43/main.c           |   7 +-
 drivers/net/wireless/broadcom/brcm80211/Kconfig    |  52 +-
 drivers/net/wireless/broadcom/brcm80211/Makefile   |  14 +-
 .../wireless/broadcom/brcm80211/brcmfmac/Kconfig   |  50 ++
 .../wireless/broadcom/brcm80211/brcmfmac/Makefile  |  14 +-
 .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/btcoex.c  |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/btcoex.h  |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  13 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         |  13 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.h         |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/chip.h    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  15 +-
 .../wireless/broadcom/brcm80211/brcmfmac/common.h  |  16 +-
 .../broadcom/brcm80211/brcmfmac/commonring.c       |  16 +-
 .../broadcom/brcm80211/brcmfmac/commonring.h       |  16 +-
 .../wireless/broadcom/brcm80211/brcmfmac/core.c    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/debug.c   |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/debug.h   |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/feature.h |  13 +-
 .../broadcom/brcm80211/brcmfmac/firmware.c         |  13 +-
 .../broadcom/brcm80211/brcmfmac/firmware.h         |  13 +-
 .../broadcom/brcm80211/brcmfmac/flowring.c         |  16 +-
 .../broadcom/brcm80211/brcmfmac/flowring.h         |  16 +-
 .../wireless/broadcom/brcm80211/brcmfmac/fweh.c    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/fweh.h    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/fwil.c    |  15 +-
 .../wireless/broadcom/brcm80211/brcmfmac/fwil.h    |  13 +-
 .../broadcom/brcm80211/brcmfmac/fwil_types.h       |  13 +-
 .../broadcom/brcm80211/brcmfmac/fwsignal.c         |  13 +-
 .../broadcom/brcm80211/brcmfmac/fwsignal.h         |  14 +-
 .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c  |  16 +-
 .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h  |  16 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/of.c  |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/of.h  |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.h |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  16 +-
 .../wireless/broadcom/brcm80211/brcmfmac/pcie.h    |  16 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/proto.c   |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/proto.h   |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h    |  13 +-
 .../broadcom/brcm80211/brcmfmac/tracepoint.c       |  13 +-
 .../broadcom/brcm80211/brcmfmac/tracepoint.h       |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/usb.h |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/vendor.c  |  13 +-
 .../wireless/broadcom/brcm80211/brcmfmac/vendor.h  |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_cmn.c      |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_hal.h      |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_int.h      |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_lcn.c      |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_lcn.h      |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_qmath.c    |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_qmath.h    |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_radio.h    |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phyreg_n.h     |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.c   |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.h   |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phytbl_n.c     |  13 +-
 .../broadcom/brcm80211/brcmsmac/phy/phytbl_n.h     |  13 +-
 .../wireless/broadcom/brcm80211/brcmutil/Makefile  |  13 +-
 .../net/wireless/broadcom/brcm80211/brcmutil/d11.c |  13 +-
 .../wireless/broadcom/brcm80211/brcmutil/utils.c   |  13 +-
 .../broadcom/brcm80211/include/brcm_hw_ids.h       |  13 +-
 .../broadcom/brcm80211/include/brcmu_d11.h         |  13 +-
 .../broadcom/brcm80211/include/brcmu_utils.h       |  13 +-
 .../broadcom/brcm80211/include/brcmu_wifi.h        |  13 +-
 .../broadcom/brcm80211/include/chipcommon.h        |  13 +-
 .../net/wireless/broadcom/brcm80211/include/defs.h |  13 +-
 .../net/wireless/broadcom/brcm80211/include/soc.h  |  13 +-
 drivers/net/wireless/cisco/Kconfig                 |   2 +
 drivers/net/wireless/cisco/airo.c                  |  57 +-
 drivers/net/wireless/intel/iwlegacy/3945-rs.c      |  14 +-
 drivers/net/wireless/intel/iwlegacy/3945.h         |   3 -
 drivers/net/wireless/intel/iwlegacy/4965-rs.c      |  31 +-
 drivers/net/wireless/intel/iwlegacy/common.h       |   4 -
 drivers/net/wireless/intersil/p54/main.c           |   9 +-
 drivers/net/wireless/intersil/p54/p54usb.c         |  43 +-
 drivers/net/wireless/intersil/p54/txrx.c           |  11 +-
 drivers/net/wireless/marvell/libertas/if_usb.c     |   2 +-
 drivers/net/wireless/marvell/libertas_tf/if_usb.c  |   2 +-
 drivers/net/wireless/marvell/mwifiex/cmdevt.c      |  27 +-
 drivers/net/wireless/marvell/mwifiex/main.c        |   6 +-
 drivers/net/wireless/marvell/mwifiex/main.h        |   2 +-
 drivers/net/wireless/marvell/mwifiex/pcie.c        |   5 +-
 drivers/net/wireless/mediatek/mt7601u/dma.c        |  54 +-
 drivers/net/wireless/mediatek/mt7601u/tx.c         |   4 +-
 drivers/net/wireless/quantenna/qtnfmac/commands.c  |   5 +-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c     |  96 ++-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h     |  11 +
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.c    |  31 +
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.h    |   2 +
 drivers/net/wireless/ralink/rt2x00/rt2800pci.c     |   3 +
 drivers/net/wireless/ralink/rt2x00/rt2800soc.c     |   3 +
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c     |  11 +
 drivers/net/wireless/ralink/rt2x00/rt2x00.h        |  10 +
 drivers/net/wireless/ralink/rt2x00/rt2x00debug.c   |  35 +
 drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  10 +-
 drivers/net/wireless/ralink/rt2x00/rt2x00link.c    |  15 +-
 drivers/net/wireless/ralink/rt2x00/rt2x00queue.h   |   6 +
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c       |  35 +-
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h       |   1 -
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c   |   3 +-
 drivers/net/wireless/realtek/rtlwifi/efuse.c       |   5 +-
 .../net/wireless/realtek/rtlwifi/rtl8188ee/hw.c    |   2 +-
 .../net/wireless/realtek/rtlwifi/rtl8192de/dm.c    | 695 ++++++++++----------
 .../net/wireless/realtek/rtlwifi/rtl8821ae/dm.c    |   8 +-
 .../net/wireless/realtek/rtlwifi/rtl8821ae/trx.c   | 253 ++++----
 .../net/wireless/realtek/rtlwifi/rtl8821ae/trx.h   | 708 +++++++++++----------
 drivers/net/wireless/realtek/rtlwifi/usb.c         |   5 +-
 drivers/net/wireless/realtek/rtlwifi/wifi.h        |   1 +
 drivers/net/wireless/realtek/rtw88/hci.h           |   2 +-
 drivers/net/wireless/realtek/rtw88/mac.c           |   8 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c      |  32 +
 drivers/net/wireless/realtek/rtw88/main.c          |  10 +-
 drivers/net/wireless/realtek/rtw88/main.h          |  11 +
 drivers/net/wireless/realtek/rtw88/pci.c           |  10 +-
 drivers/net/wireless/realtek/rtw88/phy.c           |  13 +-
 drivers/net/wireless/realtek/rtw88/rtw8822c.c      | 436 ++++++++++++-
 drivers/net/wireless/realtek/rtw88/rtw8822c.h      |  23 +
 drivers/net/wireless/realtek/rtw88/tx.c            |   2 +-
 drivers/ssb/driver_gpio.c                          |   6 -
 181 files changed, 2885 insertions(+), 2322 deletions(-)
 create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig

^ permalink raw reply

* Re: [PATCH] ath: fix SPDX tags
From: Kalle Valo @ 2019-06-26 15:10 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless
In-Reply-To: <1561474345-1439-1-git-send-email-kvalo@codeaurora.org>

Kalle Valo <kvalo@codeaurora.org> wrote:

> Commit ec8f24b7faaf ("treewide: Add SPDX license identifier -
> Makefile/Kconfig") marked various Makefiles and Kconfig files within ath
> directories as GPL-2.0. But these modules and drivers are actually ISC:
> 
> * ath
> * ar5523
> * ath10k
> * ath5k
> * ath6kl
> * ath9k
> * wcn36xx
> * wil6210
> 
> Fix SPDX tags accordingly.
> 
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to wireless-drivers.git, thanks.

e780d22757fb ath: fix SPDX tags

-- 
https://patchwork.kernel.org/patch/11015875/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH] carl9170: fix enum compare splat
From: Kalle Valo @ 2019-06-26 14:17 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless
In-Reply-To: <4392478.8kWN0Ehzps@debian64>

Christian Lamparter <chunkeey@gmail.com> writes:

> On Tuesday, June 18, 2019 2:11:53 PM CEST Kalle Valo wrote:
>> Christian Lamparter <chunkeey@gmail.com> writes:
>> > On Monday, June 10, 2019 9:06:30 AM CEST Kalle Valo wrote:
>> >> Christian Lamparter <chunkeey@gmail.com> writes:
>> >> 
>> >> > This patch fixes a noisy warning triggered by -Wenum-compare
>> >> >
>> >> > |main.c:1390:31: warning: comparison between ‘enum nl80211_ac’
>> >> > |	and ‘enum ar9170_txq’ [-Wenum-compare]
>> >> > |  BUILD_BUG_ON(NL80211_NUM_ACS > __AR9170_NUM_TXQ);
>> >> > |                               ^
>> >> > | [...]
>> >> >
>> >> > This is a little bit unfortunate, since the number of queues
>> >> > (hence NL80211_NUM_ACS) is a constant based on the IEEE 802.11
>> >> > (much like IEEE80211_NUM_ACS) and __AR9170_NUM_TXQ is more or
>> >> > less defined by the AR9170 hardware.
>> >> 
>> >> Is the warning enabled by default? TBH I'm not seeing how useful this
>> >> warning is for kernel development.
>> >
>> > It is included in the "-Wall" (which is coming from "KBUILD_CFLAGS" 
>> > in the main Makefile).
>> >
>> > I tried debian's gcc starting from 4.6 to the lastest 8.3. They all
>> > complain about it in various degrees.
>> >
>> > https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html#Warning-Options
>> 
>> Ok, odd that I haven't noticed this warning. Maybe I have been just
>> blind.
>
> Sorry. No, I messed up there. I made a patch back in the day during the spectre
> mac80211 patches that I kept in my tree for the driver. But I now remember that
> I never published those because of that exact "warning".
> These lines are coming from there.
>  
>> >> > --- a/drivers/net/wireless/ath/carl9170/main.c
>> >> > +++ b/drivers/net/wireless/ath/carl9170/main.c
>> >> > @@ -1387,7 +1387,7 @@ static int carl9170_op_conf_tx(struct ieee80211_hw *hw,
>> >> >  	int ret;
>> >> >  
>> >> >  	BUILD_BUG_ON(ARRAY_SIZE(ar9170_qmap) != __AR9170_NUM_TXQ);
>> >> > -	BUILD_BUG_ON(NL80211_NUM_ACS > __AR9170_NUM_TXQ);
>> >> > +	BUILD_BUG_ON((size_t)NL80211_NUM_ACS > (size_t)__AR9170_NUM_TXQ);
>> >> 
>> >> IMHO this just makes the code worse. Does it make sense to workaround
>> >> (stupid) compiler warnings like this?
>> >
>> > True. What's worse: This isn't really code. The BUILD_BUG_ON Macro is there
>> > to guard but it's getting compiled away. I could also just drop it.
>> 
>> Either way is fine for me. If the GCC (by default) emits a warning for
>> this we need to silence that warning, so in that respect I guess we
>> should apply this. Unless better solutions come up, of course :)
>
> Note: I dropped this patch from patchwork. So, there's nothing that
> needs to be done now ;)

Thanks, except I would prefer that I drop the patch myself :) In
numerous cases I have been wondering there a patch has disappeared and
only after a while I realise the submitter deleted the patch altogether
(which also destroys the conversation from patchwork etc). IMHO that's
really bad UX in patchwork, I should file a bug report about that.

So in general it's enough to say "Kalle, please drop the patch" and I'll
do the rest.

> Well, except OT: Would you mind adding the QCA4019 boardfiles that
> have accumulated over the past six-ish months?

Yeah, those are in my queue. But I'll first want to implement a script
so that I don't need to manually add all of them and I just haven't
found the time for that.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] rt2x00: fix rx queue hang
From: Soeren Moch @ 2019-06-26 13:28 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Helmut Schaa, Kalle Valo, David S. Miller, linux-wireless, netdev,
	linux-kernel, stable
In-Reply-To: <20190625095734.GA2886@redhat.com>

On 25.06.19 11:57, Stanislaw Gruszka wrote:
> Hello
>
> On Fri, Jun 21, 2019 at 01:30:01PM +0200, Soeren Moch wrote:
>> On 18.06.19 11:34, Stanislaw Gruszka wrote:
>>> Hi
>>>
>>> On Mon, Jun 17, 2019 at 11:46:56AM +0200, Soeren Moch wrote:
>>>> Since commit ed194d136769 ("usb: core: remove local_irq_save() around
>>>>  ->complete() handler") the handlers rt2x00usb_interrupt_rxdone() and
>>>> rt2x00usb_interrupt_txdone() are not running with interrupts disabled
>>>> anymore. So these handlers are not guaranteed to run completely before
>>>> workqueue processing starts. So only mark entries ready for workqueue
>>>> processing after proper accounting in the dma done queue.
>>> It was always the case on SMP machines that rt2x00usb_interrupt_{tx/rx}done
>>> can run concurrently with rt2x00_work_{rx,tx}done, so I do not
>>> understand how removing local_irq_save() around complete handler broke
>>> things.
>> I think because completion handlers can be interrupted now and scheduled
>> away
>> in the middle of processing.
>>> Have you reverted commit ed194d136769 and the revert does solve the problem ?
>> Yes, I already sent a patch for this, see [1]. But this was not considered
>> an acceptablesolution. Especially RT folks do not like code running with
>> interrupts disabled,particularly when trying to acquire spinlocks then.
>>
>> [1] https://lkml.org/lkml/2019/5/31/863
>>> Between 4.19 and 4.20 we have some quite big changes in rt2x00 driver:
>>>
>>> 0240564430c0 rt2800: flush and txstatus rework for rt2800mmio
>>> adf26a356f13 rt2x00: use different txstatus timeouts when flushing
>>> 5022efb50f62 rt2x00: do not check for txstatus timeout every time on tasklet
>>> 0b0d556e0ebb rt2800mmio: use txdone/txstatus routines from lib
>>> 5c656c71b1bf rt2800: move usb specific txdone/txstatus routines to rt2800lib
>>>
>>> so I'm a bit afraid that one of those changes is real cause of
>>> the issue not ed194d136769 .
>> I tested 4.20 and 5.1 and see the exact same behavior. Reverting this
>> usb core patchsolves the problem.
>> 4.19.x (before this usb core patch) is running fine.
>>>> Note that rt2x00usb_work_rxdone() processes all available entries, not
>>>> only such for which queue_work() was called.
>>>>
>>>> This fixes a regression on a RT5370 based wifi stick in AP mode, which
>>>> suddenly stopped data transmission after some period of heavy load. Also
>>>> stopping the hanging hostapd resulted in the error message "ieee80211
>>>> phy0: rt2x00queue_flush_queue: Warning - Queue 14 failed to flush".
>>>> Other operation modes are probably affected as well, this just was
>>>> the used testcase.
>>> Do you know what actually make the traffic stop,
>>> TX queue hung or RX queue hung?
>> I think RX queue hang, as stated in the patch title. "Queue 14" means QID_RX
>> (rt2x00queue.h, enum data_queue_qid).
>> I also tried to re-add local_irq_save() in only one of the handlers. Adding
>> this tort2x00usb_interrupt_rxdone() alone solved the issue, while doing so
>> for tx alonedid not.
>>
>> Note that this doesn't mean there is no problem for tx, that's maybe
>> just more
>> difficult to trigger.
>>>> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> index 1b08b01db27b..9c102a501ee6 100644
>>>> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> @@ -263,9 +263,9 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
>>>>
>>>>  void rt2x00lib_dmadone(struct queue_entry *entry)
>>>>  {
>>>> -	set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
>>>>  	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
>>>>  	rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE);
>>>> +	set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
>>> Unfortunately I do not understand how this suppose to fix the problem,
>>> could you elaborate more about this change?
>>>
>> Re-adding local_irq_save() around thisrt2x00lib_dmadone()solved
>> the issue. So I also tried to reverse the order of these calls.
>> It seems totally plausible to me, that the correct sequence is to
>> first clear the device assignment, then to set the status to dma_done,
>> then to trigger the workqueue processing for this entry. When the handler
>> is scheduled away in the middle of this sequence, now there is no
>> strange state where the entry can be processed by the workqueue while
>> not declared dma_done for it.
>> With this changed sequence there is no need anymore to disable interrupts
>> for solving the hang issue.
> Thanks very much for explanations. However I still do not fully
> understand the issue. Q_INDEX_DMA_DONE index is only checked on TX
> processing (on RX we use only Q_INDEX_DONE and Q_INDEX) and
> ENTRY_OWNER_DEVICE_DATA is already cleared before rt2x00lib_dmadone()
> in rt2x00usb_interrupt_rxdone() .
>
> So I'm not sure how changing the order solve the problem. Looks
> for me that the issue is triggered by some rt2x00lib_dmadone()
> call done on error path (not in rt2x00usb_interrupt_rxdone())
> and it race with this check:
>
>         if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
>             test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
>                 return false;
>
> in rt2x00usb_kick_rx_entry() - we return instead of submit urb.
Hi Stanislaw,

the good news is: your patch below also solves the issue for me. But
removing the ENTRY_DATA_STATUS_PENDING check in
rt2x00usb_kick_rx_entry() alone does not help, while removing this check
in rt2x00usb_work_rxdone() alone does the trick.

So the real race seems to be that the flags set in the completion
handler are not yet visible on the cpu core running the workqueue. And
because the worker is not rescheduled when aborted, the entry can just
wait forever.
Do you think this could make sense?
> I'm somewhat reluctant to change the order, because TX processing
> might relay on it (we first mark we wait for TX status and
> then mark entry is no longer owned by hardware).
OK, maybe it's just good luck that changing the order solves the rx
problem. Or can memory barriers associated with the spinlock in
rt2x00lib_dmadone() be responsible for that?
(I'm testing on a armv7 system, Cortex-A9 quadcore.)

While looking at it, why we double-clear ENTRY_OWNER_DEVICE_DATA in
rt2x00usb_interrupt_rxdone() directly and in rt2x00lib_dmadone() again,
while not doing the same for tx? Would it make more sense to possibly
set ENTRY_DATA_IO_FAILED before clearing ENTRY_OWNER_DEVICE_DATA in
rt2x00usb_interrupt_rxdone() as for tx?
>  However on RX
> side ENTRY_DATA_STATUS_PENDING bit make no sense as we do not
> wait for status. We should remove ENTRY_DATA_STATUS_PENDING on
> RX side and perhaps this also will solve issue you observe.
I agree that removing the unnecessary checks is a good idea in any case.
> Could you please check below patch, if it fixes the problem as well?
At least I could not trigger the problem within transferring 10GB of
data. But maybe the probability for triggering this bug is just lower
because ENTRY_OWNER_DEVICE_DATA is cleared some time before
ENTRY_DATA_STATUS_PENDING is set?

Soeren
>
> Stanislaw
>
> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> index b6c1344..731e633 100644
> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> @@ -360,8 +360,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
>  	while (!rt2x00queue_empty(rt2x00dev->rx)) {
>  		entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
>  
> -		if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
> -		    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> +		if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
>  			break;
>  
>  		/*
> @@ -413,8 +412,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
>  	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
>  	int status;
>  
> -	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
> -	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> +	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
>  		return false;
>  
>  	rt2x00lib_dmastart(entry);



^ permalink raw reply

* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Carpenter @ 2019-06-26 13:23 UTC (permalink / raw)
  To: Dan Williams
  Cc: Kalle Valo, Philip Rakity, Lubomir Rintel, kernel-janitors,
	linux-wireless, Allison Randal, libertas-dev
In-Reply-To: <be491ab35ba46111a1c90cc12b6d5ff6ea3f57e8.camel@redhat.com>

Yeah.  That looks nicer.  Could you send it as a proper patch and give
me Reported-by credit?

regards,
dan carpenter


^ permalink raw reply

* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Williams @ 2019-06-26 13:16 UTC (permalink / raw)
  To: Dan Carpenter, Kalle Valo, Philip Rakity
  Cc: Lubomir Rintel, kernel-janitors, linux-wireless, Allison Randal,
	libertas-dev
In-Reply-To: <20190626100926.GD3242@mwanda>

On Wed, 2019-06-26 at 13:09 +0300, Dan Carpenter wrote:
> The lbs_process_rxed_packet() frees the skb.  It didn't originally,
> but
> we fixed it in commit f54930f36311 ("libertas: don't leak skb on
> receive
> error").
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
>  drivers/net/wireless/marvell/libertas/if_spi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c
> b/drivers/net/wireless/marvell/libertas/if_spi.c
> index 27067e79e83f..e38f02d1f2e4 100644
> --- a/drivers/net/wireless/marvell/libertas/if_spi.c
> +++ b/drivers/net/wireless/marvell/libertas/if_spi.c
> @@ -772,7 +772,7 @@ static int if_spi_c2h_data(struct if_spi_card
> *card)
>  	/* pass the SKB to libertas */
>  	err = lbs_process_rxed_packet(card->priv, skb);
>  	if (err)
> -		goto free_skb;
> +		goto out;  /* lbs_process_rxed_packet() frees skb */
>  
>  	/* success */
>  	goto out;

It can be further simplified (not compile tested yet):

diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
index 27067e79e83fe..072da89c4986f 100644
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
@@ -766,19 +766,15 @@ static int if_spi_c2h_data(struct if_spi_card *card)
 
 	/* Read the data from the WLAN module into our skb... */
 	err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
-	if (err)
-		goto free_skb;
+	if (err) {
+		dev_kfree_skb(skb);
+		goto out
+	}
 
 	/* pass the SKB to libertas */
 	err = lbs_process_rxed_packet(card->priv, skb);
-	if (err)
-		goto free_skb;
+	/* lbs_process_rxed_packet() consumes the skb */
 
-	/* success */
-	goto out;
-
-free_skb:
-	dev_kfree_skb(skb);
 out:
 	if (err)
 		netdev_err(priv->dev, "%s: err=%d\n", __func__, err);


^ permalink raw reply related

* [PATCH 6/8] staging: wilc1000: remove use of 'src_addr' element in 'wilc_vif' struct
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Remove use of 'src_addr' element in wilc_vif, as the same information
already copied to net_device->dev_addr.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/wilc_netdev.c            | 3 +--
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h     | 1 -
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 0af60b2..565e2b5 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -638,8 +638,7 @@ static int wilc_mac_open(struct net_device *ndev)
 
 	wilc_get_mac_address(vif, mac_add);
 	netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
-	memcpy(vif->src_addr, mac_add, ETH_ALEN);
-	memcpy(ndev->dev_addr, vif->src_addr, ETH_ALEN);
+	ether_addr_copy(ndev->dev_addr, mac_add);
 
 	if (!is_valid_ether_addr(ndev->dev_addr)) {
 		netdev_err(ndev, "Wrong MAC address\n");
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 1580909..d72fdd3 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1499,7 +1499,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
 	if (ret != 0)
 		netdev_err(dev, "Error in setting channel\n");
 
-	wilc_wlan_set_bssid(dev, vif->src_addr, WILC_AP_MODE);
+	wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
 	wilc_set_power_mgmt(vif, 0, 0);
 
 	return wilc_add_beacon(vif, settings->beacon_interval,
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index d5d830d..e28c8de 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -198,7 +198,6 @@ struct wilc_vif {
 	struct frame_reg frame_reg[NUM_REG_FRAME];
 	struct net_device_stats netstats;
 	struct wilc *wilc;
-	u8 src_addr[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
 	struct host_if_drv *hif_drv;
 	struct net_device *ndev;
-- 
2.7.4


^ permalink raw reply related

* [PATCH 8/8] staging: wilc1000: rename 'host_interface' source and header
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Rename 'host_interface' source and header file to include the 'wilc_'
prefix in its name.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/Makefile                         | 2 +-
 drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} | 0
 drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} | 0
 drivers/staging/wilc1000/wilc_wfi_netdevice.h             | 2 +-
 4 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} (100%)
 rename drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} (100%)

diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile
index 2ad3fee..a5a8e80 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/staging/wilc1000/Makefile
@@ -5,7 +5,7 @@ ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
 		-DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
 
 wilc1000-objs := wilc_wfi_cfgoperations.o wilc_netdev.o wilc_mon.o \
-			host_interface.o wilc_wlan_cfg.o wilc_wlan.o
+			wilc_hif.o wilc_wlan_cfg.o wilc_wlan.o
 
 obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
 wilc1000-sdio-objs += wilc_sdio.o
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/wilc_hif.c
similarity index 100%
rename from drivers/staging/wilc1000/host_interface.c
rename to drivers/staging/wilc1000/wilc_hif.c
diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/wilc_hif.h
similarity index 100%
rename from drivers/staging/wilc1000/host_interface.h
rename to drivers/staging/wilc1000/wilc_hif.h
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index e28c8de..1e74a08 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -14,7 +14,7 @@
 #include <linux/if_arp.h>
 #include <linux/gpio/consumer.h>
 
-#include "host_interface.h"
+#include "wilc_hif.h"
 #include "wilc_wlan.h"
 #include "wilc_wlan_cfg.h"
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH 4/8] staging: wilc1000: remove use of driver_handler_id & ifc_id
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Removed the 'driver_handler_id' & 'ifc_id' elements and used 'idx' to
identify the handler.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c         | 3 +--
 drivers/staging/wilc1000/host_interface.h         | 1 -
 drivers/staging/wilc1000/wilc_netdev.c            | 3 +--
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 ++---
 drivers/staging/wilc1000/wilc_wfi_netdevice.h     | 1 -
 5 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index b505990..389f9f8c 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1472,7 +1472,7 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
 	drv.mode = (ifc_id | (mode << 1));
 
 	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      hif_drv->driver_handler_id);
+				      wilc_get_vif_idx(vif));
 	if (result)
 		netdev_err(vif->ndev, "Failed to set driver handler\n");
 
@@ -1644,7 +1644,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
 	for (i = 0; i < wilc->vif_num; i++)
 		if (dev == wilc->vif[i]->ndev) {
 			wilc->vif[i]->hif_drv = hif_drv;
-			hif_drv->driver_handler_id = i + 1;
 			break;
 		}
 
diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h
index 4fcc7a3..be1d249 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -166,7 +166,6 @@ struct host_if_drv {
 	struct wilc_vif *remain_on_ch_timer_vif;
 
 	bool ifc_up;
-	int driver_handler_id;
 	u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
 };
 
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 9006111..ad04744 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -636,7 +636,7 @@ static int wilc_mac_open(struct net_device *ndev)
 	for (i = 0; i < wl->vif_num; i++) {
 		if (ndev == wl->vif[i]->ndev) {
 			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-						 vif->iftype, vif->ifc_id);
+						 vif->iftype, vif->idx);
 			wilc_set_operation_mode(vif, vif->iftype);
 			break;
 		}
@@ -995,7 +995,6 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
 	ndev->needs_free_netdev = true;
 	vif->iftype = vif_type;
 	vif->wilc->vif[wl->vif_num] = vif;
-	vif->ifc_id = wl->vif_num;
 	vif->idx = wl->vif_num;
 	wl->vif_num += 1;
 	vif->mac_opened = 0;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 012e325..1580909 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1462,7 +1462,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 
 		if (wl->initialized) {
 			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-						 0, vif->ifc_id);
+						 0, vif->idx);
 			wilc_set_operation_mode(vif, WILC_AP_MODE);
 			wilc_set_power_mgmt(vif, 0, 0);
 		}
@@ -1693,11 +1693,10 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 			wl->vif[i] = NULL;
 		} else {
 			vif = wl->vif[i + 1];
-			vif->ifc_id = i;
 			vif->idx = i;
 			wl->vif[i] = vif;
 			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-						 vif->iftype, vif->ifc_id);
+						 vif->iftype, vif->idx);
 		}
 	}
 	wl->vif_num--;
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index fca3380..d5d830d 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -203,7 +203,6 @@ struct wilc_vif {
 	struct host_if_drv *hif_drv;
 	struct net_device *ndev;
 	u8 mode;
-	u8 ifc_id;
 	struct timer_list during_ip_timer;
 	bool obtaining_ip;
 	struct timer_list periodic_rssi;
-- 
2.7.4


^ permalink raw reply related

* [PATCH 7/8] staging: wilc1000: remove extra argument passing to wilc_send_config_pkt()
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Cleanup patch to remove the passing of driver handler, get the 'idx'
value inside the called function.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c | 116 ++++++++++--------------------
 drivers/staging/wilc1000/wilc_wlan.c      |   3 +-
 drivers/staging/wilc1000/wilc_wlan.h      |   2 +-
 3 files changed, 40 insertions(+), 81 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 3688088..9345cab 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -205,9 +205,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
 		wid.val = (s8 *)&abort_running_scan;
 		wid.size = sizeof(char);
 
-		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-					      wilc_get_vif_idx(vif));
-
+		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 		if (result) {
 			netdev_err(vif->ndev, "Failed to set abort running\n");
 			result = -EFAULT;
@@ -328,9 +326,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
 	hif_drv->usr_scan_req.scan_result = scan_result_fn;
 	hif_drv->usr_scan_req.arg = user_arg;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-				      index,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, index);
 	if (result) {
 		netdev_err(vif->ndev, "Failed to send scan parameters\n");
 		goto error;
@@ -380,9 +376,7 @@ static int wilc_send_connect_wid(struct wilc_vif *vif)
 	wid_list[wid_cnt].val = (u8 *)bss_param;
 	wid_cnt++;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-				      wid_cnt,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, wid_cnt);
 	if (result) {
 		netdev_err(vif->ndev, "failed to send config packet\n");
 		goto error;
@@ -430,8 +424,7 @@ static void handle_connect_timeout(struct work_struct *work)
 	wid.val = (s8 *)&dummy_reason_code;
 	wid.size = sizeof(char);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send disconnect\n");
 
@@ -619,8 +612,7 @@ static void host_int_get_assoc_res_info(struct wilc_vif *vif,
 	wid.val = assoc_resp_info;
 	wid.size = max_assoc_resp_info_len;
 
-	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
 	if (result) {
 		*rcvd_assoc_resp_info_len = 0;
 		netdev_err(vif->ndev, "Failed to send association response\n");
@@ -783,8 +775,7 @@ int wilc_disconnect(struct wilc_vif *vif)
 	vif->obtaining_ip = false;
 	wilc_set_power_mgmt(vif, 0, 0);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result) {
 		netdev_err(vif->ndev, "Failed to send disconnect\n");
 		return result;
@@ -864,10 +855,7 @@ int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
 	wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
 	wid_cnt++;
 
-	result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list,
-				      wid_cnt,
-				      wilc_get_vif_idx(vif));
-
+	result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list, wid_cnt);
 	if (result) {
 		netdev_err(vif->ndev, "Failed to send scan parameters\n");
 		return result;
@@ -950,8 +938,7 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
 	wid.val[0] = remain_on_chan_flag;
 	wid.val[1] = (s8)hif_remain_ch->ch;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	kfree(wid.val);
 	if (result)
 		return -EBUSY;
@@ -986,8 +973,7 @@ static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
 		wid.val[0] = remain_on_chan_flag;
 		wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
 
-		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-					      wilc_get_vif_idx(vif));
+		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 		kfree(wid.val);
 		if (result != 0) {
 			netdev_err(vif->ndev, "Failed to set remain channel\n");
@@ -1062,8 +1048,7 @@ static void handle_set_mcast_filter(struct work_struct *work)
 	if (set_mc->cnt > 0 && set_mc->mc_list)
 		memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send setup multicast\n");
 
@@ -1139,8 +1124,7 @@ int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
 	wid.size = sizeof(char);
 	wid.val = &index;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev,
 			   "Failed to send remove wep key config packet\n");
@@ -1156,8 +1140,7 @@ int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
 	wid.type = WID_CHAR;
 	wid.size = sizeof(char);
 	wid.val = &index;
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev,
 			   "Failed to send wep default key config packet\n");
@@ -1185,8 +1168,7 @@ int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
 	wep_key->key_len = len;
 	memcpy(wep_key->key, key, len);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev,
 			   "Failed to add wep key config packet\n");
@@ -1225,8 +1207,7 @@ int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
 	wep_key->key_len = len;
 	memcpy(wep_key->key, key, len);
 	result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-				      ARRAY_SIZE(wid_list),
-				      wilc_get_vif_idx(vif));
+				      ARRAY_SIZE(wid_list));
 	if (result)
 		netdev_err(vif->ndev,
 			   "Failed to add wep ap key config packet\n");
@@ -1273,8 +1254,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
 		wid_list[1].size = sizeof(*key_buf) + t_key_len;
 		wid_list[1].val = (u8 *)key_buf;
 		result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-					      ARRAY_SIZE(wid_list),
-					      wilc_get_vif_idx(vif));
+					      ARRAY_SIZE(wid_list));
 		kfree(key_buf);
 	} else if (mode == WILC_STATION_MODE) {
 		struct wid wid;
@@ -1300,8 +1280,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
 		wid.type = WID_STR;
 		wid.size = sizeof(*key_buf) + t_key_len;
 		wid.val = (s8 *)key_buf;
-		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-					      wilc_get_vif_idx(vif));
+		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 		kfree(key_buf);
 	}
 
@@ -1353,8 +1332,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
 		wid_list[1].val = (u8 *)gtk_key;
 
 		result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-					      ARRAY_SIZE(wid_list),
-					      wilc_get_vif_idx(vif));
+					      ARRAY_SIZE(wid_list));
 	} else if (mode == WILC_STATION_MODE) {
 		struct wid wid;
 
@@ -1362,8 +1340,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
 		wid.type = WID_STR;
 		wid.size = sizeof(*gtk_key) + t_key_len;
 		wid.val = (u8 *)gtk_key;
-		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-					      wilc_get_vif_idx(vif));
+		result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	}
 
 	kfree(gtk_key);
@@ -1379,8 +1356,7 @@ int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid)
 	wid.size = (pmkid->numpmkid * sizeof(struct wilc_pmkid)) + 1;
 	wid.val = (u8 *)pmkid;
 
-	return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				    wilc_get_vif_idx(vif));
+	return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 }
 
 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
@@ -1393,8 +1369,7 @@ int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
 	wid.size = ETH_ALEN;
 	wid.val = mac_addr;
 
-	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to get mac address\n");
 
@@ -1444,8 +1419,7 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
 	wid.size = sizeof(char);
 	wid.val = &channel;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to set channel\n");
 
@@ -1471,8 +1445,7 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
 	drv.handler = cpu_to_le32(index);
 	drv.mode = (ifc_id | (mode << 1));
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to set driver handler\n");
 
@@ -1492,8 +1465,7 @@ int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
 
 	op_mode.mode = cpu_to_le32(mode);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to set operation mode\n");
 
@@ -1513,8 +1485,7 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
 		return -ENOMEM;
 
 	ether_addr_copy(wid.val, mac);
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	kfree(wid.val);
 	if (result) {
 		netdev_err(vif->ndev, "Failed to set inactive mac\n");
@@ -1525,8 +1496,7 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
 	wid.type = WID_INT;
 	wid.val = (s8 *)out_val;
 	wid.size = sizeof(u32);
-	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to get inactive time\n");
 
@@ -1547,8 +1517,7 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
 	wid.type = WID_CHAR;
 	wid.size = sizeof(char);
 	wid.val = rssi_level;
-	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to get RSSI value\n");
 
@@ -1610,8 +1579,7 @@ int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
 		i++;
 	}
 
-	return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-				    i, wilc_get_vif_idx(vif));
+	return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, i);
 }
 
 static void get_periodic_rssi(struct timer_list *t)
@@ -1876,8 +1844,7 @@ void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
 		break;
 	}
 	reg_frame.frame_type = cpu_to_le16(frame_type);
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to frame register\n");
 }
@@ -1914,8 +1881,7 @@ int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
 	if (params->tail_len > 0)
 		memcpy(cur_byte, params->tail, params->tail_len);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send add beacon\n");
 
@@ -1935,8 +1901,7 @@ int wilc_del_beacon(struct wilc_vif *vif)
 	wid.size = sizeof(char);
 	wid.val = &del_beacon;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send delete beacon\n");
 
@@ -1960,8 +1925,7 @@ int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
 	cur_byte = wid.val;
 	wilc_hif_pack_sta_param(cur_byte, mac, params);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result != 0)
 		netdev_err(vif->ndev, "Failed to send add station\n");
 
@@ -1987,8 +1951,7 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
 	else
 		ether_addr_copy(wid.val, mac_addr);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to del station\n");
 
@@ -2023,8 +1986,7 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
 	wid.size = (assoc_sta * ETH_ALEN) + 1;
 	wid.val = (u8 *)&del_sta;
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send delete all station\n");
 
@@ -2048,8 +2010,7 @@ int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
 	cur_byte = wid.val;
 	wilc_hif_pack_sta_param(cur_byte, mac, params);
 
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send edit station\n");
 
@@ -2074,8 +2035,7 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
 	wid.id = WID_POWER_MANAGEMENT;
 	wid.val = &power_mode;
 	wid.size = sizeof(char);
-	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				      wilc_get_vif_idx(vif));
+	result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 	if (result)
 		netdev_err(vif->ndev, "Failed to send power management\n");
 
@@ -2113,8 +2073,7 @@ int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
 	wid.val = &tx_power;
 	wid.size = sizeof(char);
 
-	return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
-				   wilc_get_vif_idx(vif));
+	return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
 }
 
 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
@@ -2126,6 +2085,5 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
 	wid.val = tx_power;
 	wid.size = sizeof(char);
 
-	return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
-				    wilc_get_vif_idx(vif));
+	return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
 }
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index bd2ffc3..d46876e 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1202,10 +1202,11 @@ int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size)
 }
 
 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
-			 u32 count, u32 drv)
+			 u32 count)
 {
 	int i;
 	int ret = 0;
+	u32 drv = wilc_get_vif_idx(vif);
 
 	if (mode == WILC_GET_CFG) {
 		for (i = 0; i < count; i++) {
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 3e54a56..d2eef7b 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -307,7 +307,7 @@ void host_sleep_notify(struct wilc *wilc);
 void chip_allow_sleep(struct wilc *wilc);
 void chip_wakeup(struct wilc *wilc);
 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
-			 u32 count, u32 drv);
+			 u32 count);
 int wilc_wlan_init(struct net_device *dev);
 u32 wilc_get_chipid(struct wilc *wilc, bool update);
 #endif
-- 
2.7.4


^ permalink raw reply related

* [PATCH 5/8] staging: wilc1000: remove unnecessary loop to traverse vif interfaces
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Cleanup patch to avoid loop to traverse the interfaces instead make use
of vif received from net_device priv data.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c |  7 +------
 drivers/staging/wilc1000/wilc_netdev.c    | 16 +++++-----------
 2 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 389f9f8c..3688088 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1634,19 +1634,14 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
 	struct host_if_drv *hif_drv;
 	struct wilc_vif *vif = netdev_priv(dev);
 	struct wilc *wilc = vif->wilc;
-	int i;
 
 	hif_drv  = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
 	if (!hif_drv)
 		return -ENOMEM;
 
 	*hif_drv_handler = hif_drv;
-	for (i = 0; i < wilc->vif_num; i++)
-		if (dev == wilc->vif[i]->ndev) {
-			wilc->vif[i]->hif_drv = hif_drv;
-			break;
-		}
 
+	vif->hif_drv = hif_drv;
 	vif->obtaining_ip = false;
 
 	if (wilc->clients_count == 0)
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index ad04744..0af60b2 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -614,7 +614,6 @@ static int wilc_mac_open(struct net_device *ndev)
 	struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr);
 	unsigned char mac_add[ETH_ALEN] = {0};
 	int ret = 0;
-	int i = 0;
 
 	if (!wl || !wl->dev) {
 		netdev_err(ndev, "device not ready\n");
@@ -633,19 +632,14 @@ static int wilc_mac_open(struct net_device *ndev)
 		return ret;
 	}
 
-	for (i = 0; i < wl->vif_num; i++) {
-		if (ndev == wl->vif[i]->ndev) {
-			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-						 vif->iftype, vif->idx);
-			wilc_set_operation_mode(vif, vif->iftype);
-			break;
-		}
-	}
+	wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), vif->iftype,
+				 vif->idx);
+	wilc_set_operation_mode(vif, vif->iftype);
 
 	wilc_get_mac_address(vif, mac_add);
 	netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
-	memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
-	memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
+	memcpy(vif->src_addr, mac_add, ETH_ALEN);
+	memcpy(ndev->dev_addr, vif->src_addr, ETH_ALEN);
 
 	if (!is_valid_ether_addr(ndev->dev_addr)) {
 		netdev_err(ndev, "Wrong MAC address\n");
-- 
2.7.4


^ permalink raw reply related

* [PATCH 3/8] staging: wilc1000: added support to dynamically add/remove interfaces
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Removed the use of two hardcoded interfaces and added support to
add/remove the network interfaces dynamically.
Now the driver will have single default interface with name 'wlan0' and
later other interface can be added from user space application e.g
using 'iw add' command.
Also taken care to maintain 'wilc_vif' as part of 'net_device'
private data and 'wilc' struct as 'wiphy' private data.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/wilc_mon.c               |   9 +-
 drivers/staging/wilc1000/wilc_netdev.c            | 269 ++++-------
 drivers/staging/wilc1000/wilc_sdio.c              |   7 +-
 drivers/staging/wilc1000/wilc_spi.c               |   3 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 535 ++++++++++++++--------
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.h |  13 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h     |  20 +-
 drivers/staging/wilc1000/wilc_wlan.c              |  20 +-
 drivers/staging/wilc1000/wilc_wlan.h              |   6 +-
 9 files changed, 492 insertions(+), 390 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_mon.c b/drivers/staging/wilc1000/wilc_mon.c
index 9fe19a3..7d7933d4 100644
--- a/drivers/staging/wilc1000/wilc_mon.c
+++ b/drivers/staging/wilc1000/wilc_mon.c
@@ -233,6 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
 	strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
 	wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
 	wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
+	wl->monitor_dev->needs_free_netdev = true;
 
 	if (register_netdevice(wl->monitor_dev)) {
 		netdev_err(real_dev, "register_netdevice failed\n");
@@ -247,12 +248,14 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
 	return wl->monitor_dev;
 }
 
-void wilc_wfi_deinit_mon_interface(struct wilc *wl)
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked)
 {
 	if (!wl->monitor_dev)
 		return;
 
-	unregister_netdev(wl->monitor_dev);
-	free_netdev(wl->monitor_dev);
+	if (rtnl_locked)
+		unregister_netdevice(wl->monitor_dev);
+	else
+		unregister_netdev(wl->monitor_dev);
 	wl->monitor_dev = NULL;
 }
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 0e0a4ee..9006111 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -97,22 +97,29 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
 {
 	u8 *bssid, *bssid1;
 	int i = 0;
+	struct net_device *ndev = NULL;
 
 	bssid = mac_header + 10;
 	bssid1 = mac_header + 4;
 
+	mutex_lock(&wilc->vif_mutex);
 	for (i = 0; i < wilc->vif_num; i++) {
 		if (wilc->vif[i]->mode == WILC_STATION_MODE)
 			if (ether_addr_equal_unaligned(bssid,
-						       wilc->vif[i]->bssid))
-				return wilc->vif[i]->ndev;
+						       wilc->vif[i]->bssid)) {
+				ndev = wilc->vif[i]->ndev;
+				goto out;
+			}
 		if (wilc->vif[i]->mode == WILC_AP_MODE)
 			if (ether_addr_equal_unaligned(bssid1,
-						       wilc->vif[i]->bssid))
-				return wilc->vif[i]->ndev;
+						       wilc->vif[i]->bssid)) {
+				ndev = wilc->vif[i]->ndev;
+				goto out;
+			}
 	}
-
-	return NULL;
+out:
+	mutex_unlock(&wilc->vif_mutex);
+	return ndev;
 }
 
 void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
@@ -143,9 +150,7 @@ static int wilc_txq_task(void *vp)
 {
 	int ret;
 	u32 txq_count;
-	struct net_device *dev = vp;
-	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wl = vif->wilc;
+	struct wilc *wl = vp;
 
 	complete(&wl->txq_thread_started);
 	while (1) {
@@ -159,14 +164,18 @@ static int wilc_txq_task(void *vp)
 			break;
 		}
 		do {
-			ret = wilc_wlan_handle_txq(dev, &txq_count);
+			ret = wilc_wlan_handle_txq(wl, &txq_count);
 			if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
-				if (wl->vif[0]->mac_opened &&
-				    netif_queue_stopped(wl->vif[0]->ndev))
-					netif_wake_queue(wl->vif[0]->ndev);
-				if (wl->vif[1]->mac_opened &&
-				    netif_queue_stopped(wl->vif[1]->ndev))
-					netif_wake_queue(wl->vif[1]->ndev);
+				int i;
+				struct wilc_vif *ifc;
+
+				mutex_lock(&wl->vif_mutex);
+				for (i = 0; i < wl->vif_num; i++) {
+					ifc = wl->vif[i];
+					if (ifc->mac_opened && ifc->ndev)
+						netif_wake_queue(ifc->ndev);
+				}
+				mutex_unlock(&wl->vif_mutex);
 			}
 		} while (ret == -ENOBUFS && !wl->close);
 	}
@@ -245,14 +254,13 @@ static int wilc1000_firmware_download(struct net_device *dev)
 
 static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif)
 {
-	struct wilc_priv *priv;
+	struct wilc_priv *priv = &vif->priv;
 	struct host_if_drv *hif_drv;
 	u8 b;
 	u16 hw;
 	u32 w;
 
 	netdev_dbg(dev, "Start configuring Firmware\n");
-	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
 	hif_drv = (struct host_if_drv *)priv->hif_drv;
 	netdev_dbg(dev, "Host = %p\n", hif_drv);
 
@@ -424,6 +432,7 @@ static void wlan_deinit_locks(struct net_device *dev)
 	mutex_destroy(&wilc->rxq_cs);
 	mutex_destroy(&wilc->cfg_cmd_lock);
 	mutex_destroy(&wilc->txq_add_to_head_cs);
+	mutex_destroy(&wilc->vif_mutex);
 }
 
 static void wlan_deinitialize_threads(struct net_device *dev)
@@ -477,31 +486,12 @@ static void wilc_wlan_deinitialize(struct net_device *dev)
 	}
 }
 
-static void wlan_init_locks(struct net_device *dev)
-{
-	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wl = vif->wilc;
-
-	mutex_init(&wl->hif_cs);
-	mutex_init(&wl->rxq_cs);
-	mutex_init(&wl->cfg_cmd_lock);
-
-	spin_lock_init(&wl->txq_spinlock);
-	mutex_init(&wl->txq_add_to_head_cs);
-
-	init_completion(&wl->txq_event);
-
-	init_completion(&wl->cfg_event);
-	init_completion(&wl->sync_event);
-	init_completion(&wl->txq_thread_started);
-}
-
 static int wlan_initialize_threads(struct net_device *dev)
 {
 	struct wilc_vif *vif = netdev_priv(dev);
 	struct wilc *wilc = vif->wilc;
 
-	wilc->txq_thread = kthread_run(wilc_txq_task, (void *)dev,
+	wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc,
 				       "K_TXQ_TASK");
 	if (IS_ERR(wilc->txq_thread)) {
 		netdev_err(dev, "couldn't create TXQ thread\n");
@@ -513,6 +503,12 @@ static int wlan_initialize_threads(struct net_device *dev)
 	return 0;
 }
 
+static int dev_state_ev_handler(struct notifier_block *this,
+				unsigned long event, void *ptr);
+static struct notifier_block g_dev_notifier = {
+	.notifier_call = dev_state_ev_handler
+};
+
 static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 {
 	int ret = 0;
@@ -522,13 +518,9 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 		wl->mac_status = WILC_MAC_STATUS_INIT;
 		wl->close = 0;
 
-		wlan_init_locks(dev);
-
 		ret = wilc_wlan_init(dev);
-		if (ret < 0) {
-			ret = -EIO;
-			goto fail_locks;
-		}
+		if (ret < 0)
+			return -EIO;
 
 		ret = wlan_initialize_threads(dev);
 		if (ret < 0) {
@@ -582,7 +574,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 			ret = -EIO;
 			goto fail_fw_start;
 		}
-
+		register_inetaddr_notifier(&g_dev_notifier);
 		wl->initialized = true;
 		return 0;
 
@@ -600,8 +592,6 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 		wlan_deinitialize_threads(dev);
 fail_wilc_wlan:
 		wilc_wlan_cleanup(dev);
-fail_locks:
-		wlan_deinit_locks(dev);
 		netdev_err(dev, "WLAN initialization FAILED\n");
 	} else {
 		netdev_dbg(dev, "wilc1000 already initialized\n");
@@ -758,16 +748,19 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	vif->netstats.tx_packets++;
 	vif->netstats.tx_bytes += tx_data->size;
-	tx_data->bssid = wilc->vif[vif->idx]->bssid;
 	queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
 						tx_data->buff, tx_data->size,
 						wilc_tx_complete);
 
 	if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
-		if (wilc->vif[0]->mac_opened)
-			netif_stop_queue(wilc->vif[0]->ndev);
-		if (wilc->vif[1]->mac_opened)
-			netif_stop_queue(wilc->vif[1]->ndev);
+		int i;
+
+		mutex_lock(&wilc->vif_mutex);
+		for (i = 0; i < wilc->vif_num; i++) {
+			if (wilc->vif[i]->mac_opened)
+				netif_stop_queue(wilc->vif[i]->ndev);
+		}
+		mutex_unlock(&wilc->vif_mutex);
 	}
 
 	return 0;
@@ -794,6 +787,7 @@ static int wilc_mac_close(struct net_device *ndev)
 	if (wl->open_ifcs == 0) {
 		netdev_dbg(ndev, "Deinitializing wilc1000\n");
 		wl->close = 1;
+		unregister_inetaddr_notifier(&g_dev_notifier);
 		wilc_wlan_deinitialize(ndev);
 	}
 
@@ -848,18 +842,23 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
 	int i = 0;
 	struct wilc_vif *vif;
 
+	mutex_lock(&wilc->vif_mutex);
 	for (i = 0; i < wilc->vif_num; i++) {
+		u16 type = le16_to_cpup((__le16 *)buff);
+
 		vif = netdev_priv(wilc->vif[i]->ndev);
+		if ((type == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
+		    (type == vif->frame_reg[1].type && vif->frame_reg[1].reg)) {
+			wilc_wfi_p2p_rx(vif, buff, size);
+			break;
+		}
+
 		if (vif->monitor_flag) {
 			wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size);
-			return;
+			break;
 		}
 	}
-
-	vif = netdev_priv(wilc->vif[1]->ndev);
-	if ((buff[0] == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
-	    (buff[0] == vif->frame_reg[1].type && vif->frame_reg[1].reg))
-		wilc_wfi_p2p_rx(wilc->vif[1]->ndev, buff, size);
+	mutex_unlock(&wilc->vif_mutex);
 }
 
 static const struct net_device_ops wilc_netdev_ops = {
@@ -890,14 +889,10 @@ static int dev_state_ev_handler(struct notifier_block *this,
 	if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
 		return NOTIFY_DONE;
 
-	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
-	if (!priv)
-		return NOTIFY_DONE;
+	vif = netdev_priv(dev);
+	priv = &vif->priv;
 
 	hif_drv = (struct host_if_drv *)priv->hif_drv;
-	vif = netdev_priv(dev);
-	if (!vif || !hif_drv)
-		return NOTIFY_DONE;
 
 	switch (event) {
 	case NETDEV_UP:
@@ -932,10 +927,6 @@ static int dev_state_ev_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block g_dev_notifier = {
-	.notifier_call = dev_state_ev_handler
-};
-
 void wilc_netdev_cleanup(struct wilc *wilc)
 {
 	int i;
@@ -943,136 +934,72 @@ void wilc_netdev_cleanup(struct wilc *wilc)
 	if (!wilc)
 		return;
 
-	if (wilc->vif[0]->ndev || wilc->vif[1]->ndev)
-		unregister_inetaddr_notifier(&g_dev_notifier);
-
 	if (wilc->firmware) {
 		release_firmware(wilc->firmware);
 		wilc->firmware = NULL;
 	}
 
-	for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) {
-		if (wilc->vif[i] && wilc->vif[i]->ndev) {
+	for (i = 0; i < wilc->vif_num; i++) {
+		if (wilc->vif[i] && wilc->vif[i]->ndev)
 			unregister_netdev(wilc->vif[i]->ndev);
-			wilc_free_wiphy(wilc->vif[i]->ndev);
-			free_netdev(wilc->vif[i]->ndev);
-		}
 	}
 
-	wilc_wfi_deinit_mon_interface(wilc);
+	wilc_wfi_deinit_mon_interface(wilc, false);
 	flush_workqueue(wilc->hif_workqueue);
 	destroy_workqueue(wilc->hif_workqueue);
 	wilc_wlan_cfg_deinit(wilc);
 	kfree(wilc->bus_data);
-	kfree(wilc);
+	wiphy_unregister(wilc->wiphy);
+	wiphy_free(wilc->wiphy);
 }
 EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
 
-int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
-		     const struct wilc_hif_func *ops)
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+				      int vif_type, enum nl80211_iftype type,
+				      bool rtnl_locked)
 {
-	int i, ret;
-	struct wilc_vif *vif;
 	struct net_device *ndev;
-	struct wilc *wl;
-
-	wl = kzalloc(sizeof(*wl), GFP_KERNEL);
-	if (!wl)
-		return -ENOMEM;
-
-	ret = wilc_wlan_cfg_init(wl);
-	if (ret)
-		goto free_wl;
-
-	*wilc = wl;
-	wl->io_type = io_type;
-	wl->hif_func = ops;
-	wl->enable_ps = true;
-	wl->chip_ps_state = WILC_CHIP_WAKEDUP;
-	INIT_LIST_HEAD(&wl->txq_head.list);
-	INIT_LIST_HEAD(&wl->rxq_head.list);
-
-	wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
-	if (!wl->hif_workqueue) {
-		ret = -ENOMEM;
-		goto free_cfg;
-	}
-
-	register_inetaddr_notifier(&g_dev_notifier);
-
-	for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) {
-		struct wireless_dev *wdev;
+	struct wilc_vif *vif;
+	int ret;
 
-		ndev = alloc_etherdev(sizeof(struct wilc_vif));
-		if (!ndev) {
-			ret = -ENOMEM;
-			goto free_ndev;
-		}
+	ndev = alloc_etherdev(sizeof(*vif));
+	if (!ndev)
+		return ERR_PTR(-ENOMEM);
 
-		vif = netdev_priv(ndev);
+	vif = netdev_priv(ndev);
+	ndev->ieee80211_ptr = &vif->priv.wdev;
+	strcpy(ndev->name, name);
+	vif->wilc = wl;
+	vif->ndev = ndev;
+	ndev->ml_priv = vif;
 
-		if (i == 0) {
-			strcpy(ndev->name, "wlan%d");
-			vif->ifc_id = 1;
-		} else {
-			strcpy(ndev->name, "p2p%d");
-			vif->ifc_id = 0;
-		}
-		vif->wilc = *wilc;
-		vif->ndev = ndev;
-		wl->vif[i] = vif;
-		wl->vif_num = i + 1;
-		vif->idx = i;
-
-		ndev->netdev_ops = &wilc_netdev_ops;
-
-		wdev = wilc_create_wiphy(ndev, dev);
-		if (!wdev) {
-			netdev_err(ndev, "Can't register WILC Wiphy\n");
-			ret = -ENOMEM;
-			goto free_ndev;
-		}
+	ndev->netdev_ops = &wilc_netdev_ops;
 
-		SET_NETDEV_DEV(ndev, dev);
+	SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy));
 
-		vif->ndev->ieee80211_ptr = wdev;
-		vif->ndev->ml_priv = vif;
-		wdev->netdev = vif->ndev;
-		vif->netstats.rx_packets = 0;
-		vif->netstats.tx_packets = 0;
-		vif->netstats.rx_bytes = 0;
-		vif->netstats.tx_bytes = 0;
+	vif->priv.wdev.wiphy = wl->wiphy;
+	vif->priv.wdev.netdev = ndev;
+	vif->priv.wdev.iftype = type;
+	vif->priv.dev = ndev;
 
+	if (rtnl_locked)
+		ret = register_netdevice(ndev);
+	else
 		ret = register_netdev(ndev);
-		if (ret)
-			goto free_ndev;
 
-		vif->iftype = WILC_STATION_MODE;
-		vif->mac_opened = 0;
+	if (ret) {
+		free_netdev(ndev);
+		return ERR_PTR(-EFAULT);
 	}
 
-	return 0;
-
-free_ndev:
-	for (; i >= 0; i--) {
-		if (wl->vif[i]) {
-			if (wl->vif[i]->iftype == WILC_STATION_MODE)
-				unregister_netdev(wl->vif[i]->ndev);
-
-			if (wl->vif[i]->ndev) {
-				wilc_free_wiphy(wl->vif[i]->ndev);
-				free_netdev(wl->vif[i]->ndev);
-			}
-		}
-	}
-	unregister_inetaddr_notifier(&g_dev_notifier);
-	destroy_workqueue(wl->hif_workqueue);
-free_cfg:
-	wilc_wlan_cfg_deinit(wl);
-free_wl:
-	kfree(wl);
-	return ret;
+	ndev->needs_free_netdev = true;
+	vif->iftype = vif_type;
+	vif->wilc->vif[wl->vif_num] = vif;
+	vif->ifc_id = wl->vif_num;
+	vif->idx = wl->vif_num;
+	wl->vif_num += 1;
+	vif->mac_opened = 0;
+	return vif;
 }
-EXPORT_SYMBOL_GPL(wilc_netdev_init);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
index b789c57..4c1c81f 100644
--- a/drivers/staging/wilc1000/wilc_sdio.c
+++ b/drivers/staging/wilc1000/wilc_sdio.c
@@ -8,6 +8,7 @@
 #include <linux/mmc/host.h>
 
 #include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
 
 #define SDIO_MODALIAS "wilc1000_sdio"
 
@@ -139,11 +140,9 @@ static int wilc_sdio_probe(struct sdio_func *func,
 		}
 	}
 
-	dev_dbg(&func->dev, "Initializing netdev\n");
-	ret = wilc_netdev_init(&wilc, &func->dev, WILC_HIF_SDIO,
-			       &wilc_hif_sdio);
+	ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
+				 &wilc_hif_sdio);
 	if (ret) {
-		dev_err(&func->dev, "Couldn't initialize netdev\n");
 		kfree(sdio_priv);
 		return ret;
 	}
diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index d8910bf..3c1ae9e 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -7,6 +7,7 @@
 #include <linux/spi/spi.h>
 
 #include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
 
 struct wilc_spi {
 	int crc_off;
@@ -120,7 +121,7 @@ static int wilc_bus_probe(struct spi_device *spi)
 			dev_err(&spi->dev, "failed to get the irq gpio\n");
 	}
 
-	ret = wilc_netdev_init(&wilc, NULL, WILC_HIF_SPI, &wilc_hif_spi);
+	ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
 	if (ret) {
 		kfree(spi_priv);
 		return ret;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index b0daa11..012e325 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -183,48 +183,67 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
 		eth_zero_addr(priv->associated_bss);
 		wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 
-		if (vif->iftype != WILC_CLIENT_MODE)
+		if (vif->iftype != WILC_CLIENT_MODE) {
 			wl->sta_ch = WILC_INVALID_CHANNEL;
-
-		if (wfi_drv->ifc_up && dev == wl->vif[1]->ndev)
-			reason = 3;
-		else if (!wfi_drv->ifc_up && dev == wl->vif[1]->ndev)
-			reason = 1;
+		} else {
+			if (wfi_drv->ifc_up)
+				reason = 3;
+			else
+				reason = 1;
+		}
 
 		cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
 	}
 }
 
+static struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
+{
+	int i;
+
+	for (i = 0; i < wl->vif_num; i++)
+		if (wl->vif[i])
+			return wl->vif[i];
+
+	return ERR_PTR(-EINVAL);
+}
+
 static int set_channel(struct wiphy *wiphy,
 		       struct cfg80211_chan_def *chandef)
 {
-	u32 channelnum = 0;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
-	int result = 0;
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif;
+	u32 channelnum;
+	int result;
+
+	mutex_lock(&wl->vif_mutex);
+	vif = wilc_get_wl_to_vif(wl);
+	if (IS_ERR(vif)) {
+		mutex_unlock(&wl->vif_mutex);
+		return PTR_ERR(vif);
+	}
 
 	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
 
-	vif->wilc->op_ch = channelnum;
+	wl->op_ch = channelnum;
 	result = wilc_set_mac_chnl_num(vif, channelnum);
+	if (result)
+		netdev_err(vif->ndev, "Error in setting channel\n");
 
-	if (result != 0)
-		netdev_err(priv->dev, "Error in setting channel\n");
-
+	mutex_unlock(&wl->vif_mutex);
 	return result;
 }
 
 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
+	struct wilc_priv *priv = &vif->priv;
 	u32 i;
 	int ret = 0;
 	u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
 	u8 scan_type;
 
 	if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
-		netdev_err(priv->dev, "Requested scanned channels over\n");
+		netdev_err(vif->ndev, "Requested scanned channels over\n");
 		return -EINVAL;
 	}
 
@@ -256,8 +275,8 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 static int connect(struct wiphy *wiphy, struct net_device *dev,
 		   struct cfg80211_connect_params *sme)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 	struct host_if_drv *wfi_drv = priv->hif_drv;
 	int ret;
 	u32 i;
@@ -410,8 +429,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
 static int disconnect(struct wiphy *wiphy, struct net_device *dev,
 		      u16 reason_code)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 	struct wilc *wilc = vif->wilc;
 	int ret;
 
@@ -501,17 +520,17 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 
 {
 	int ret = 0, keylen = params->key_len;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
 	const u8 *rx_mic = NULL;
 	const u8 *tx_mic = NULL;
 	u8 mode = WILC_FW_SEC_NO;
 	u8 op_mode;
 	struct wilc_vif *vif = netdev_priv(netdev);
+	struct wilc_priv *priv = &vif->priv;
 
 	switch (params->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
-		if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
+		if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
 			wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
 
 			if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
@@ -538,8 +557,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 
 	case WLAN_CIPHER_SUITE_TKIP:
 	case WLAN_CIPHER_SUITE_CCMP:
-		if (priv->wdev->iftype == NL80211_IFTYPE_AP ||
-		    priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
+		if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
+		    priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
 			struct wilc_wfi_key *key;
 
 			ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
@@ -611,9 +630,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
 		   bool pairwise,
 		   const u8 *mac_addr)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc *wl = wiphy_priv(wiphy);
 	struct wilc_vif *vif = netdev_priv(netdev);
-	struct wilc *wl = vif->wilc;
+	struct wilc_priv *priv = &vif->priv;
 
 	if (netdev == wl->vif[0]->ndev) {
 		if (priv->wilc_gtk[key_index]) {
@@ -650,7 +669,8 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 		   bool pairwise, const u8 *mac_addr, void *cookie,
 		   void (*callback)(void *cookie, struct key_params *))
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc_vif *vif = netdev_priv(netdev);
+	struct wilc_priv *priv = &vif->priv;
 	struct  key_params key_params;
 
 	if (!pairwise) {
@@ -675,8 +695,7 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 			   u8 key_index, bool unicast, bool multicast)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(netdev);
 
 	wilc_set_wep_default_keyid(vif, key_index);
 
@@ -686,8 +705,8 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 static int get_station(struct wiphy *wiphy, struct net_device *dev,
 		       const u8 *mac, struct station_info *sinfo)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
 	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 	u32 i = 0;
 	u32 associatedsta = ~0;
 	u32 inactive_time = 0;
@@ -743,13 +762,35 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
+struct wilc_vif *wilc_get_interface(struct wilc *wl)
+{
+	int i;
+	struct wilc_vif *vif = NULL;
+
+	mutex_lock(&wl->vif_mutex);
+	for (i = 0; i < wl->vif_num; i++) {
+		if (wl->vif[i]) {
+			vif = wl->vif[i];
+			break;
+		}
+	}
+	mutex_unlock(&wl->vif_mutex);
+	return vif;
+}
+
 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
 	int ret;
 	struct cfg_param_attr cfg_param_val;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif;
+	struct wilc_priv *priv;
 
+	vif = wilc_get_interface(wl);
+	if (!vif)
+		return -EINVAL;
+
+	priv = &vif->priv;
 	cfg_param_val.flag = 0;
 
 	if (changed & WIPHY_PARAM_RETRY_SHORT) {
@@ -804,8 +845,8 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 		     struct cfg80211_pmksa *pmksa)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(netdev);
+	struct wilc_priv *priv = &vif->priv;
 	u32 i;
 	int ret = 0;
 	u8 flag = 0;
@@ -840,7 +881,8 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 {
 	u32 i;
 	int ret = 0;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc_vif *vif = netdev_priv(netdev);
+	struct wilc_priv *priv = &vif->priv;
 
 	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
 		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
@@ -870,9 +912,9 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 
 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc_vif *vif = netdev_priv(netdev);
 
-	memset(&priv->pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
+	memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
 
 	return 0;
 }
@@ -987,12 +1029,11 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
 	}
 }
 
-void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
 {
-	struct wilc_priv *priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
-	struct host_if_drv *wfi_drv = priv->hif_drv;
-	struct wilc_vif *vif = netdev_priv(dev);
 	struct wilc *wl = vif->wilc;
+	struct wilc_priv *priv = &vif->priv;
+	struct host_if_drv *wfi_drv = priv->hif_drv;
 	u32 header, pkt_offset;
 	s32 freq;
 	__le16 fc;
@@ -1008,8 +1049,8 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
 		    pkt_offset & IS_MGMT_STATUS_SUCCES)
 			ack = true;
 
-		cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size,
-					ack, GFP_KERNEL);
+		cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
+					size, ack, GFP_KERNEL);
 		return;
 	}
 
@@ -1017,13 +1058,13 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
 
 	fc = ((struct ieee80211_hdr *)buff)->frame_control;
 	if (!ieee80211_is_action(fc)) {
-		cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
+		cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
 		return;
 	}
 
 	if (priv->cfg_scanning &&
 	    time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
-		netdev_dbg(dev, "Receiving action wrong ch\n");
+		netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
 		return;
 	}
 	if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
@@ -1046,14 +1087,14 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
 			break;
 
 		default:
-			netdev_dbg(dev,
+			netdev_dbg(vif->ndev,
 				   "%s: Not handled action frame type:%x\n",
 				   __func__, buff[ACTION_SUBTYPE_ID]);
 			break;
 		}
 	}
 
-	cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
+	cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
 }
 
 static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
@@ -1066,7 +1107,8 @@ static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
 
 static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
 {
-	struct wilc_priv *priv = data;
+	struct wilc_vif *vif = data;
+	struct wilc_priv *priv = &vif->priv;
 	struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
 
 	if (cookie != params->listen_cookie)
@@ -1074,7 +1116,7 @@ static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
 
 	priv->p2p_listen_state = false;
 
-	cfg80211_remain_on_channel_expired(priv->wdev, params->listen_cookie,
+	cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
 					   params->listen_ch, GFP_KERNEL);
 }
 
@@ -1084,8 +1126,8 @@ static int remain_on_channel(struct wiphy *wiphy,
 			     unsigned int duration, u64 *cookie)
 {
 	int ret = 0;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
+	struct wilc_priv *priv = &vif->priv;
 	u64 id;
 
 	if (wdev->iftype == NL80211_IFTYPE_AP) {
@@ -1099,7 +1141,7 @@ static int remain_on_channel(struct wiphy *wiphy,
 
 	ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
 				     wilc_wfi_remain_on_channel_expired,
-				     (void *)priv);
+				     (void *)vif);
 	if (ret)
 		return ret;
 
@@ -1122,8 +1164,8 @@ static int cancel_remain_on_channel(struct wiphy *wiphy,
 				    struct wireless_dev *wdev,
 				    u64 cookie)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
+	struct wilc_priv *priv = &vif->priv;
 
 	if (cookie != priv->remain_on_ch_params.listen_cookie)
 		return -ENOENT;
@@ -1193,9 +1235,9 @@ static int mgmt_tx(struct wiphy *wiphy,
 	size_t len = params->len;
 	const struct ieee80211_mgmt *mgmt;
 	struct wilc_p2p_mgmt_data *mgmt_tx;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct host_if_drv *wfi_drv = priv->hif_drv;
 	struct wilc_vif *vif = netdev_priv(wdev->netdev);
+	struct wilc_priv *priv = &vif->priv;
+	struct host_if_drv *wfi_drv = priv->hif_drv;
 	u32 buf_len = len + sizeof(p2p_vendor_spec) +
 			sizeof(priv->p2p.local_random);
 	int ret = 0;
@@ -1279,7 +1321,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
 			       struct wireless_dev *wdev,
 			       u64 cookie)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
+	struct wilc_priv *priv = &vif->priv;
 	struct host_if_drv *wfi_drv = priv->hif_drv;
 
 	wfi_drv->p2p_timeout = jiffies;
@@ -1289,7 +1332,7 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
 
 		params = &priv->remain_on_ch_params;
 
-		cfg80211_remain_on_channel_expired(priv->wdev,
+		cfg80211_remain_on_channel_expired(wdev,
 						   params->listen_cookie,
 						   params->listen_ch,
 						   GFP_KERNEL);
@@ -1301,9 +1344,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
 			      u16 frame_type, bool reg)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->wdev->netdev);
-	struct wilc *wl = vif->wilc;
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
 
 	if (!frame_type)
 		return;
@@ -1337,8 +1379,7 @@ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
 			int idx, u8 *mac, struct station_info *sinfo)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
 	int ret;
 
 	if (idx != 0)
@@ -1350,15 +1391,15 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev,
 	if (ret)
 		return ret;
 
-	memcpy(mac, priv->associated_bss, ETH_ALEN);
+	memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
 	return 0;
 }
 
 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 			  bool enabled, int timeout)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 
 	if (!priv->hif_drv)
 		return -EIO;
@@ -1373,9 +1414,9 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 			       enum nl80211_iftype type,
 			       struct vif_params *params)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
+	struct wilc *wl = wiphy_priv(wiphy);
 	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wl = vif->wilc;
+	struct wilc_priv *priv = &vif->priv;
 
 	priv->p2p.local_random = 0x01;
 	priv->p2p.recv_random = 0x00;
@@ -1387,8 +1428,10 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_STATION:
 		vif->connecting = false;
 		dev->ieee80211_ptr->iftype = type;
-		priv->wdev->iftype = type;
+		priv->wdev.iftype = type;
 		vif->monitor_flag = 0;
+		if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
+			wilc_wfi_deinit_mon_interface(wl, true);
 		vif->iftype = WILC_STATION_MODE;
 		wilc_set_operation_mode(vif, WILC_STATION_MODE);
 
@@ -1402,7 +1445,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_P2P_CLIENT:
 		vif->connecting = false;
 		dev->ieee80211_ptr->iftype = type;
-		priv->wdev->iftype = type;
+		priv->wdev.iftype = type;
 		vif->monitor_flag = 0;
 		vif->iftype = WILC_CLIENT_MODE;
 		wilc_set_operation_mode(vif, WILC_STATION_MODE);
@@ -1414,7 +1457,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_AP:
 		wl->enable_ps = false;
 		dev->ieee80211_ptr->iftype = type;
-		priv->wdev->iftype = type;
+		priv->wdev.iftype = type;
 		vif->iftype = WILC_AP_MODE;
 
 		if (wl->initialized) {
@@ -1431,7 +1474,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 			  jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS));
 		wilc_set_operation_mode(vif, WILC_AP_MODE);
 		dev->ieee80211_ptr->iftype = type;
-		priv->wdev->iftype = type;
+		priv->wdev.iftype = type;
 		vif->iftype = WILC_GO_MODE;
 
 		wl->enable_ps = false;
@@ -1450,14 +1493,13 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
 		    struct cfg80211_ap_settings *settings)
 {
 	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wl = vif->wilc;
 	int ret;
 
 	ret = set_channel(wiphy, &settings->chandef);
 	if (ret != 0)
 		netdev_err(dev, "Error in setting channel\n");
 
-	wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, WILC_AP_MODE);
+	wilc_wlan_set_bssid(dev, vif->src_addr, WILC_AP_MODE);
 	wilc_set_power_mgmt(vif, 0, 0);
 
 	return wilc_add_beacon(vif, settings->beacon_interval,
@@ -1467,8 +1509,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
 			 struct cfg80211_beacon_data *beacon)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
 
 	return wilc_add_beacon(vif, 0, 0, beacon);
 }
@@ -1476,8 +1517,7 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
 {
 	int ret;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(dev);
 
 	wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
 
@@ -1493,8 +1533,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
 		       const u8 *mac, struct station_parameters *params)
 {
 	int ret = 0;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
 	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 
 	if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
 		memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
@@ -1513,8 +1553,8 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev,
 {
 	const u8 *mac = params->mac;
 	int ret = 0;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
 	struct wilc_vif *vif = netdev_priv(dev);
+	struct wilc_priv *priv = &vif->priv;
 	struct sta_info *info;
 
 	if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
@@ -1545,60 +1585,158 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
 	return ret;
 }
 
+static int wilc_get_vif_from_type(struct wilc *wl, int type)
+{
+	int i;
+
+	mutex_lock(&wl->vif_mutex);
+	for (i = 0; i < wl->vif_num; i++) {
+		if (wl->vif[i]->iftype == type) {
+			mutex_unlock(&wl->vif_mutex);
+			return i;
+		}
+	}
+	mutex_unlock(&wl->vif_mutex);
+
+	return -EINVAL;
+}
+
 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
 					     const char *name,
 					     unsigned char name_assign_type,
 					     enum nl80211_iftype type,
 					     struct vif_params *params)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->wdev->netdev);
-	struct net_device *new_ifc;
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif;
+	struct wireless_dev *wdev;
+	int iftype;
+	int ret;
 
 	if (type == NL80211_IFTYPE_MONITOR) {
-		new_ifc = wilc_wfi_init_mon_interface(vif->wilc, name,
-						      vif->ndev);
-		if (new_ifc) {
-			vif = netdev_priv(priv->wdev->netdev);
-			vif->monitor_flag = 1;
+		struct net_device *ndev;
+		int ap_index = wilc_get_vif_from_type(wl, WILC_AP_MODE);
+
+		if (ap_index < 0) {
+			ap_index = wilc_get_vif_from_type(wl, WILC_GO_MODE);
+			if (ap_index < 0)
+				goto validate_interface;
 		}
+
+		vif  = wl->vif[ap_index];
+		if (vif->monitor_flag)
+			goto validate_interface;
+
+		ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
+		if (ndev)
+			vif->monitor_flag = 1;
+		else
+			return ERR_PTR(-EINVAL);
+
+		wdev = &vif->priv.wdev;
+		return wdev;
+	}
+
+validate_interface:
+	mutex_lock(&wl->vif_mutex);
+	if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
+		pr_err("Reached maximum number of interface\n");
+		ret = -EINVAL;
+		goto out_err;
+	}
+
+	switch (type) {
+	case NL80211_IFTYPE_STATION:
+		iftype = WILC_STATION_MODE;
+		break;
+	case NL80211_IFTYPE_AP:
+		iftype = WILC_AP_MODE;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		goto out_err;
+	}
+
+	vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
+	if (IS_ERR(vif)) {
+		ret = PTR_ERR(vif);
+		goto out_err;
 	}
-	return priv->wdev;
+
+	mutex_unlock(&wl->vif_mutex);
+
+	return &vif->priv.wdev;
+
+out_err:
+	mutex_unlock(&wl->vif_mutex);
+	return ERR_PTR(ret);
 }
 
 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif;
+	int i;
+
+	if (wdev->iftype == NL80211_IFTYPE_AP ||
+	    wdev->iftype == NL80211_IFTYPE_P2P_GO)
+		wilc_wfi_deinit_mon_interface(wl, true);
+	vif = netdev_priv(wdev->netdev);
+	cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
+	unregister_netdevice(vif->ndev);
+	vif->monitor_flag = 0;
+
+	mutex_lock(&wl->vif_mutex);
+	wilc_set_wfi_drv_handler(vif, 0, 0, 0);
+	for (i = vif->idx; i < wl->vif_num ; i++) {
+		if ((i + 1) >= wl->vif_num) {
+			wl->vif[i] = NULL;
+		} else {
+			vif = wl->vif[i + 1];
+			vif->ifc_id = i;
+			vif->idx = i;
+			wl->vif[i] = vif;
+			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
+						 vif->iftype, vif->ifc_id);
+		}
+	}
+	wl->vif_num--;
+	mutex_unlock(&wl->vif_mutex);
+
 	return 0;
 }
 
 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc *wl = wiphy_priv(wiphy);
 
-	if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
-		vif->wilc->suspend_event = true;
+	if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
+		wl->suspend_event = true;
 	else
-		vif->wilc->suspend_event = false;
+		wl->suspend_event = false;
 
 	return 0;
 }
 
 static int wilc_resume(struct wiphy *wiphy)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
-
-	netdev_info(vif->ndev, "cfg resume\n");
 	return 0;
 }
 
 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
 {
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc *wl = wiphy_priv(wiphy);
+	struct wilc_vif *vif;
+
+	mutex_lock(&wl->vif_mutex);
+	vif = wilc_get_wl_to_vif(wl);
+	if (IS_ERR(vif)) {
+		mutex_unlock(&wl->vif_mutex);
+		return;
+	}
 
 	netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
+	mutex_unlock(&wl->vif_mutex);
 }
 
 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
@@ -1606,8 +1744,7 @@ static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 {
 	int ret;
 	s32 tx_power = MBM_TO_DBM(mbm);
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
 
 	if (tx_power < 0)
 		tx_power = 0;
@@ -1624,8 +1761,7 @@ static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 			int *dbm)
 {
 	int ret;
-	struct wilc_priv *priv = wiphy_priv(wiphy);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(wdev->netdev);
 	struct wilc *wl = vif->wilc;
 
 	/* If firmware is not started, return. */
@@ -1682,98 +1818,137 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
 
 };
 
-static struct wireless_dev *wilc_wfi_cfg_alloc(void)
+static void wlan_init_locks(struct wilc *wl)
 {
-	struct wireless_dev *wdev;
+	mutex_init(&wl->hif_cs);
+	mutex_init(&wl->rxq_cs);
+	mutex_init(&wl->cfg_cmd_lock);
+	mutex_init(&wl->vif_mutex);
+
+	spin_lock_init(&wl->txq_spinlock);
+	mutex_init(&wl->txq_add_to_head_cs);
+
+	init_completion(&wl->txq_event);
+	init_completion(&wl->cfg_event);
+	init_completion(&wl->sync_event);
+	init_completion(&wl->txq_thread_started);
+}
 
-	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
-	if (!wdev)
-		goto out;
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+		       const struct wilc_hif_func *ops)
+{
+	struct wilc *wl;
+	struct wilc_vif *vif;
+	int ret;
 
-	wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
-	if (!wdev->wiphy)
-		goto free_mem;
+	wl = wilc_create_wiphy(dev);
+	if (!wl)
+		return -EINVAL;
 
-	return wdev;
+	ret = wilc_wlan_cfg_init(wl);
+	if (ret)
+		goto free_wl;
+
+	*wilc = wl;
+	wl->io_type = io_type;
+	wl->hif_func = ops;
+	wl->enable_ps = false;
+	wl->chip_ps_state = WILC_CHIP_WAKEDUP;
+	INIT_LIST_HEAD(&wl->txq_head.list);
+	INIT_LIST_HEAD(&wl->rxq_head.list);
+
+	wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
+	if (!wl->hif_workqueue) {
+		ret = -ENOMEM;
+		goto free_cfg;
+	}
+	vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
+				   NL80211_IFTYPE_STATION, false);
+	if (IS_ERR(vif)) {
+		ret = PTR_ERR(vif);
+		goto free_hq;
+	}
 
-free_mem:
-	kfree(wdev);
-out:
-	return NULL;
+	wlan_init_locks(wl);
+
+	return 0;
+
+free_hq:
+	destroy_workqueue(wl->hif_workqueue);
+
+free_cfg:
+	wilc_wlan_cfg_deinit(wl);
+
+free_wl:
+	wiphy_unregister(wl->wiphy);
+	wiphy_free(wl->wiphy);
+	return ret;
 }
+EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
 
-struct wireless_dev *wilc_create_wiphy(struct net_device *net,
-				       struct device *dev)
+struct wilc *wilc_create_wiphy(struct device *dev)
 {
-	struct wilc_priv *priv;
-	struct wireless_dev *wdev;
+	struct wiphy *wiphy;
+	struct wilc *wl;
 	int ret;
 
-	wdev = wilc_wfi_cfg_alloc();
-	if (!wdev) {
-		netdev_err(net, "wiphy new allocate failed\n");
+	wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
+	if (!wiphy)
 		return NULL;
-	}
 
-	priv = wdev_priv(wdev);
-	priv->wdev = wdev;
+	wl = wiphy_priv(wiphy);
 
-	memcpy(priv->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
-	memcpy(priv->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
-	priv->band.bitrates = priv->bitrates;
-	priv->band.n_bitrates = ARRAY_SIZE(priv->bitrates);
-	priv->band.channels = priv->channels;
-	priv->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
+	memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
+	memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
+	wl->band.bitrates = wl->bitrates;
+	wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
+	wl->band.channels = wl->channels;
+	wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
 
-	priv->band.ht_cap.ht_supported = 1;
-	priv->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
-	priv->band.ht_cap.mcs.rx_mask[0] = 0xff;
-	priv->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
-	priv->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+	wl->band.ht_cap.ht_supported = 1;
+	wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+	wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
+	wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
+	wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
 
-	wdev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
+	wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
 
-	wdev->wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
+	wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
 #ifdef CONFIG_PM
-	wdev->wiphy->wowlan = &wowlan_support;
+	wiphy->wowlan = &wowlan_support;
 #endif
-	wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
-	wdev->wiphy->max_scan_ie_len = 1000;
-	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-	memcpy(priv->cipher_suites, wilc_cipher_suites,
+	wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
+	wiphy->max_scan_ie_len = 1000;
+	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+	memcpy(wl->cipher_suites, wilc_cipher_suites,
 	       sizeof(wilc_cipher_suites));
-	wdev->wiphy->cipher_suites = priv->cipher_suites;
-	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
-	wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
-
-	wdev->wiphy->max_remain_on_channel_duration = 500;
-	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-					BIT(NL80211_IFTYPE_AP) |
-					BIT(NL80211_IFTYPE_MONITOR) |
-					BIT(NL80211_IFTYPE_P2P_GO) |
-					BIT(NL80211_IFTYPE_P2P_CLIENT);
-	wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
-	wdev->iftype = NL80211_IFTYPE_STATION;
-
-	set_wiphy_dev(wdev->wiphy, dev);
-
-	ret = wiphy_register(wdev->wiphy);
+	wiphy->cipher_suites = wl->cipher_suites;
+	wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
+	wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
+
+	wiphy->max_remain_on_channel_duration = 500;
+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+				BIT(NL80211_IFTYPE_AP) |
+				BIT(NL80211_IFTYPE_MONITOR) |
+				BIT(NL80211_IFTYPE_P2P_GO) |
+				BIT(NL80211_IFTYPE_P2P_CLIENT);
+	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+
+	set_wiphy_dev(wiphy, dev);
+	wl->wiphy = wiphy;
+	ret = wiphy_register(wiphy);
 	if (ret) {
-		netdev_err(net, "Cannot register wiphy device\n");
-		wiphy_free(wdev->wiphy);
-		kfree(wdev);
+		wiphy_free(wiphy);
 		return NULL;
 	}
-
-	priv->dev = net;
-	return wdev;
+	return wl;
 }
 
 int wilc_init_host_int(struct net_device *net)
 {
 	int ret;
-	struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(net);
+	struct wilc_priv *priv = &vif->priv;
 
 	timer_setup(&vif->during_ip_timer, clear_during_ip, 0);
 
@@ -1790,8 +1965,8 @@ int wilc_init_host_int(struct net_device *net)
 void wilc_deinit_host_int(struct net_device *net)
 {
 	int ret;
-	struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
-	struct wilc_vif *vif = netdev_priv(priv->dev);
+	struct wilc_vif *vif = netdev_priv(net);
+	struct wilc_priv *priv = &vif->priv;
 
 	priv->p2p_listen_state = false;
 
@@ -1804,19 +1979,3 @@ void wilc_deinit_host_int(struct net_device *net)
 		netdev_err(net, "Error while deinitializing host interface\n");
 }
 
-void wilc_free_wiphy(struct net_device *net)
-{
-	if (!net)
-		return;
-
-	if (!net->ieee80211_ptr)
-		return;
-
-	if (!net->ieee80211_ptr->wiphy)
-		return;
-
-	wiphy_unregister(net->ieee80211_ptr->wiphy);
-
-	wiphy_free(net->ieee80211_ptr->wiphy);
-	kfree(net->ieee80211_ptr);
-}
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
index 31dfa1f..234faaa 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
@@ -8,17 +8,20 @@
 #define NM_WFI_CFGOPERATIONS
 #include "wilc_wfi_netdevice.h"
 
-struct wireless_dev *wilc_create_wiphy(struct net_device *net,
-				       struct device *dev);
-void wilc_free_wiphy(struct net_device *net);
+struct wiphy *wilc_cfg_alloc(void);
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+		       const struct wilc_hif_func *ops);
+struct wilc *wilc_create_wiphy(struct device *dev);
 void wilc_deinit_host_int(struct net_device *net);
 int wilc_init_host_int(struct net_device *net);
 void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
-void wilc_wfi_deinit_mon_interface(struct wilc *wl);
+struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name,
+				       enum nl80211_iftype type);
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked);
 struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
 					       const char *name,
 					       struct net_device *real_dev);
 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
 			      u16 frame_type, bool reg);
-
+struct wilc_vif *wilc_get_interface(struct wilc *wl);
 #endif
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index df00762..fca3380 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -129,7 +129,7 @@ static struct ieee80211_rate wilc_bitrates[] = {
 };
 
 struct wilc_priv {
-	struct wireless_dev *wdev;
+	struct wireless_dev wdev;
 	struct cfg80211_scan_request *scan_req;
 
 	struct wilc_wfi_p2p_listen_params remain_on_ch_params;
@@ -156,10 +156,6 @@ struct wilc_priv {
 	int scanned_cnt;
 	struct wilc_p2p_var p2p;
 
-	struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
-	struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
-	struct ieee80211_supported_band band;
-	u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
 	u64 inc_roc_cookie;
 };
 
@@ -214,9 +210,11 @@ struct wilc_vif {
 	struct rf_info periodic_stat;
 	struct tcp_ack_filter ack_filter;
 	bool connecting;
+	struct wilc_priv priv;
 };
 
 struct wilc {
+	struct wiphy *wiphy;
 	const struct wilc_hif_func *hif_func;
 	int io_type;
 	s8 mac_status;
@@ -226,6 +224,8 @@ struct wilc {
 	int close;
 	u8 vif_num;
 	struct wilc_vif *vif[WILC_NUM_CONCURRENT_IFC];
+	/*protect vif list*/
+	struct mutex vif_mutex;
 	u8 open_ifcs;
 	/*protect head of transmit queue*/
 	struct mutex txq_add_to_head_cs;
@@ -275,6 +275,10 @@ struct wilc {
 	struct mutex deinit_lock;
 	u8 sta_ch;
 	u8 op_ch;
+	struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
+	struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
+	struct ieee80211_supported_band band;
+	u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
 };
 
 struct wilc_wfi_mon_priv {
@@ -284,9 +288,9 @@ struct wilc_wfi_mon_priv {
 void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
 void wilc_mac_indicate(struct wilc *wilc);
 void wilc_netdev_cleanup(struct wilc *wilc);
-int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
-		     const struct wilc_hif_func *ops);
 void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
 void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
-
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+				      int vif_type, enum nl80211_iftype type,
+				      bool rtnl_locked);
 #endif
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index dcd7285..bd2ffc3 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -6,7 +6,7 @@
 
 #include <linux/if_ether.h>
 #include <linux/ip.h>
-#include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
 #include "wilc_wlan_cfg.h"
 
 static inline bool is_wilc1000(u32 id)
@@ -267,6 +267,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
 	tqe->tx_complete_func = NULL;
 	tqe->priv = NULL;
 	tqe->ack_idx = NOT_TCP_ACK;
+	tqe->vif = vif;
 
 	wilc_wlan_txq_add_to_head(vif, tqe);
 
@@ -295,6 +296,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
 	tqe->buffer_size = buffer_size;
 	tqe->tx_complete_func = tx_complete_fn;
 	tqe->priv = priv;
+	tqe->vif = vif;
 
 	tqe->ack_idx = NOT_TCP_ACK;
 	if (vif->ack_filter.enabled)
@@ -326,6 +328,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
 	tqe->tx_complete_func = tx_complete_fn;
 	tqe->priv = priv;
 	tqe->ack_idx = NOT_TCP_ACK;
+	tqe->vif = vif;
 	wilc_wlan_txq_add_to_tail(dev, tqe);
 	return 1;
 }
@@ -482,7 +485,7 @@ void host_sleep_notify(struct wilc *wilc)
 }
 EXPORT_SYMBOL_GPL(host_sleep_notify);
 
-int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
+int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
 {
 	int i, entries = 0;
 	u32 sum;
@@ -494,17 +497,20 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 	int counter;
 	int timeout;
 	u32 vmm_table[WILC_VMM_TBL_SIZE];
-	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wilc = vif->wilc;
 	const struct wilc_hif_func *func;
 	u8 *txb = wilc->tx_buffer;
+	struct net_device *dev;
+	struct wilc_vif *vif;
 
 	if (wilc->quit)
 		goto out;
 
 	mutex_lock(&wilc->txq_add_to_head_cs);
-	wilc_wlan_txq_filter_dup_tcp_ack(dev);
 	tqe = wilc_wlan_txq_get_first(wilc);
+	if (!tqe)
+		goto out;
+	dev = tqe->vif->ndev;
+	wilc_wlan_txq_filter_dup_tcp_ack(dev);
 	i = 0;
 	sum = 0;
 	do {
@@ -629,6 +635,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 		if (!tqe)
 			break;
 
+		vif = tqe->vif;
 		if (vmm_table[i] == 0)
 			break;
 
@@ -648,8 +655,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
 		if (tqe->type == WILC_CFG_PKT) {
 			buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
 		} else if (tqe->type == WILC_NET_PKT) {
-			bssid = ((struct tx_complete_data *)(tqe->priv))->bssid;
-
+			bssid = tqe->vif->bssid;
 			buffer_offset = ETH_ETHERNET_HDR_OFFSET;
 			memcpy(&txb[offset + 8], bssid, 6);
 		} else {
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 1a27f62..3e54a56 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -216,6 +216,7 @@ struct txq_entry_t {
 	int buffer_size;
 	void *priv;
 	int status;
+	struct wilc_vif *vif;
 	void (*tx_complete_func)(void *priv, int status);
 };
 
@@ -253,7 +254,6 @@ struct wilc_hif_func {
 struct tx_complete_data {
 	int size;
 	void *buff;
-	u8 *bssid;
 	struct sk_buff *skb;
 };
 
@@ -284,7 +284,7 @@ int wilc_wlan_stop(struct wilc *wilc);
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
 			      u32 buffer_size,
 			      void (*tx_complete_fn)(void *, int));
-int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count);
+int wilc_wlan_handle_txq(struct wilc *wl, u32 *txq_count);
 void wilc_handle_isr(struct wilc *wilc);
 void wilc_wlan_cleanup(struct net_device *dev);
 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
@@ -301,7 +301,7 @@ void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
 netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
 
-void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
 void host_wakeup_notify(struct wilc *wilc);
 void host_sleep_notify(struct wilc *wilc);
 void chip_allow_sleep(struct wilc *wilc);
-- 
2.7.4


^ permalink raw reply related

* [PATCH 2/8] staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless
  Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat, stable
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

For the error path in wilc_wlan_initialize(), the resources are not
cleanup in the correct order. Reverted the previous changes and use the
correct order to free during error condition.

Fixes: b46d68825c2d ("staging: wilc1000: remove COMPLEMENT_BOOT")
Cc: <stable@vger.kernel.org>
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/wilc_netdev.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index c4efec2..0e0a4ee 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -530,17 +530,17 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 			goto fail_locks;
 		}
 
-		if (wl->gpio_irq && init_irq(dev)) {
-			ret = -EIO;
-			goto fail_locks;
-		}
-
 		ret = wlan_initialize_threads(dev);
 		if (ret < 0) {
 			ret = -EIO;
 			goto fail_wilc_wlan;
 		}
 
+		if (wl->gpio_irq && init_irq(dev)) {
+			ret = -EIO;
+			goto fail_threads;
+		}
+
 		if (!wl->dev_irq_num &&
 		    wl->hif_func->enable_interrupt &&
 		    wl->hif_func->enable_interrupt(wl)) {
@@ -596,7 +596,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
 fail_irq_init:
 		if (wl->dev_irq_num)
 			deinit_irq(dev);
-
+fail_threads:
 		wlan_deinitialize_threads(dev);
 fail_wilc_wlan:
 		wilc_wlan_cleanup(dev);
-- 
2.7.4


^ permalink raw reply related

* [PATCH 1/8] staging: wilc1000: handle p2p operations in caller context
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>

From: Ajay Singh <ajay.kathat@microchip.com>

Moved the handling of p2p related operation in the caller context instead
of using workqueue.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c | 46 ++++++++++++-------------------
 1 file changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 13c991535..b505990 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -965,11 +965,8 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
 	return 0;
 }
 
-static void handle_listen_state_expired(struct work_struct *work)
+static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
 {
-	struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-	struct wilc_vif *vif = msg->vif;
-	struct wilc_remain_ch *hif_remain_ch = &msg->body.remain_on_ch;
 	u8 remain_on_chan_flag;
 	struct wid wid;
 	int result;
@@ -981,10 +978,10 @@ static void handle_listen_state_expired(struct work_struct *work)
 		wid.id = WID_REMAIN_ON_CHAN;
 		wid.type = WID_STR;
 		wid.size = 2;
-		wid.val = kmalloc(wid.size, GFP_KERNEL);
 
+		wid.val = kmalloc(wid.size, GFP_KERNEL);
 		if (!wid.val)
-			goto free_msg;
+			return -ENOMEM;
 
 		wid.val[0] = remain_on_chan_flag;
 		wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
@@ -994,18 +991,25 @@ static void handle_listen_state_expired(struct work_struct *work)
 		kfree(wid.val);
 		if (result != 0) {
 			netdev_err(vif->ndev, "Failed to set remain channel\n");
-			goto free_msg;
+			return -EINVAL;
 		}
 
 		if (hif_drv->remain_on_ch.expired) {
 			hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
-						      hif_remain_ch->cookie);
+						      cookie);
 		}
 	} else {
 		netdev_dbg(vif->ndev, "Not in listen state\n");
 	}
 
-free_msg:
+	return 0;
+}
+
+static void wilc_handle_listen_state_expired(struct work_struct *work)
+{
+	struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+
+	wilc_handle_roc_expired(msg->vif, msg->body.remain_on_ch.cookie);
 	kfree(msg);
 }
 
@@ -1019,7 +1023,7 @@ static void listen_timer_cb(struct timer_list *t)
 
 	del_timer(&vif->hif_drv->remain_on_ch_timer);
 
-	msg = wilc_alloc_work(vif, handle_listen_state_expired, false);
+	msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
 	if (IS_ERR(msg))
 		return;
 
@@ -1841,30 +1845,14 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
 
 int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
 {
-	int result;
-	struct host_if_msg *msg;
-	struct host_if_drv *hif_drv = vif->hif_drv;
-
-	if (!hif_drv) {
+	if (!vif->hif_drv) {
 		netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
 		return -EFAULT;
 	}
 
-	del_timer(&hif_drv->remain_on_ch_timer);
-
-	msg = wilc_alloc_work(vif, handle_listen_state_expired, false);
-	if (IS_ERR(msg))
-		return PTR_ERR(msg);
-
-	msg->body.remain_on_ch.cookie = cookie;
-
-	result = wilc_enqueue_work(msg);
-	if (result) {
-		netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-		kfree(msg);
-	}
+	del_timer(&vif->hif_drv->remain_on_ch_timer);
 
-	return result;
+	return wilc_handle_roc_expired(vif, cookie);
 }
 
 void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
-- 
2.7.4


^ permalink raw reply related

* [PATCH 0/8] staging: wilc1000: dynamically add/delete interfaces & cleanup fixes
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat

From: Ajay Singh <ajay.kathat@microchip.com>

This patch series mainly contains the changes to support the
add/delete of wlan0/p2p0 network interfaces dynamically. The driver
will be loaded with a single default interface and later new interfaces
can be added or removed.
Also included few cleanup patches in this series.

Ajay Singh (8):
  staging: wilc1000: handle p2p operations in caller context
  staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
  staging: wilc1000: added support to dynamically add/remove interfaces
  staging: wilc1000: remove use of driver_handler_id & ifc_id
  staging: wilc1000: remove unnecessary loop to traverse vif interfaces
  staging: wilc1000: remove use of 'src_addr' element in 'wilc_vif'
    struct
  staging: wilc1000: remove extra argument passing to
    wilc_send_config_pkt()
  staging: wilc1000: rename 'host_interface' source and header

 drivers/staging/wilc1000/Makefile                  |   2 +-
 .../wilc1000/{host_interface.c => wilc_hif.c}      | 170 +++----
 .../wilc1000/{host_interface.h => wilc_hif.h}      |   1 -
 drivers/staging/wilc1000/wilc_mon.c                |   9 +-
 drivers/staging/wilc1000/wilc_netdev.c             | 293 ++++-------
 drivers/staging/wilc1000/wilc_sdio.c               |   7 +-
 drivers/staging/wilc1000/wilc_spi.c                |   3 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c  | 536 +++++++++++++--------
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.h  |  13 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h      |  24 +-
 drivers/staging/wilc1000/wilc_wlan.c               |  23 +-
 drivers/staging/wilc1000/wilc_wlan.h               |   8 +-
 12 files changed, 560 insertions(+), 529 deletions(-)
 rename drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} (91%)
 rename drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} (99%)

-- 
2.7.4


^ permalink raw reply

* [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Carpenter @ 2019-06-26 10:09 UTC (permalink / raw)
  To: Kalle Valo, Philip Rakity
  Cc: Allison Randal, Lubomir Rintel, libertas-dev, linux-wireless,
	kernel-janitors

The lbs_process_rxed_packet() frees the skb.  It didn't originally, but
we fixed it in commit f54930f36311 ("libertas: don't leak skb on receive
error").

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
 drivers/net/wireless/marvell/libertas/if_spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
index 27067e79e83f..e38f02d1f2e4 100644
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
@@ -772,7 +772,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
 	/* pass the SKB to libertas */
 	err = lbs_process_rxed_packet(card->priv, skb);
 	if (err)
-		goto free_skb;
+		goto out;  /* lbs_process_rxed_packet() frees skb */
 
 	/* success */
 	goto out;
-- 
2.20.1


^ permalink raw reply related

* Re: [RFC 0/5] add hw dfs pattern detector support to mt7615 driver
From: Ryder Lee @ 2019-06-26  9:46 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: nbd, lorenzo.bianconi, linux-wireless, royluo, yf.luo
In-Reply-To: <cover.1561499275.git.lorenzo@kernel.org>

On Wed, 2019-06-26 at 00:01 +0200, Lorenzo Bianconi wrote:
> Introduce radar pattern detection support to mt7615 driver. Please note I have
> tested this series just through the radar pattern test knob added to debugfs
> and not through I real radar signal generator.
> CSA is currently missing (I am currently working on it).
> This series is based on 'mt76: move nl80211_dfs_regions in mt76_dev data
> structure' https://patchwork.kernel.org/patch/11010723/
> 
> Lorenzo Bianconi (5):
>   mt76: mt7615: introduce mt7615_regd_notifier
>   mt76: mt7615: add hw dfs pattern detector support
>   mt76: mt7615: do not perform txcalibration before cac is complited
>   mt76: mt7615: unlock dfs bands
>   mt76: mt7615: add radar pattern test knob to debugfs
> 
>  .../wireless/mediatek/mt76/mt7615/Makefile    |   3 +-
>  .../wireless/mediatek/mt76/mt7615/debugfs.c   |  38 ++++++
>  .../net/wireless/mediatek/mt76/mt7615/dma.c   |   2 +-
>  .../net/wireless/mediatek/mt76/mt7615/init.c  |  43 +++++--
>  .../net/wireless/mediatek/mt76/mt7615/mac.c   |  88 +++++++++++++
>  .../net/wireless/mediatek/mt76/mt7615/main.c  |   6 +
>  .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 121 ++++++++++++++++--
>  .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  23 ++++
>  .../wireless/mediatek/mt76/mt7615/mt7615.h    |  55 ++++++++
>  9 files changed, 356 insertions(+), 23 deletions(-)
>  create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
> 
For the series
Acked-by: Ryder Lee <ryder.lee@mediatek.com>


^ permalink raw reply

* [PATCH] ath10k: Move non-fatal warn logs to dbg level for SDIO chip
From: Wen Gong @ 2019-06-26  2:29 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

ath10k will receive some message with invalid peer id from firmware.
reason is:
There are incoming frames to MAC hardware that NOT find relative
address search table, then peer id is invalid set by MAC hardware,
it is hardware's logic, so fix it in ath10k will be more convenient.

log:
ath10k_sdio mmc1:0001:1: Got RX ind from invalid peer: 65535

Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00007-QCARMSWP-1.

Signed-off-by: Wen Gong <wgong@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a20ea27..14b838f 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2082,7 +2082,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
 	spin_lock_bh(&ar->data_lock);
 	peer = ath10k_peer_find_by_id(ar, peer_id);
 	spin_unlock_bh(&ar->data_lock);
-	if (!peer)
+	if (!peer && peer_id != HTT_INVALID_PEERID)
 		ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);
 
 	num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
-- 
1.9.1


^ permalink raw reply related

* [PATCH] ath10k: destroy sdio workqueue while remove sdio module
From: Wen Gong @ 2019-06-26  2:25 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

The workqueue need to flush and destory while remove sdio module,
otherwise it will have thread which is not destory after remove
sdio modules.

Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00007-QCARMSWP-1.

Signed-off-by: Wen Gong <wgong@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/sdio.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index fae56c6..40c3b4b 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -2077,6 +2077,9 @@ static void ath10k_sdio_remove(struct sdio_func *func)
 	cancel_work_sync(&ar_sdio->wr_async_work);
 	ath10k_core_unregister(ar);
 	ath10k_core_destroy(ar);
+
+	flush_workqueue(ar_sdio->workqueue);
+	destroy_workqueue(ar_sdio->workqueue);
 }
 
 static const struct sdio_device_id ath10k_sdio_devices[] = {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH v4 5/7] lib/hexdump.c: Allow multiple groups to be separated by lines '|'
From: Alastair D'Silva @ 2019-06-26  1:28 UTC (permalink / raw)
  To: Joe Perches
  Cc: Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, David Airlie,
	Daniel Vetter, Dan Carpenter, Karsten Keil, Jassi Brar,
	Tom Lendacky, David S. Miller, Jose Abreu, Kalle Valo,
	Stanislaw Gruszka, Benson Leung, Enric Balletbo i Serra,
	James E.J. Bottomley, Martin K. Petersen, Greg Kroah-Hartman,
	Alexander Viro, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	David Laight, Andrew Morton, intel-gfx, dri-devel, linux-kernel,
	netdev, ath10k, linux-wireless, linux-scsi, linux-fbdev, devel,
	linux-fsdevel
In-Reply-To: <c364c36338d385eba60c523828ad8995c792ae4d.camel@perches.com>

On Mon, 2019-06-24 at 22:37 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva <alastair@d-silva.org>
> > 
> > With the wider display format, it can become hard to identify how
> > many
> > bytes into the line you are looking at.
> > 
> > The patch adds new flags to hex_dump_to_buffer() and
> > print_hex_dump() to
> > print vertical lines to separate every N groups of bytes.
> > 
> > eg.
> > buf:00000000: 454d414e 43415053|4e495f45
> > 00584544  NAMESPAC|E_INDEX.
> > buf:00000010: 00000000 00000002|00000000
> > 00000000  ........|........
> > 
> > Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> > ---
> >  include/linux/printk.h |  3 +++
> >  lib/hexdump.c          | 59 ++++++++++++++++++++++++++++++++++++
> > ------
> >  2 files changed, 54 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/linux/printk.h b/include/linux/printk.h
> []
> > @@ -485,6 +485,9 @@ enum {
> >  
> >  #define HEXDUMP_ASCII			BIT(0)
> >  #define HEXDUMP_SUPPRESS_REPEATED	BIT(1)
> > +#define HEXDUMP_2_GRP_LINES		BIT(2)
> > +#define HEXDUMP_4_GRP_LINES		BIT(3)
> > +#define HEXDUMP_8_GRP_LINES		BIT(4)
> 
> These aren't really bits as only one value should be set
> as 8 overrides 4 and 4 overrides 2.

This should be the other way around, as we should be emitting alternate
seperators based on the smallest grouping (2 implies 4 and 8, and 4
implies 8). I'll fix the logic.

I can't come up with a better way to represent these without making the
API more complex, if you have a suggestion, I'm happy to hear it.

> 
> I would also expect this to be a value of 2 in your above
> example, rather than 8.  It's described as groups not bytes.
> 
> The example is showing a what would normally be a space ' '
> separator as a vertical bar '|' every 2nd grouping.
> 

The above example shows a group size of 4 bytes, and
HEXDUMP_2_GRP_LINES set, with 2 groups being 8 bytes.

I'll make that clearer in the commit message.

-- 
Alastair D'Silva           mob: 0423 762 819
skype: alastair_dsilva    
Twitter: @EvilDeece
blog: http://alastair.d-silva.org



^ permalink raw reply

* Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
From: Alastair D'Silva @ 2019-06-26  1:27 UTC (permalink / raw)
  To: Joe Perches
  Cc: Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, David Airlie,
	Daniel Vetter, Dan Carpenter, Karsten Keil, Jassi Brar,
	Tom Lendacky, David S. Miller, Jose Abreu, Kalle Valo,
	Stanislaw Gruszka, Benson Leung, Enric Balletbo i Serra,
	James E.J. Bottomley, Martin K. Petersen, Greg Kroah-Hartman,
	Alexander Viro, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	David Laight, Andrew Morton, intel-gfx, dri-devel, linux-kernel,
	netdev, ath10k, linux-wireless, linux-scsi, linux-fbdev, devel,
	linux-fsdevel
In-Reply-To: <4ba3b835fb3675ea685390903a082bf8b7f9e955.camel@perches.com>

On Mon, 2019-06-24 at 22:19 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 15:06 +1000, Alastair D'Silva wrote:
> > The change actions Jani's suggestion:
> > https://lkml.org/lkml/2019/6/20/343
> 
> I suggest not changing any of the existing uses of
> hex_dump_to_buffer and only use hex_dump_to_buffer_ext
> when necessary for your extended use cases.
> 
> 

I disagree, adding a wrapper for the benefit of avoiding touching a
handful of call sites that are easily amended would be adding technical
debt.

-- 
Alastair D'Silva           mob: 0423 762 819
skype: alastair_dsilva    
Twitter: @EvilDeece
blog: http://alastair.d-silva.org



^ permalink raw reply

* Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
From: Alastair D'Silva @ 2019-06-26  1:27 UTC (permalink / raw)
  To: Joe Perches
  Cc: Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, David Airlie,
	Daniel Vetter, Dan Carpenter, Karsten Keil, Jassi Brar,
	Tom Lendacky, David S. Miller, Jose Abreu, Kalle Valo,
	Stanislaw Gruszka, Benson Leung, Enric Balletbo i Serra,
	James E.J. Bottomley, Martin K. Petersen, Greg Kroah-Hartman,
	Alexander Viro, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	David Laight, Andrew Morton, intel-gfx, dri-devel, linux-kernel,
	netdev, ath10k, linux-wireless, linux-scsi, linux-fbdev, devel,
	linux-fsdevel
In-Reply-To: <3340b520a57e00a483eae170be97316c8d18c22c.camel@perches.com>

On Mon, 2019-06-24 at 22:01 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva <alastair@d-silva.org>
> > 
> > In order to support additional features, rename hex_dump_to_buffer
> > to
> > hex_dump_to_buffer_ext, and replace the ascii bool parameter with
> > flags.
> []
> > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c
> > b/drivers/gpu/drm/i915/intel_engine_cs.c
> []
> > @@ -1338,9 +1338,8 @@ static void hexdump(struct drm_printer *m,
> > const void *buf, size_t len)
> >  		}
> >  
> >  		WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
> > -						rowsize, sizeof(u32),
> > -						line, sizeof(line),
> > -						false) >=
> > sizeof(line));
> > +						rowsize, sizeof(u32),
> > line,
> > +						sizeof(line)) >=
> > sizeof(line));
> 
> Huh?  Why do this?

The ascii parameter was removed from the simple API as per Jani's
suggestion. The remainder was reformatted to avoid exceeding the line
length limits.

> 
> > diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c
> > b/drivers/isdn/hardware/mISDN/mISDNisar.c
> []
> > @@ -70,8 +70,9 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg,
> > u8 len, u8 *msg)
> >  			int l = 0;
> >  
> >  			while (l < (int)len) {
> > -				hex_dump_to_buffer(msg + l, len - l,
> > 32, 1,
> > -						   isar->log, 256, 1);
> > +				hex_dump_to_buffer_ext(msg + l, len -
> > l, 32, 1,
> > +						       isar->log, 256,
> > +						       HEXDUMP_ASCII);
> 
> Again, why do any of these?
> 
> The point of the wrapper is to avoid changing these.

Jani made a pretty good point that about half the callers didn't want
an ASCII dump, and presenting a simplified API makes sense.

I would actually put forward that we consider dropping rowsize from the
simplified API too, as most callers use 32, and those that use 16 would
probably be OK with 32.

Your proposal, on the other hand, only makes sense if there were many
callers, and even so, not in the form that you presented, since that
result in a mix of booleans & bitfields that you were critical of.

-- 
Alastair D'Silva           mob: 0423 762 819
skype: alastair_dsilva    
Twitter: @EvilDeece
blog: http://alastair.d-silva.org



^ permalink raw reply

* Re: [PATCH v4 0/7] Hexdump Enhancements
From: Alastair D'Silva @ 2019-06-26  1:02 UTC (permalink / raw)
  To: Joe Perches
  Cc: Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, David Airlie,
	Daniel Vetter, Dan Carpenter, Karsten Keil, Jassi Brar,
	Tom Lendacky, David S. Miller, Jose Abreu, Kalle Valo,
	Stanislaw Gruszka, Benson Leung, Enric Balletbo i Serra,
	James E.J. Bottomley, Martin K. Petersen, Greg Kroah-Hartman,
	Alexander Viro, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	David Laight, Andrew Morton, intel-gfx, dri-devel, linux-kernel,
	netdev, ath10k, linux-wireless, linux-scsi, linux-fbdev, devel,
	linux-fsdevel
In-Reply-To: <3ae4c1a4a72f8ee6b75c45adfbe543fc0a7b5da1.camel@perches.com>

On Mon, 2019-06-24 at 22:01 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva <alastair@d-silva.org>
> > 
> > Apologies for the large CC list, it's a heads up for those
> > responsible
> > for subsystems where a prototype change in generic code causes a
> > change
> > in those subsystems.
> []
> > The default behaviour of hexdump is unchanged, however, the
> > prototype
> > for hex_dump_to_buffer() has changed, and print_hex_dump() has been
> > renamed to print_hex_dump_ext(), with a wrapper replacing it for
> > compatibility with existing code, which would have been too
> > invasive to
> > change.
> 
> I believe this cover letter is misleading.
> 
> The point of the wrapper is to avoid unnecessary changes
> in existing
> code.
> 
> 

The wrapper is for print_hex_dump(), which has many callers.

The changes to existing code are for hex_dump_to_buffer(), which is
called in relatively few places.

-- 
Alastair D'Silva           mob: 0423 762 819
skype: alastair_dsilva    
Twitter: @EvilDeece
blog: http://alastair.d-silva.org



^ permalink raw reply

* Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
From: kbuild test robot @ 2019-06-25 22:52 UTC (permalink / raw)
  To: Alastair D'Silva
  Cc: kbuild-all, alastair, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Dan Carpenter, Karsten Keil,
	Jassi Brar, Tom Lendacky, David S. Miller, Jose Abreu, Kalle Valo,
	Stanislaw Gruszka, Benson Leung, Enric Balletbo i Serra,
	James E.J. Bottomley, Martin K. Petersen, Greg Kroah-Hartman,
	Alexander Viro, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	David Laight, Andrew Morton, intel-gfx, dri-devel, linux-kernel,
	netdev, ath10k, linux-wireless, linux-scsi, linux-fbdev, devel,
	linux-fsdevel
In-Reply-To: <20190625031726.12173-5-alastair@au1.ibm.com>

Hi Alastair,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.2-rc6 next-20190625]
[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/Alastair-D-Silva/Hexdump-Enhancements/20190625-224046
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-rc1-7-g2b96cd8-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

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


sparse warnings: (new ones prefixed by >>)

   sound/soc/intel/skylake/skl-debug.c:191:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void [noderef] <asn:2> *to @@    got eref] <asn:2> *to @@
   sound/soc/intel/skylake/skl-debug.c:191:34: sparse:    expected void [noderef] <asn:2> *to
   sound/soc/intel/skylake/skl-debug.c:191:34: sparse:    got unsigned char *
   sound/soc/intel/skylake/skl-debug.c:191:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void const *from @@    got void [noderef] <asn:2> void const *from @@
   sound/soc/intel/skylake/skl-debug.c:191:51: sparse:    expected void const *from
   sound/soc/intel/skylake/skl-debug.c:191:51: sparse:    got void [noderef] <asn:2> *[assigned] fw_reg_addr
>> sound/soc/intel/skylake/skl-debug.c:195:35: sparse: sparse: too many arguments for function hex_dump_to_buffer
--
>> drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c:93:27: sparse: sparse: too many arguments for function hex_dump_to_buffer
--
>> sound/soc/sof/xtensa/core.c:125:35: sparse: sparse: too many arguments for function hex_dump_to_buffer

vim +195 sound/soc/intel/skylake/skl-debug.c

d14700a0 Vinod Koul  2017-06-30  170  
bdd0384a Vunny Sodhi 2017-06-30  171  static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
bdd0384a Vunny Sodhi 2017-06-30  172  			       size_t count, loff_t *ppos)
bdd0384a Vunny Sodhi 2017-06-30  173  {
bdd0384a Vunny Sodhi 2017-06-30  174  	struct skl_debug *d = file->private_data;
bdd0384a Vunny Sodhi 2017-06-30  175  	struct sst_dsp *sst = d->skl->skl_sst->dsp;
bdd0384a Vunny Sodhi 2017-06-30  176  	size_t w0_stat_sz = sst->addr.w0_stat_sz;
bdd0384a Vunny Sodhi 2017-06-30  177  	void __iomem *in_base = sst->mailbox.in_base;
bdd0384a Vunny Sodhi 2017-06-30  178  	void __iomem *fw_reg_addr;
bdd0384a Vunny Sodhi 2017-06-30  179  	unsigned int offset;
bdd0384a Vunny Sodhi 2017-06-30  180  	char *tmp;
bdd0384a Vunny Sodhi 2017-06-30  181  	ssize_t ret = 0;
bdd0384a Vunny Sodhi 2017-06-30  182  
bdd0384a Vunny Sodhi 2017-06-30  183  	tmp = kzalloc(FW_REG_BUF, GFP_KERNEL);
bdd0384a Vunny Sodhi 2017-06-30  184  	if (!tmp)
bdd0384a Vunny Sodhi 2017-06-30  185  		return -ENOMEM;
bdd0384a Vunny Sodhi 2017-06-30  186  
bdd0384a Vunny Sodhi 2017-06-30  187  	fw_reg_addr = in_base - w0_stat_sz;
bdd0384a Vunny Sodhi 2017-06-30  188  	memset(d->fw_read_buff, 0, FW_REG_BUF);
bdd0384a Vunny Sodhi 2017-06-30  189  
bdd0384a Vunny Sodhi 2017-06-30  190  	if (w0_stat_sz > 0)
bdd0384a Vunny Sodhi 2017-06-30 @191  		__iowrite32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2);
bdd0384a Vunny Sodhi 2017-06-30  192  
bdd0384a Vunny Sodhi 2017-06-30  193  	for (offset = 0; offset < FW_REG_SIZE; offset += 16) {
bdd0384a Vunny Sodhi 2017-06-30  194  		ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset);
bdd0384a Vunny Sodhi 2017-06-30 @195  		hex_dump_to_buffer(d->fw_read_buff + offset, 16, 16, 4,
bdd0384a Vunny Sodhi 2017-06-30  196  				   tmp + ret, FW_REG_BUF - ret, 0);
bdd0384a Vunny Sodhi 2017-06-30  197  		ret += strlen(tmp + ret);
bdd0384a Vunny Sodhi 2017-06-30  198  
bdd0384a Vunny Sodhi 2017-06-30  199  		/* print newline for each offset */
bdd0384a Vunny Sodhi 2017-06-30  200  		if (FW_REG_BUF - ret > 0)
bdd0384a Vunny Sodhi 2017-06-30  201  			tmp[ret++] = '\n';
bdd0384a Vunny Sodhi 2017-06-30  202  	}
bdd0384a Vunny Sodhi 2017-06-30  203  
bdd0384a Vunny Sodhi 2017-06-30  204  	ret = simple_read_from_buffer(user_buf, count, ppos, tmp, ret);
bdd0384a Vunny Sodhi 2017-06-30  205  	kfree(tmp);
bdd0384a Vunny Sodhi 2017-06-30  206  
bdd0384a Vunny Sodhi 2017-06-30  207  	return ret;
bdd0384a Vunny Sodhi 2017-06-30  208  }
bdd0384a Vunny Sodhi 2017-06-30  209  

:::::: The code at line 195 was first introduced by commit
:::::: bdd0384a5ada8bb5745e5f29c10a5ba88827efad ASoC: Intel: Skylake: Add support to read firmware registers

:::::: TO: Vunny Sodhi <vunnyx.sodhi@intel.com>
:::::: CC: Mark Brown <broonie@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply


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