Skip to contentSkip to conversation

wifi: aic: add AIC8800 SDIO FullMAC driver

RFC PATCH Superseded Yanli Yang 4 participants 21 messages Jul 23 – Sep 6

Subsystems (2)
lore
Share & tools
lore

Yanli Yang

author
#0 lore raw

v2 cover wifi: aic: add AIC8800 SDIO FullMAC driver

This RFC adds an SDIO FullMAC driver for AIC8801, AIC8800DC and AIC8800D80 devices. It contains an SDIO/BSP layer, the firmware protocol, the cfg80211 FullMAC implementation, and diagnostic and compatibility interfaces.

The series is organized as follows:

1. build configuration, SDIO BSP, firmware loading and BSP chip support;
2. FullMAC firmware protocol, platform bring-up and control path;
3. cfg80211 core, data path, SDIO/chip support, wireless features,

     diagnostics and compatibility interfaces;

4. parent wireless build integration and MAINTAINERS.

The parent build integration is added last so that no incomplete driver state can be selected by Kconfig.

Changes since v1:

- update the driver for current wireless-next cfg80211 APIs, including

    per-interface-type HE capability registration;
  - fix cfg80211 BSS IE lifetime and reference handling;
  - address 32-bit GCC, Clang, W=1 and sparse diagnostics, including
    declarations, const correctness, format strings and unused objects;

- limit file-local data and helpers to static scope;
- complete kernel-doc annotations needed by W=1 builds;
- normalize maintainer names in MAINTAINERS.

v1: https://lore.kernel.org/r/[email protected]

Validation performed for v2:

- ARCH=i386 allmodconfig W=1 build with GCC 13.3.0;
- x86-64 allmodconfig W=1 build with Clang/LLD 18.1.3;
- W=1 C=1 sparse checks for all 51 AIC translation units with no AIC

    warning or error;

- sequential git am application on wireless-next commit ac798f757d6475.

The complete W=1 C=1 allmodconfig build was interrupted after the AIC checks by a reproducible sparse v0.6.5-rc1 crash while checking the unrelated drivers/gpu/drm/msm/msm_gem.c file.

Runtime testing on production hardware has not yet been performed.

Known limitations of this RFC are:

- firmware redistribution permission and the corresponding linux-firmware

    submission are not yet available;

- DT power and wake bindings are not included;
- private generic-netlink and vendor interfaces, the regulatory database, and rwnx_settings.ini require follow-up work.

Zhirun Liu (4):
wifi: aic: add SDIO BSP and build configuration
wifi: aic: add FullMAC firmware and platform interface
wifi: aic: add FullMAC WLAN driver
wifi: aic: integrate AIC8800 driver

 MAINTAINERS                                   |   10 +
 drivers/net/wireless/Kconfig                  |    1 +
 drivers/net/wireless/Makefile                 |    1 +
 drivers/net/wireless/aic/Kconfig              |  135 +
 drivers/net/wireless/aic/Makefile             |   17 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |   97 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   42 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  290 +
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 ++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   40 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1679 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  624 ++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  556 ++
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |  116 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 +
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   77 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   71 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2020 ++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 +
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  465 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_bsp/md5.c    |  165 +
 drivers/net/wireless/aic/aic8800_bsp/md5.h    |   77 +
 .../aic/aic8800_bsp/rwnx_version_gen.h        |    5 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |  539 ++
 .../net/wireless/aic/aic8800_fdrv/Makefile    |  117 +
 .../wireless/aic/aic8800_fdrv/aic_br_ext.c    | 1598 +++++
 .../wireless/aic/aic8800_fdrv/aic_br_ext.h    |   72 +
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../wireless/aic/aic8800_fdrv/aic_btsdio.c    | 1169 ++++
 .../wireless/aic/aic8800_fdrv/aic_btsdio.h    |  472 ++
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  | 1978 ++++++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  127 +
 .../wireless/aic/aic8800_fdrv/aic_vendor.c    |  950 +++
 .../wireless/aic/aic8800_fdrv/aic_vendor.h    |  370 ++
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  267 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  186 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  941 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |  112 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2816 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  264 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  753 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 .../aic/aic8800_fdrv/aicwf_wext_linux.c       | 1137 ++++
 .../aic/aic8800_fdrv/aicwf_wext_linux.h       |   15 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  781 +++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  470 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3124 ++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   37 +
 drivers/net/wireless/aic/aic8800_fdrv/md5.c   |  175 +
 drivers/net/wireless/aic/aic8800_fdrv/md5.h   |   82 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_debugfs.c  | 2585 ++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_debugfs.h  |  134 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  743 +++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 +++
 .../wireless/aic/aic8800_fdrv/rwnx_fw_trace.c |   50 +
 .../wireless/aic/aic8800_fdrv/rwnx_fw_trace.h |   28 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_gki.c  |  406 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_gki.h  |   46 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5413 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        | 1312 ++++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1742 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3809 ++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  285 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2954 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  187 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1975 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2445 ++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  777 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1811 ++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  185 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   36 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 .../wireless/aic/aic8800_fdrv/rwnx_version.h  |   14 +
 .../aic/aic8800_fdrv/rwnx_version_gen.h       |    5 +
 .../wireless/aic/aic8800_fdrv/rwnx_wakelock.c |  109 +
 .../wireless/aic/aic8800_fdrv/rwnx_wakelock.h |   24 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 132 files changed, 67364 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/md5.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/md5.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/rwnx_version_gen.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/md5.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/md5.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_version.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_version_gen.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h

base-commit: ac798f757d6475dc6fee2ec899980d6740714596

author
#1 lore raw

RFC PATCH v2 1/4 wifi: aic: add SDIO BSP and build configuration

From: Zhirun Liu <[email protected]>

Add the vendor, BSP and FullMAC build descriptions together with the shared SDIO BSP, firmware loader and BSP chipset support. Keep parent wireless build integration in the final patch.

---
 drivers/net/wireless/aic/Kconfig              |  135 ++
 drivers/net/wireless/aic/Makefile             |   17 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |   97 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   42 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  290 +++
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 +++++++++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   40 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1679 ++++++++++++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  624 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  556 +++++
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |  116 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 ++
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   77 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   71 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2020 +++++++++++++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  465 ++++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 ++
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_bsp/md5.c    |  165 ++
 drivers/net/wireless/aic/aic8800_bsp/md5.h    |   77 +
 .../aic/aic8800_bsp/rwnx_version_gen.h        |    5 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |  539 +++++
 .../net/wireless/aic/aic8800_fdrv/Makefile    |  117 +
 28 files changed, 9241 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/md5.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/md5.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/rwnx_version_gen.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
drivers/net/wireless/aic/Kconfig new file +135 -0
new file mode 100644
index 0000000000000..ed62a5f2d9333
@@ -0,0 +1,135 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config WLAN_VENDOR_AIC
+	bool "AIC devices"
+	default y
+	help
+	  Say Y to expose drivers for wireless devices based on AIC
+	  chipsets. The individual bus and WLAN drivers remain separately
+	  selectable below this vendor menu. Saying N hides those driver
+	  questions without changing any unrelated wireless drivers.
+
+if WLAN_VENDOR_AIC
+
+menuconfig AIC8800_BSP_SUPPORT
+	tristate "AIC8800 SDIO bus support"
+	depends on MMC
+	help
+	  Enable the AIC8800 bus support package. It provides the SDIO
+	  transport, chip operations and firmware download infrastructure
+	  shared by the AIC8800 FullMAC WLAN driver.
+	  Firmware files are loaded from the aic8800/ subdirectory of the
+	  kernel firmware search path, normally /lib/firmware/aic8800/.
+
+	  If unsure, say N.
+
+if AIC8800_BSP_SUPPORT
+
+# The current driver only implements an SDIO transport. Keep this internal
+# symbol for the existing Makefile and C preprocessor conditionals.
+config AIC8800_SDIO_SUPPORT
+	def_bool y
+
+menu "AIC8800 common firmware and transport options"
+
+config AIC8800_SDIO_PWRCTRL
+	bool "SDIO power control"
+	default y
+	help
+	  Allow the driver to control the SDIO interface power state while
+	  bringing the AIC device up and down. The BSP coordinates this
+	  state with firmware download and the WLAN function. This is the
+	  normal setting for supported AIC8800 SDIO modules.
+
+	  If unsure, say Y.
+
+config AIC8800_GPIO_WAKEUP
+	bool "GPIO wakeup support"
+	default y
+	help
+	  Enable a dedicated GPIO signal for device-to-host wakeup. The
+	  signal lets the device wake the host without polling the SDIO
+	  bus. Board wiring and firmware must both provide the wake signal.
+	  Disable this when the board has no dedicated wake GPIO.
+
+	  If unsure, say Y.
+
+config AIC8800_OOB
+	bool "Out-of-band interrupt support"
+	depends on AIC8800_GPIO_WAKEUP
+	help
+	  Use a dedicated GPIO interrupt instead of the in-band SDIO
+	  interrupt. The GPIO must be described by the platform and wired
+	  to the AIC device interrupt output. This mode is only suitable
+	  for boards whose firmware and hardware use out-of-band signaling.
+
+config AIC8800_PREALLOC_TXQ
+	bool "Preallocate TX queues"
+	default y
+	help
+	  Preallocate transmit queue buffers during driver initialization.
+	  This avoids data-path allocations after the interface starts and
+	  can reduce latency under memory pressure. It also reserves the
+	  queue memory for the lifetime of the driver.
+
+	  If unsure, say Y.
+
+config AIC8800_DPD
+	bool "DPD calibration support"
+	default y
+	help
+	  Enable Digital Pre-Distortion calibration support for radio
+	  transmit-path linearization. The driver loads or generates DPD
+	  data expected by supported firmware. Keep this enabled for boards
+	  whose supplied firmware requires DPD calibration data.
+
+	  If unsure, say Y.
+
+config AIC8800_FORCE_DPD_CALIB
+	bool "Force DPD calibration"
+	depends on AIC8800_DPD
+	default y
+	help
+	  Force DPD calibration instead of using existing calibration data.
+	  This makes initialization regenerate the result even when stored
+	  calibration data is available. It increases startup work but can
+	  be useful while validating a new board or radio configuration.
+
+config AIC8800_RESV_MEM_SUPPORT
+	bool "Reserved memory support"
+	default y
+	help
+	  Enable the driver's reserved-memory allocation path for transport
+	  buffers. Platforms may use this to avoid allocating large buffers
+	  during device initialization. The reserved area must be supplied
+	  by the platform integration when this option is selected.
+
+	  If unsure, say Y.
+
+config AIC8800_SDIO_BT
+	bool "Bluetooth over SDIO support"
+	depends on BROKEN
+	help
+	  Enable the downstream Bluetooth transport sharing the Wi-Fi SDIO
+	  interface. The retained implementation uses interfaces that are
+	  not available to a current mainline kernel. It remains disabled
+	  until it is converted to the upstream Bluetooth HCI interfaces.
+
+config AIC8800_VRF_DCDC_MODE
+	bool "VRF DCDC mode"
+	default y
+	help
+	  Configure the chipset's VRF rail to use its internal DC-DC mode.
+	  This affects radio power delivery and must agree with the module
+	  and board power design. The standard supported configuration uses
+	  the internal converter. Check the board design before changing it.
+
+	  If unsure, say Y.
+
+endmenu
+
+source "drivers/net/wireless/aic/aic8800_bsp/Kconfig"
+source "drivers/net/wireless/aic/aic8800_fdrv/Kconfig"
+
+endif # AIC8800_BSP_SUPPORT
+endif # WLAN_VENDOR_AIC
drivers/net/wireless/aic/Makefile new file +17 -0
new file mode 100644
index 0000000000000..247f7fbbc83b4
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
+obj-$(CONFIG_AIC8800_BSP_SUPPORT) += aic8800_bsp/
+
+ccflags-$(CONFIG_AIC8800_SDIO_SUPPORT)       += -DAICWF_SDIO_SUPPORT
+ccflags-$(CONFIG_AIC8800_SDIO_PWRCTRL)       += -DCONFIG_SDIO_PWRCTRL
+ccflags-$(CONFIG_AIC8800_GPIO_WAKEUP)        += -DCONFIG_GPIO_WAKEUP
+ccflags-$(CONFIG_AIC8800_OOB)                += -DCONFIG_OOB
+ccflags-$(CONFIG_AIC8800_PREALLOC_TXQ)       += -DCONFIG_PREALLOC_TXQ
+ccflags-$(CONFIG_AIC8800_PREALLOC_RX_SKB)    += -DCONFIG_PREALLOC_RX_SKB
+ccflags-$(CONFIG_AIC8800_DPD)                += -DCONFIG_DPD
+ccflags-$(CONFIG_AIC8800_FORCE_DPD_CALIB)    += -DCONFIG_FORCE_DPD_CALIB
+ccflags-$(CONFIG_AIC8800_RESV_MEM_SUPPORT)   += -DCONFIG_RESV_MEM_SUPPORT
+ccflags-$(CONFIG_AIC8800_SDIO_BT)            += -DCONFIG_SDIO_BT
+ccflags-$(CONFIG_AIC8800_FDRV_NO_REG_SDIO)   += -DCONFIG_FDRV_NO_REG_SDIO
+ccflags-$(CONFIG_AIC8800_VRF_DCDC_MODE)      += -DCONFIG_VRF_DCDC_MODE
drivers/net/wireless/aic/aic8800_bsp/Kconfig new file +97 -0

97 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/Makefile new file +42 -0

42 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c new file +290 -0

290 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h new file +11 -0
new file mode 100644
index 0000000000000..a22e440b09a66
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800D80_COMPAT_H_
+#define _AIC8800D80_COMPAT_H_
+
+#include "aicsdio.h"
+
+int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c new file +1342 -0

1,342 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h new file +40 -0
new file mode 100644
index 0000000000000..3db89a92dfe01
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800DC_COMPAT_H_
+#define _AIC8800DC_COMPAT_H_
+
+#include "aicsdio.h"
+typedef u32 (*array2_tbl_t)[2];
+typedef u32 (*array3_tbl_t)[3];
+
+typedef u8 u8_l;
+typedef s8 s8_l;
+typedef u16 u16_l;
+typedef s16 s16_l;
+typedef u32 u32_l;
+typedef s32 s32_l;
+typedef u64 u64_l;
+
+extern u8 chip_sub_id;
+extern u8 chip_mcu_id;
+#define FW_PATH_MAX_LEN 200
+
+void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+int rwnx_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
+int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
+int start_from_bootrom_8800DC(struct aic_sdio_dev *sdiodev);
+
+#ifdef CONFIG_DPD
+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev,
+			   struct rf_misc_ram_lite_t *dpd_res);
+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev,
+				  struct rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev,
+				 struct rf_misc_ram_lite_t *dpd_res);
+#endif /* !CONFIG_FORCE_DPD_CALIB */
+#endif
+
+int set_bbpll_config(struct aic_sdio_dev *rwnx_hw);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c new file +1679 -0

1,026 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h new file +624 -0

624 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h new file +70 -0

70 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +556 -0

556 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c new file +116 -0

116 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c new file +133 -0

133 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c new file +117 -0

117 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c new file +77 -0

77 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h new file +71 -0

71 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.c new file +2020 -0

2,020 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.h new file +176 -0

176 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c new file +465 -0

465 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h new file +180 -0

180 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c new file +72 -0

72 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h new file +8 -0
new file mode 100644
index 0000000000000..680d37ffca931

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_bsp/md5.c new file +165 -0

165 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/md5.h new file +77 -0

77 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/rwnx_version_gen.h new file +5 -0
new file mode 100644
index 0000000000000..8768db424ce78

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/Kconfig new file +539 -0

539 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/Makefile new file +117 -0

117 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

author
#2 lore raw

RFC PATCH v2 2/4 wifi: aic: add FullMAC firmware and platform interface

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the FullMAC IPC and LMAC protocol definitions, command serialization, firmware request and confirmation handling, platform bring-up, interrupt helpers and BSP integration.

---
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  781 ++++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  470 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3124 ++++++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   37 +
 drivers/net/wireless/aic/aic8800_fdrv/md5.c   |  175 +
 drivers/net/wireless/aic/aic8800_fdrv/md5.h   |   82 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   93 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  743 ++++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 ++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1742 ++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3809 +++++++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  285 ++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2954 +++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  187 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   36 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 .../wireless/aic/aic8800_fdrv/rwnx_version.h  |   14 +
 .../aic/aic8800_fdrv/rwnx_version_gen.h       |    5 +
 .../wireless/aic/aic8800_fdrv/rwnx_wakelock.c |  109 +
 .../wireless/aic/aic8800_fdrv/rwnx_wakelock.h |   24 +
 38 files changed, 18053 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/md5.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/md5.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_version.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_version_gen.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.h
drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h new file +62 -0
new file mode 100644
index 0000000000000..11b414df42ce3
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __AIC_BSP_EXPORT_H
+#define __AIC_BSP_EXPORT_H
+
+#include <linux/types.h>
+
+enum aicbsp_subsys {
+	AIC_BLUETOOTH,
+	AIC_WIFI,
+};
+
+enum aicbsp_pwr_state {
+	AIC_PWR_OFF,
+	AIC_PWR_ON,
+};
+
+struct aicbsp_feature_t {
+	int hwinfo;
+	u32 sdio_clock;
+	u8 sdio_phase;
+	int fwlog_en;
+	u8 irqf;
+	u8 cpmode;
+	int adapt;
+};
+
+enum skb_buff_id {
+	AIC_RESV_MEM_TXDATA,
+};
+
+#ifdef CONFIG_DPD
+struct rf_misc_ram_t {
+	u32 bit_mask[3];
+	u32 reserved;
+	u32 dpd_high[96];
+	u32 dpd_11b[96];
+	u32 dpd_low[96];
+	u32 idac_11b[48];
+	u32 idac_high[48];
+	u32 idac_low[48];
+	u32 loft_res[18];
+	u32 rx_iqim_res[16];
+};
+
+struct rf_misc_ram_lite_t {
+	u32 bit_mask[4];
+	u32 dpd_high[96];
+	u32 loft_res[18];
+};
+
+#define MEMBER_SIZE(type, member) sizeof_field(type, member)
+#define DPD_RESULT_SIZE_8800DC    sizeof(struct rf_misc_ram_lite_t)
+
+extern struct rf_misc_ram_lite_t dpd_res;
+#endif
+
+int aicbsp_set_subsys(int, int);
+int aicbsp_get_feature(struct aicbsp_feature_t *feature);
+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);
+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id);
+
+#endif
drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h new file +191 -0

191 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h new file +37 -0
new file mode 100644
index 0000000000000..4a49c16f15a31
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_DEBUG_H_
+#define _AICWF_DEBUG_H_
+
+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
+
+/* message levels */
+#define LOGERROR    0x0001
+#define LOGINFO     0x0002
+#define LOGTRACE    0x0004
+#define LOGDEBUG    0x0008
+#define LOGDATA     0x0010
+#define LOGIRQ      0x0020
+#define LOGSDPWRC   0x0040
+#define LOGWAKELOCK 0x0080
+#define LOGRXPOLL   0x0100
+
+extern int aicwf_dbg_level;
+void rwnx_data_dump(char *tag, void *data, unsigned long len);
+
+#define AICWF_LOG "AICWFDBG("
+
+#define AICWFDBG(level, args, arg...)                                          \
+	do {                                                                       \
+		if (aicwf_dbg_level & (level)) {                                         \
+			pr_debug(AICWF_LOG #level ")\t" args, ##arg);                        \
+		}                                                                      \
+	} while (0)
+
+#define RWNX_DBG(fmt, ...)                                                     \
+	do {                                                                       \
+		if (aicwf_dbg_level & LOGTRACE) {                                      \
+			pr_debug(AICWF_LOG "LOGTRACE)\t" fmt, ##__VA_ARGS__);                \
+		}                                                                      \
+	} while (0)
+
+#endif /* _AICWF_DEBUG_H_ */
drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h new file +359 -0

359 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h new file +25 -0
new file mode 100644
index 0000000000000..cf1fe0d737b84
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ ****************************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ ****************************************************************************************
+ */
+
+#ifndef _IPC_H_
+#define _IPC_H_
+
+#define __INLINE inline
+
+#define __ALIGN4 __aligned(4)
+
+#define ASSERT_ERR(condition)                                                  \
+	do {                                                                       \
+		if (unlikely(!(condition))) {                                          \
+			pr_err("%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__,    \
+				   __LINE__);                                                  \
+		}                                                                      \
+	} while (0)
+
+#endif /* _IPC_H_ */
drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c new file +42 -0

42 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h new file +169 -0

169 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h new file +781 -0

781 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h new file +470 -0

470 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h new file +3124 -0

864 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h new file +37 -0
new file mode 100644
index 0000000000000..0ddd2f837bf12

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/md5.c new file +175 -0

175 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/md5.h new file +82 -0

82 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/reg_access.h new file +146 -0

146 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c new file +471 -0

471 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h new file +99 -0

99 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h new file +93 -0

93 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h new file +743 -0

743 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h new file +938 -0

938 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c new file +49 -0

49 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h new file +12 -0
new file mode 100644
index 0000000000000..ff6c766c727c3

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c new file +1742 -0

1,742 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h new file +8 -0
new file mode 100644
index 0000000000000..211f2e616cbf4

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c new file +3809 -0

3,809 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h new file +285 -0

285 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c new file +2954 -0

2,954 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h new file +187 -0

187 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h new file +142 -0

142 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c new file +269 -0

269 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h new file +31 -0
new file mode 100644
index 0000000000000..1b4df40f2a912

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c new file +36 -0
new file mode 100644
index 0000000000000..2da6cfc03f3cc

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h new file +131 -0

131 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c new file +181 -0

181 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h new file +21 -0
new file mode 100644
index 0000000000000..709553f96c2a1

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_version.h new file +14 -0
new file mode 100644
index 0000000000000..7f3f2d88d2d98

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_version_gen.h new file +5 -0
new file mode 100644
index 0000000000000..8768db424ce78

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.c new file +109 -0

109 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_wakelock.h new file +24 -0
new file mode 100644
index 0000000000000..f3ec804f5732d

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

author
#3 lore raw

RFC PATCH v2 3/4 wifi: aic: add FullMAC WLAN driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the cfg80211 FullMAC core, regulatory and configuration paths, TX/RX data path, SDIO and chipset integration, advanced wireless features, diagnostics and retained downstream compatibility interfaces.

This is the complete untrimmed RFC implementation. Private interfaces, the copied regulatory database and INI configuration are included for design review and are not claimed to be merge-ready.

---
 .../wireless/aic/aic8800_fdrv/aic_br_ext.c    | 1598 +++++
 .../wireless/aic/aic8800_fdrv/aic_br_ext.h    |   72 +
 .../wireless/aic/aic8800_fdrv/aic_btsdio.c    | 1169 ++++
 .../wireless/aic/aic8800_fdrv/aic_btsdio.h    |  472 ++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  | 1978 ++++++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  127 +
 .../wireless/aic/aic8800_fdrv/aic_vendor.c    |  950 +++
 .../wireless/aic/aic8800_fdrv/aic_vendor.h    |  370 ++
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  267 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  186 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  941 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |  112 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2816 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  264 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  753 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 .../aic/aic8800_fdrv/aicwf_wext_linux.c       | 1137 ++++
 .../aic/aic8800_fdrv/aicwf_wext_linux.h       |   15 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../wireless/aic/aic8800_fdrv/rwnx_debugfs.c  | 2585 ++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_debugfs.h  |  134 +
 .../wireless/aic/aic8800_fdrv/rwnx_fw_trace.c |   50 +
 .../wireless/aic/aic8800_fdrv/rwnx_fw_trace.h |   28 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_gki.c  |  406 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_gki.h  |   46 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5413 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        | 1312 ++++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1975 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2445 ++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  777 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1811 ++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  185 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 63 files changed, 40058 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h
drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.c new file +1598 -0
new file mode 100644
index 0000000000000..4dc33b367cac3
@@ -0,0 +1,1598 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *****************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ * @brief bridge function definitions
+ *
+ ****************************************************************************
+ */
+
+#define _AIC_BR_EXT_C_
+
+#ifdef __KERNEL__
+#include "rwnx_defs.h"
+#include <linux/atalk.h>
+#include <linux/if_arp.h>
+#include <linux/if_pppox.h>
+#include <linux/udp.h>
+#include <net/ip.h>
+#include <net/ipx.h>
+#endif
+
+#ifdef CL_IPV6_PASS
+#ifdef __KERNEL__
+#include <linux/icmpv6.h>
+#include <linux/ipv6.h>
+#include <net/ndisc.h>
+#include <net/checksum.h>
+#endif
+#endif
+
+#ifdef CONFIG_AIC8800_BR_SUPPORT
+
+/* #define BR_SUPPORT_DEBUG */
+
+#define NAT25_IPV4  01
+#define NAT25_IPV6  02
+#define NAT25_IPX   03
+#define NAT25_APPLE 04
+#define NAT25_PPPOE 05
+
+#define RTL_RELAY_TAG_LEN (ETH_ALEN)
+#define TAG_HDR_LEN       4
+
+#define MAGIC_CODE      0x8186
+#define MAGIC_CODE_LEN  2
+#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
+
+/*-----------------------------------------------------------------
+ * How database records network address:
+ *		   0    1    2    3    4    5    6    7    8    9   10
+ *		|----|----|----|----|----|----|----|----|----|----|----|
+ * IPv4  |type|                             |      IP addr      |
+ * IPX   |type|      Net addr     |          Node addr          |
+ * IPX   |type|      Net addr     |Sckt addr|
+ * Apple |type| Network |node|
+ * PPPoE |type|   SID   |           AC MAC            |
+ *-----------------------------------------------------------------
+ */
+
+/* Find a tag in pppoe frame and return the pointer */
+static inline unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph,
+						    unsigned short type)
+{
+	unsigned char *cur_ptr, *start_ptr;
+	unsigned short tag_len, tag_type;
+
+	cur_ptr = (unsigned char *)ph->tag;
+	start_ptr = cur_ptr;
+	while ((cur_ptr - start_ptr) < ntohs(ph->length)) {
+		/* prevent un-alignment access */
+		tag_type = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]);
+		tag_len = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]);
+		if (tag_type == type)
+			return cur_ptr;
+		cur_ptr = cur_ptr + TAG_HDR_LEN + tag_len;
+	}
+	return 0;
+}
+
+static inline int __nat25_add_pppoe_tag(struct sk_buff *skb,
+					struct pppoe_tag *tag)
+{
+	struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
+	int data_len;
+
+	data_len = tag->tag_len + TAG_HDR_LEN;
+	if (skb_tailroom(skb) < data_len) {
+		pr_err("skb_tailroom() failed in add SID tag!\n");
+		return -1;
+	}
+
+	skb_put(skb, data_len);
+	/* have a room for new tag */
+	memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag,
+		ntohs(ph->length));
+	ph->length = htons(ntohs(ph->length) + data_len);
+	memcpy((unsigned char *)ph->tag, tag, data_len);
+	return data_len;
+}
+
+static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
+{
+	int tail_len;
+	unsigned long end, tail;
+
+	if ((src + len) > skb_tail_pointer(skb) || skb->len < len)
+		return -1;
+
+	tail = (unsigned long)skb_tail_pointer(skb);
+	end = (unsigned long)src + len;
+	if (tail < end)
+		return -1;
+
+	tail_len = (int)(tail - end);
+	if (tail_len > 0)
+		memmove(src, src + len, tail_len);
+
+	skb_trim(skb, skb->len - len);
+	return 0;
+}
+
+static inline unsigned long __nat25_timeout(struct rwnx_vif *vif)
+{
+	unsigned long timeout;
+
+	timeout = jiffies - NAT25_AGEING_TIME * HZ;
+
+	return timeout;
+}
+
+static inline int __nat25_has_expired(struct rwnx_vif *vif,
+				      struct nat25_network_db_entry *fdb)
+{
+	if (time_before_eq(fdb->ageing_timer, __nat25_timeout(vif)))
+		return 1;
+
+	return 0;
+}
+
+static inline void
+__nat25_generate_ipv4_network_addr(unsigned char *network_addr,
+				   unsigned int *ip_addr)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_IPV4;
+	memcpy(network_addr + 7, (unsigned char *)ip_addr, 4);
+}
+
+static inline void
+__nat25_generate_ipx_network_addr_with_node(unsigned char *network_addr,
+					    unsigned int *ipx_net_addr,
+					    unsigned char *ipx_node_addr)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_IPX;
+	memcpy(network_addr + 1, (unsigned char *)ipx_net_addr, 4);
+	memcpy(network_addr + 5, ipx_node_addr, 6);
+}
+
+static inline void
+__nat25_generate_ipx_network_addr_with_socket(unsigned char *network_addr,
+					      unsigned int *ipx_net_addr,
+					      unsigned short *ipx_socket_addr)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_IPX;
+	memcpy(network_addr + 1, (unsigned char *)ipx_net_addr, 4);
+	memcpy(network_addr + 5, (unsigned char *)ipx_socket_addr, 2);
+}
+
+static inline void __nat25_generate_apple_network_addr(unsigned char *network_addr,
+						       unsigned short *network,
+						       unsigned char *node)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_APPLE;
+	memcpy(network_addr + 1, (unsigned char *)network, 2);
+	network_addr[3] = *node;
+}
+
+static inline void
+__nat25_generate_pppoe_network_addr(unsigned char *network_addr,
+				    unsigned char *ac_mac, unsigned short *sid)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_PPPOE;
+	memcpy(network_addr + 1, (unsigned char *)sid, 2);
+	memcpy(network_addr + 3, (unsigned char *)ac_mac, 6);
+}
+
+#ifdef CL_IPV6_PASS
+static void __nat25_generate_ipv6_network_addr(unsigned char *network_addr,
+					       unsigned int *ip_addr)
+{
+	memset(network_addr, 0, MAX_NETWORK_ADDR_LEN);
+
+	network_addr[0] = NAT25_IPV6;
+	memcpy(network_addr + 1, (unsigned char *)ip_addr, 16);
+}
+
+static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag,
+			       unsigned char len8b)
+{
+	while (len > 0) {
+		if (*data == tag && *(data + 1) == len8b && len >= len8b * 8)
+			return data + 2;
+
+		len -= (*(data + 1)) * 8;
+		data += (*(data + 1)) * 8;
+	}
+	return NULL;
+}
+
+static int update_nd_link_layer_addr(unsigned char *data, int len,
+				     unsigned char *replace_mac)
+{
+	struct icmp6hdr *icmphdr = (struct icmp6hdr *)data;
+	unsigned char *mac;
+
+	if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) {
+		if (len >= 8) {
+			mac = scan_tlv(&data[8], len - 8, 1, 1);
+			if (mac) {
+				pr_info("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+					replace_mac[0], replace_mac[1], replace_mac[2],
+					replace_mac[3], replace_mac[4], replace_mac[5]);
+				memcpy(mac, replace_mac, 6);
+				return 1;
+			}
+		}
+	} else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) {
+		if (len >= 16) {
+			mac = scan_tlv(&data[16], len - 16, 1, 1);
+			if (mac) {
+				pr_info("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+					replace_mac[0], replace_mac[1], replace_mac[2],
+					replace_mac[3], replace_mac[4], replace_mac[5]);
+				memcpy(mac, replace_mac, 6);
+				return 1;
+			}
+		}
+	} else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
+		if (len >= 24) {
+			mac = scan_tlv(&data[24], len - 24, 1, 1);
+			if (mac) {
+				pr_info("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+					replace_mac[0], replace_mac[1], replace_mac[2],
+					replace_mac[3], replace_mac[4], replace_mac[5]);
+				memcpy(mac, replace_mac, 6);
+				return 1;
+			}
+		}
+	} else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
+		if (len >= 24) {
+			mac = scan_tlv(&data[24], len - 24, 2, 1);
+			if (mac) {
+				pr_info("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+					replace_mac[0], replace_mac[1], replace_mac[2],
+					replace_mac[3], replace_mac[4], replace_mac[5]);
+				memcpy(mac, replace_mac, 6);
+				return 1;
+			}
+		}
+	} else if (icmphdr->icmp6_type == NDISC_REDIRECT) {
+		if (len >= 40) {
+			mac = scan_tlv(&data[40], len - 40, 2, 1);
+			if (mac) {
+				pr_info("Redirect,  replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+					replace_mac[0], replace_mac[1], replace_mac[2],
+					replace_mac[3], replace_mac[4], replace_mac[5]);
+				memcpy(mac, replace_mac, 6);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+#ifdef SUPPORT_RX_UNI2MCAST
+static void convert_ipv6_mac_to_mc(struct sk_buff *skb)
+{
+	struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
+	unsigned char *dst_mac = skb->data;
+
+	/*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx */
+	dst_mac[0] = 0x33;
+	dst_mac[1] = 0x33;
+	memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4);
+#if defined(__LINUX_2_6__)
+	/*modified by qinjunjie,warning:should not remove next line */
+	skb->pkt_type = PACKET_MULTICAST;
+#endif
+}
+#endif /* CL_IPV6_PASS */
+#endif /* SUPPORT_RX_UNI2MCAST */
+
+static inline int __nat25_network_hash(unsigned char *network_addr)
+{
+	if (network_addr[0] == NAT25_IPV4) {
+		unsigned long x;
+
+		x = network_addr[7] ^ network_addr[8] ^ network_addr[9] ^ network_addr[10];
+
+		return x & (NAT25_HASH_SIZE - 1);
+	} else if (network_addr[0] == NAT25_IPX) {
+		unsigned long x;
+
+		x = network_addr[1] ^ network_addr[2] ^ network_addr[3] ^ network_addr[4] ^
+			network_addr[5] ^ network_addr[6] ^ network_addr[7] ^ network_addr[8] ^
+			network_addr[9] ^ network_addr[10];
+
+		return x & (NAT25_HASH_SIZE - 1);
+	} else if (network_addr[0] == NAT25_APPLE) {
+		unsigned long x;
+
+		x = network_addr[1] ^ network_addr[2] ^ network_addr[3];
+
+		return x & (NAT25_HASH_SIZE - 1);
+	} else if (network_addr[0] == NAT25_PPPOE) {
+		unsigned long x;
+
+		x = network_addr[0] ^ network_addr[1] ^ network_addr[2] ^ network_addr[3] ^
+			network_addr[4] ^ network_addr[5] ^ network_addr[6] ^ network_addr[7] ^
+			network_addr[8];
+
+		return x & (NAT25_HASH_SIZE - 1);
+#ifdef CL_IPV6_PASS
+	} else if (network_addr[0] == NAT25_IPV6) {
+		unsigned long x;
+
+		x = network_addr[1] ^ network_addr[2] ^ network_addr[3] ^ network_addr[4] ^
+			network_addr[5] ^ network_addr[6] ^ network_addr[7] ^ network_addr[8] ^
+			network_addr[9] ^ network_addr[10] ^ network_addr[11] ^
+			network_addr[12] ^ network_addr[13] ^ network_addr[14] ^
+			network_addr[15] ^ network_addr[16];
+
+		return x & (NAT25_HASH_SIZE - 1);
+#endif
+	} else {
+		unsigned long x = 0;
+		int i;
+
+		for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++)
+			x ^= network_addr[i];
+
+		return x & (NAT25_HASH_SIZE - 1);
+	}
+}
+
+static inline void __network_hash_link(struct rwnx_vif *vif,
+				       struct nat25_network_db_entry *ent,
+				       int hash)
+{
+	/* Caller must _enter_critical_bh already! */
+	/* _irqL irqL; */
+	/* _enter_critical_bh(&priv->br_ext_lock, &irqL); */
+
+	ent->next_hash = vif->nethash[hash];
+	if (ent->next_hash)
+		ent->next_hash->pprev_hash = &ent->next_hash;
+	vif->nethash[hash] = ent;
+	ent->pprev_hash = &vif->nethash[hash];
+
+	/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
+}
+
+static inline void __network_hash_unlink(struct nat25_network_db_entry *ent)
+{
+	/* Caller must _enter_critical_bh already! */
+	/* _irqL irqL; */
+	/* _enter_critical_bh(&priv->br_ext_lock, &irqL); */
+
+	*ent->pprev_hash = ent->next_hash;
+	if (ent->next_hash)
+		ent->next_hash->pprev_hash = ent->pprev_hash;
+	ent->next_hash = NULL;
+	ent->pprev_hash = NULL;
+
+	/* _exit_critical_bh(&priv->br_ext_lock, &irqL); */
+}
+
+static int __nat25_db_network_lookup_and_replace(struct rwnx_vif *vif,
+						 struct sk_buff *skb,
+						 unsigned char *network_addr)
+{
+	struct nat25_network_db_entry *db;
+
+	spin_lock_bh(&vif->br_ext_lock);
+
+	db = vif->nethash[__nat25_network_hash(network_addr)];
+	while (db) {
+		if (!memcmp(db->network_addr, network_addr, MAX_NETWORK_ADDR_LEN)) {
+			if (!__nat25_has_expired(vif, db)) {
+				/* replace the destination mac address */
+				memcpy(skb->data, db->mac_addr, ETH_ALEN);
+				atomic_inc(&db->use_count);
+
+#ifdef CL_IPV6_PASS
+				pr_info("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+					db->mac_addr[0], db->mac_addr[1], db->mac_addr[2],
+					db->mac_addr[3], db->mac_addr[4], db->mac_addr[5],
+					db->network_addr[0], db->network_addr[1],
+					db->network_addr[2], db->network_addr[3],
+					db->network_addr[4], db->network_addr[5],
+					db->network_addr[6], db->network_addr[7],
+					db->network_addr[8], db->network_addr[9],
+					db->network_addr[10], db->network_addr[11],
+					db->network_addr[12], db->network_addr[13],
+					db->network_addr[14], db->network_addr[15],
+					db->network_addr[16]);
+#else
+				pr_info("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+					db->mac_addr[0], db->mac_addr[1], db->mac_addr[2],
+					db->mac_addr[3], db->mac_addr[4], db->mac_addr[5],
+					db->network_addr[0], db->network_addr[1],
+					db->network_addr[2], db->network_addr[3],
+					db->network_addr[4], db->network_addr[5],
+					db->network_addr[6], db->network_addr[7],
+					db->network_addr[8], db->network_addr[9],
+					db->network_addr[10]);
+#endif
+			}
+			spin_unlock_bh(&vif->br_ext_lock);
+			return 1;
+		}
+
+		db = db->next_hash;
+	}
+
+	spin_unlock_bh(&vif->br_ext_lock);
+	return 0;
+}
+
+static void __nat25_db_network_insert(struct rwnx_vif *vif,
+				      unsigned char *mac_addr,
+				      unsigned char *network_addr)
+{
+	struct nat25_network_db_entry *db;
+	int hash;
+
+	spin_lock_bh(&vif->br_ext_lock);
+
+	hash = __nat25_network_hash(network_addr);
+	db = vif->nethash[hash];
+
+	while (db) {
+		if (!memcmp(db->network_addr, network_addr, MAX_NETWORK_ADDR_LEN)) {
+			memcpy(db->mac_addr, mac_addr, ETH_ALEN);
+			db->ageing_timer = jiffies;
+			spin_unlock_bh(&vif->br_ext_lock);
+			return;
+		}
+
+		db = db->next_hash;
+	}
+
+	db = kmalloc(sizeof(*db), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+	if (!db) {
+		spin_unlock_bh(&vif->br_ext_lock);
+		return;
+	}
+
+	memcpy(db->network_addr, network_addr, MAX_NETWORK_ADDR_LEN);
+	memcpy(db->mac_addr, mac_addr, ETH_ALEN);
+	atomic_set(&db->use_count, 1);
+	db->ageing_timer = jiffies;
+
+	__network_hash_link(vif, db, hash);
+
+	spin_unlock_bh(&vif->br_ext_lock);
+}
+
+static void __nat25_db_print(struct rwnx_vif *vif)
+{
+	spin_lock_bh(&vif->br_ext_lock);
+
+#ifdef BR_SUPPORT_DEBUG
+	static int counter;
+	int i, j;
+	struct nat25_network_db_entry *db;
+
+	counter++;
+	if ((counter % 16) != 0)
+		return;
+
+	for (i = 0, j = 0; i < NAT25_HASH_SIZE; i++) {
+		db = vif->nethash[i];
+
+		while (db) {
+#ifdef CL_IPV6_PASS
+			pr_info("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				j, i, atomic_read(&db->use_count), db->mac_addr[0],
+				db->mac_addr[1], db->mac_addr[2], db->mac_addr[3], db->mac_addr[4],
+				db->mac_addr[5], db->network_addr[0], db->network_addr[1],
+				db->network_addr[2], db->network_addr[3], db->network_addr[4],
+				db->network_addr[5], db->network_addr[6], db->network_addr[7],
+				db->network_addr[8], db->network_addr[9], db->network_addr[10],
+				db->network_addr[11], db->network_addr[12], db->network_addr[13],
+				db->network_addr[14], db->network_addr[15], db->network_addr[16]);
+#else
+			pr_info("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				j, i, atomic_read(&db->use_count), db->mac_addr[0],
+				db->mac_addr[1], db->mac_addr[2], db->mac_addr[3],
+				db->mac_addr[4], db->mac_addr[5], db->network_addr[0],
+				db->network_addr[1], db->network_addr[2], db->network_addr[3],
+				db->network_addr[4], db->network_addr[5], db->network_addr[6],
+				db->network_addr[7], db->network_addr[8], db->network_addr[9],
+				db->network_addr[10]);
+#endif
+			j++;
+
+			db = db->next_hash;
+		}
+	}
+#endif
+
+	spin_unlock_bh(&vif->br_ext_lock);
+}
+
+/*
+ *	NAT2.5 interface
+ */
+
+void nat25_db_cleanup(struct rwnx_vif *vif)
+{
+	int i;
+
+	spin_lock_bh(&vif->br_ext_lock);
+
+	for (i = 0; i < NAT25_HASH_SIZE; i++) {
+		struct nat25_network_db_entry *f;
+
+		f = vif->nethash[i];
+		while (f) {
+			struct nat25_network_db_entry *g;
+
+			g = f->next_hash;
+			if (vif->scdb_entry == f) {
+				memset(vif->scdb_mac, 0, ETH_ALEN);
+				memset(vif->scdb_ip, 0, 4);
+				vif->scdb_entry = NULL;
+			}
+			__network_hash_unlink(f);
+			kfree(f);
+
+			f = g;
+		}
+	}
+
+	spin_unlock_bh(&vif->br_ext_lock);
+}
+
+static inline void clear_scdb_entry(struct rwnx_vif *vif,
+				    struct nat25_network_db_entry *f)
+{
+	if (vif->scdb_entry == f) {
+		memset(vif->scdb_mac, 0, ETH_ALEN);
+		memset(vif->scdb_ip, 0, 4);
+		vif->scdb_entry = NULL;
+	}
+}
+
+void nat25_db_expire(struct rwnx_vif *vif)
+{
+	int i;
+
+	spin_lock_bh(&vif->br_ext_lock);
+
+	/* if(!priv->eth_br_ext_info.nat25_disable) */
+	{
+		for (i = 0; i < NAT25_HASH_SIZE; i++) {
+			struct nat25_network_db_entry *f;
+
+			f = vif->nethash[i];
+
+			while (f) {
+				struct nat25_network_db_entry *g;
+
+				g = f->next_hash;
+
+				if (__nat25_has_expired(vif, f)) {
+					if (atomic_dec_and_test(&f->use_count)) {
+#ifdef BR_SUPPORT_DEBUG
+#ifdef CL_IPV6_PASS
+						panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+							     i, f->mac_addr[0], f->mac_addr[1],
+							     f->mac_addr[2], f->mac_addr[3],
+							     f->mac_addr[4], f->mac_addr[5],
+							     f->network_addr[0], f->network_addr[1],
+							     f->network_addr[2], f->network_addr[3],
+							     f->network_addr[4], f->network_addr[5],
+							     f->network_addr[6], f->network_addr[7],
+							     f->network_addr[8], f->network_addr[9],
+							     f->network_addr[10],
+							     f->network_addr[11],
+							     f->network_addr[12],
+							     f->network_addr[13],
+							     f->network_addr[14],
+							     f->network_addr[15],
+							     f->network_addr[16]);
+#else
+
+						panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+							     i, f->mac_addr[0], f->mac_addr[1],
+							     f->mac_addr[2], f->mac_addr[3],
+							     f->mac_addr[4], f->mac_addr[5],
+							     f->network_addr[0], f->network_addr[1],
+							     f->network_addr[2], f->network_addr[3],
+							     f->network_addr[4], f->network_addr[5],
+							     f->network_addr[6], f->network_addr[7],
+							     f->network_addr[8], f->network_addr[9],
+							     f->network_addr[10]);
+#endif
+#endif
+						clear_scdb_entry(vif, f);
+						__network_hash_unlink(f);
+						kfree(f);
+					}
+				}
+
+				f = g;
+			}
+		}
+	}
+
+	spin_unlock_bh(&vif->br_ext_lock);
+}
+
+#ifdef SUPPORT_TX_MCAST2UNI
+static int check_ip_mc_and_replace(struct rwnx_vif *vif, struct sk_buff *skb,
+				   unsigned int *dst_ip)
+{
+	struct stat_info *pstat;
+	struct list_head *phead, *plist;
+	int i;
+
+	phead = &vif->asoc_list;
+	plist = phead->next;
+
+	while (plist != phead) {
+		pstat = list_entry(plist, struct stat_info, asoc_list);
+		plist = plist->next;
+
+		if (pstat->ipmc_num == 0)
+			continue;
+
+		for (i = 0; i < MAX_IP_MC_ENTRY; i++) {
+			if (pstat->ipmc[i].used &&
+			    !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip) + 1,
+						3)) {
+				memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+#endif
+
+static inline void check_and_reinit_br_mac(struct rwnx_vif *vif)
+{
+	if ((*(u32 *)vif->br_mac) == 0 &&
+	    (*(u16 *)(vif->br_mac + 4)) == 0) {
+		pr_info("Re-init netdev_br_init() due to br_mac==0!\n");
+		netdev_br_init(vif->ndev);
+	}
+}
+
+static int nat25_handle_pppoe_packet(struct rwnx_vif *vif,
+				     struct pppoe_hdr *ph,
+				     struct sk_buff *skb,
+				     unsigned char network_addr[MAX_NETWORK_ADDR_LEN])
+{
+	struct pppoe_tag *tag, *old_tag;
+	unsigned char tag_buf[40];
+	int old_tag_len = 0;
+	unsigned short *p_magic;
+
+	if (ph->sid == 0) {
+		/* Discovery phase */
+		if (ph->code != PADI_CODE && ph->code != PADR_CODE)
+			return -EINVAL;
+
+		if (vif->eth_br_ext_info.add_pppoe_tag) {
+			tag = (struct pppoe_tag *)tag_buf;
+			old_tag = __nat25_find_pppoe_tag(ph,
+							 ntohs(PTT_RELAY_SID));
+
+			if (old_tag) {
+				/* Copy old value and delete it */
+				old_tag_len = ntohs(old_tag->tag_len);
+
+				if (old_tag_len + TAG_HDR_LEN +
+				    MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN >
+				    sizeof(tag_buf)) {
+					pr_err("SID tag length too long!\n");
+					return -EINVAL;
+				}
+
+				memcpy(tag->tag_data + MAGIC_CODE_LEN +
+				       RTL_RELAY_TAG_LEN,
+				       old_tag->tag_data, old_tag_len);
+
+				if (skb_pull_and_merge(skb,
+						       (unsigned char *)old_tag,
+						       TAG_HDR_LEN + old_tag_len)
+						       < 0) {
+					pr_err("skb_pull_and_merge() failed in PADI/R packet!\n");
+					return -EINVAL;
+				}
+
+				ph->length = htons(ntohs(ph->length) -
+						   TAG_HDR_LEN - old_tag_len);
+			}
+
+			tag->tag_type = PTT_RELAY_SID;
+			tag->tag_len = htons(MAGIC_CODE_LEN +
+					     RTL_RELAY_TAG_LEN + old_tag_len);
+
+			/* Insert magic_code + client MAC */
+			p_magic = (unsigned short *)tag->tag_data;
+			*p_magic = htons(MAGIC_CODE);
+			memcpy(tag->tag_data + MAGIC_CODE_LEN,
+			       skb->data + ETH_ALEN, ETH_ALEN);
+
+			if (__nat25_add_pppoe_tag(skb, tag) < 0)
+				return -EINVAL;
+
+			pr_info("NAT25: Insert PPPoE, forward %s packet\n",
+				(ph->code == PADI_CODE) ? "PADI" : "PADR");
+
+		} else {
+			/* Not adding relay tag */
+			if (vif->pppoe_connection_in_progress &&
+			    memcmp(skb->data + ETH_ALEN,
+				   vif->pppoe_addr, ETH_ALEN)) {
+				pr_info("Discard PPPoE packet: another connection in progress!\n");
+				return -EBUSY;
+			}
+
+			if (vif->pppoe_connection_in_progress == 0)
+				memcpy(vif->pppoe_addr, skb->data + ETH_ALEN,
+				       ETH_ALEN);
+
+			vif->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
+		}
+
+	} else {
+		/* Session phase */
+		pr_info("NAT25: Insert PPPoE session packet to %s\n",
+			skb->dev->name);
+
+		__nat25_generate_pppoe_network_addr(network_addr,
+						    skb->data, &ph->sid);
+
+		__nat25_db_network_insert(vif, skb->data + ETH_ALEN,
+					  network_addr);
+
+		__nat25_db_print(vif);
+
+		if (!vif->eth_br_ext_info.add_pppoe_tag &&
+		    vif->pppoe_connection_in_progress &&
+		    !memcmp(skb->data + ETH_ALEN,
+			    vif->pppoe_addr, ETH_ALEN))
+			vif->pppoe_connection_in_progress = 0;
+	}
+
+	return 0;
+}
+
+int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
+{
+	unsigned short protocol;
+	unsigned char network_addr[MAX_NETWORK_ADDR_LEN];
+
+	if (!skb)
+		return -1;
+
+	if (method <= NAT25_MIN || method >= NAT25_MAX)
+		return -1;
+
+	protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
+
+	/*---------------------------------------------------*/
+	/*                 Handle IP frame                  */
+	/*---------------------------------------------------*/
+	if (protocol == htons(ETH_P_IP)) {
+		struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
+
+		if (((unsigned char *)(iph) + (iph->ihl << 2)) >=
+			(skb->data + ETH_HLEN + skb->len)) {
+			pr_err("NAT25: malformed IP packet !\n");
+			return -1;
+		}
+
+		switch (method) {
+		case NAT25_CHECK:
+			return -1;
+
+		case NAT25_INSERT: {
+			/* some multicast with source IP is all zero, maybe other case is
+			 * illegal
+			 */
+			/* in class A, B, C, host address is all zero or all one is illegal
+			 */
+			if (iph->saddr == 0)
+				return 0;
+			pr_info("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr,
+				iph->daddr);
+			__nat25_generate_ipv4_network_addr(network_addr, &iph->saddr);
+			/* record source IP address and , source mac address into db */
+			__nat25_db_network_insert(vif, skb->data + ETH_ALEN, network_addr);
+
+			__nat25_db_print(vif);
+		}
+			return 0;
+
+		case NAT25_LOOKUP: {
+			pr_info("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr,
+				iph->daddr);
+#ifdef SUPPORT_TX_MCAST2UNI
+			if (vif->pshare->rf_ft_var.mc2u_disable ||
+			    ((((OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE)) ==
+				   (WIFI_STATION_STATE | WIFI_ASOC_STATE)) &&
+				  !check_ip_mc_and_replace(vif, skb, &iph->daddr)) ||
+				 (OPMODE & WIFI_ADHOC_STATE)))
+#endif
+			{
+				__nat25_generate_ipv4_network_addr(network_addr, &iph->daddr);
+
+				if (!__nat25_db_network_lookup_and_replace(vif, skb,
+									   network_addr)) {
+					if (*((unsigned char *)&iph->daddr + 3) == 0xff) {
+						/* L2 is unicast but L3 is broadcast, make L2 bacome
+						 * broadcast
+						 */
+						pr_info("NAT25: Set DA as broadcast\n");
+						memset(skb->data, 0xff, ETH_ALEN);
+					} else {
+						/* forward unknown IP packet to upper TCP/IP */
+						pr_info("NAT25: Replace DA with BR's MAC\n");
+						check_and_reinit_br_mac(vif);
+						memcpy(skb->data, vif->br_mac, ETH_ALEN);
+					}
+				}
+			}
+		}
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+
+	/*---------------------------------------------------*/
+	/*                 Handle ARP frame                 */
+	/*---------------------------------------------------*/
+	else if (protocol == htons(ETH_P_ARP)) {
+		struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
+		unsigned char *arp_ptr = (unsigned char *)(arp + 1);
+		unsigned int *sender, *target;
+
+		if (arp->ar_pro != htons(ETH_P_IP)) {
+			pr_err("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro));
+			return -1;
+		}
+
+		switch (method) {
+		case NAT25_CHECK:
+			return 0; /* skb_copy for all ARP frame */
+
+		case NAT25_INSERT: {
+			pr_info("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n",
+				arp_ptr[0], arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4],
+				arp_ptr[5]);
+
+			/* change to ARP sender mac address to wlan STA address */
+			memcpy(arp_ptr, vif->ndev->dev_addr, ETH_ALEN);
+
+			arp_ptr += arp->ar_hln;
+			sender = (unsigned int *)arp_ptr;
+
+			__nat25_generate_ipv4_network_addr(network_addr, sender);
+
+			__nat25_db_network_insert(vif, skb->data + ETH_ALEN, network_addr);
+
+			__nat25_db_print(vif);
+		}
+			return 0;
+
+		case NAT25_LOOKUP: {
+			pr_info("NAT25: Lookup ARP\n");
+
+			arp_ptr += arp->ar_hln;
+			sender = (unsigned int *)arp_ptr;
+			arp_ptr += (arp->ar_hln + arp->ar_pln);
+			target = (unsigned int *)arp_ptr;
+
+			__nat25_generate_ipv4_network_addr(network_addr, target);
+
+			__nat25_db_network_lookup_and_replace(vif, skb, network_addr);
+
+			/* change to ARP target mac address to Lookup result */
+			arp_ptr = (unsigned char *)(arp + 1);
+			arp_ptr += (arp->ar_hln + arp->ar_pln);
+			memcpy(arp_ptr, skb->data, ETH_ALEN);
+		}
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+
+	/*---------------------------------------------------*/
+	/*         Handle IPX and Apple Talk frame          */
+	/*---------------------------------------------------*/
+	else if ((protocol == htons(ETH_P_IPX)) ||
+		 (protocol == htons(ETH_P_ATALK)) ||
+			 (protocol == htons(ETH_P_AARP))) {
+		unsigned char ipx_header[2] = {0xFF, 0xFF};
+		struct ipxhdr *ipx = NULL;
+		struct elapaarp *ea = NULL;
+		struct ddpehdr *ddp = NULL;
+		unsigned char *frame_ptr = skb->data + ETH_HLEN;
+
+		if (protocol == htons(ETH_P_IPX)) {
+			pr_info("NAT25: Protocol=IPX (Ethernet II)\n");
+			ipx = (struct ipxhdr *)frame_ptr;
+		} else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */
+			if (!memcmp(ipx_header, frame_ptr, 2)) {
+				pr_info("NAT25: Protocol=IPX (Ethernet 802.3)\n");
+				ipx = (struct ipxhdr *)frame_ptr;
+			} else {
+				unsigned char ipx_8022_type = 0xE0;
+				unsigned char snap_8022_type = 0xAA;
+
+				if (*frame_ptr == snap_8022_type) {
+					unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81,
+									0x37}; /* IPX SNAP ID */
+					unsigned char aarp_snap_id[5] = {
+						0x00, 0x00, 0x00, 0x80,
+						0xF3}; /* Apple Talk AARP SNAP ID */
+					unsigned char ddp_snap_id[5] = {
+						0x08, 0x00, 0x07, 0x80,
+						0x9B}; /* Apple Talk DDP SNAP ID */
+
+					frame_ptr += 3; /* eliminate the 802.2 header */
+
+					if (!memcmp(ipx_snap_id, frame_ptr, 5)) {
+						frame_ptr += 5; /* eliminate the SNAP header */
+
+						pr_info("NAT25: Protocol=IPX (Ethernet SNAP)\n");
+						ipx = (struct ipxhdr *)frame_ptr;
+					} else if (!memcmp(aarp_snap_id, frame_ptr, 5)) {
+						frame_ptr += 5; /* eliminate the SNAP header */
+
+						ea = (struct elapaarp *)frame_ptr;
+					} else if (!memcmp(ddp_snap_id, frame_ptr, 5)) {
+						frame_ptr += 5; /* eliminate the SNAP header */
+
+						ddp = (struct ddpehdr *)frame_ptr;
+					} else {
+						pr_info("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n",
+							frame_ptr[0], frame_ptr[1], frame_ptr[2],
+							frame_ptr[3], frame_ptr[4]);
+						return -1;
+					}
+				} else if (*frame_ptr == ipx_8022_type) {
+					frame_ptr += 3; /* eliminate the 802.2 header */
+
+					if (!memcmp(ipx_header, frame_ptr, 2)) {
+						pr_info("NAT25: Protocol=IPX (Ethernet 802.2)\n");
+						ipx = (struct ipxhdr *)frame_ptr;
+					} else {
+						return -1;
+					}
+				}
+			}
+		}
+
+		/*   IPX  */
+		if (ipx) {
+			unsigned int *ipx_net = NULL;
+			unsigned short *ipx_socket = NULL;
+
+			switch (method) {
+			case NAT25_CHECK:
+				if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node,
+					    ETH_ALEN)) {
+					pr_info("NAT25: Check IPX skb_copy\n");
+					return 0;
+				}
+				return -1;
+
+			case NAT25_INSERT: {
+				pr_info("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
+					ipx->ipx_dest.net, ipx->ipx_dest.node[0],
+					ipx->ipx_dest.node[1], ipx->ipx_dest.node[2],
+					ipx->ipx_dest.node[3], ipx->ipx_dest.node[4],
+					ipx->ipx_dest.node[5], ipx->ipx_dest.sock,
+					ipx->ipx_source.net, ipx->ipx_source.node[0],
+					ipx->ipx_source.node[1], ipx->ipx_source.node[2],
+					ipx->ipx_source.node[3], ipx->ipx_source.node[4],
+					ipx->ipx_source.node[5], ipx->ipx_source.sock);
+
+				if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node,
+					    ETH_ALEN)) {
+					unsigned int *ipx_net = NULL;
+					unsigned short *ipx_socket = NULL;
+
+					pr_info("NAT25: Use IPX Net, and Socket as network addr\n");
+
+					ipx_net = &ipx->ipx_source.net;
+					ipx_socket = &ipx->ipx_source.sock;
+					__nat25_generate_ipx_network_addr_with_socket(network_addr,
+										      ipx_net,
+										      ipx_socket);
+
+					/* change IPX source node addr to wlan STA address */
+					memcpy(ipx->ipx_source.node, vif->ndev->dev_addr, ETH_ALEN);
+				} else {
+					unsigned int *ipx_net = NULL;
+					unsigned char *ipx_node = NULL;
+
+					ipx_net = &ipx->ipx_source.net;
+					ipx_node = ipx->ipx_source.node;
+					__nat25_generate_ipx_network_addr_with_node(network_addr,
+										    ipx_net,
+										    ipx_node);
+				}
+
+				__nat25_db_network_insert(vif, skb->data + ETH_ALEN,
+							  network_addr);
+
+				__nat25_db_print(vif);
+			}
+				return 0;
+
+			case NAT25_LOOKUP: {
+				if (!memcmp(vif->ndev->dev_addr, ipx->ipx_dest.node,
+					    ETH_ALEN)) {
+					unsigned int *ipx_net = &ipx->ipx_dest.net;
+					unsigned short *ipx_socket = &ipx->ipx_dest.sock;
+
+					pr_info("NAT25: Lookup IPX, Modify Destination IPX Node addr\n");
+
+					__nat25_generate_ipx_network_addr_with_socket(network_addr,
+										      ipx_net,
+										      ipx_socket);
+
+					__nat25_db_network_lookup_and_replace(vif, skb,
+									      network_addr);
+
+					/* replace IPX destination node addr with Lookup destination
+					 * MAC addr
+					 */
+					memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN);
+				} else {
+					unsigned int *ipx_net = &ipx->ipx_dest.net;
+					unsigned char *ipx_node = ipx->ipx_dest.node;
+
+					__nat25_generate_ipx_network_addr_with_node(network_addr,
+										    ipx_net,
+										    ipx_node);
+
+					__nat25_db_network_lookup_and_replace(vif, skb,
+									      network_addr);
+				}
+			}
+				return 0;
+
+			default:
+				return -1;
+			}
+		}
+
+		/*   AARP  */
+		else if (ea) {
+			/* Sanity check fields. */
+			if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
+				pr_err("NAT25: Appletalk AARP Sanity check fail!\n");
+				return -1;
+			}
+
+			switch (method) {
+			case NAT25_CHECK:
+				return 0;
+
+			case NAT25_INSERT: {
+				/* change to AARP source mac address to wlan STA address */
+				memcpy(ea->hw_src, vif->ndev->dev_addr, ETH_ALEN);
+
+				pr_info("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n",
+					ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net,
+					ea->pa_dst_node);
+
+				__nat25_generate_apple_network_addr(network_addr,
+								    &ea->pa_src_net,
+								    &ea->pa_src_node);
+
+				__nat25_db_network_insert(vif, skb->data + ETH_ALEN,
+							  network_addr);
+
+				__nat25_db_print(vif);
+			}
+				return 0;
+
+			case NAT25_LOOKUP: {
+				pr_info("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n",
+					ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net,
+					ea->pa_dst_node);
+
+				__nat25_generate_apple_network_addr(network_addr,
+								    &ea->pa_dst_net,
+								    &ea->pa_dst_node);
+
+				__nat25_db_network_lookup_and_replace(vif, skb, network_addr);
+
+				/* change to AARP destination mac address to Lookup result */
+				memcpy(ea->hw_dst, skb->data, ETH_ALEN);
+			}
+				return 0;
+
+			default:
+				return -1;
+			}
+		}
+
+		/*   DDP  */
+		else if (ddp) {
+			switch (method) {
+			case NAT25_CHECK:
+				return -1;
+
+			case NAT25_INSERT: {
+				pr_info("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n",
+					ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet,
+					ddp->deh_dnode);
+
+				__nat25_generate_apple_network_addr(network_addr, &ddp->deh_snet,
+								    &ddp->deh_snode);
+
+				__nat25_db_network_insert(vif, skb->data + ETH_ALEN,
+							  network_addr);
+
+				__nat25_db_print(vif);
+			}
+				return 0;
+
+			case NAT25_LOOKUP: {
+				pr_info("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n",
+					ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet,
+					ddp->deh_dnode);
+
+				__nat25_generate_apple_network_addr(network_addr, &ddp->deh_dnet,
+								    &ddp->deh_dnode);
+
+				__nat25_db_network_lookup_and_replace(vif, skb, network_addr);
+			}
+				return 0;
+
+			default:
+				return -1;
+			}
+		}
+
+		return -1;
+	}
+
+	/*---------------------------------------------------*/
+	/*                Handle PPPoE frame                */
+	/*---------------------------------------------------*/
+	else if ((protocol == htons(ETH_P_PPP_DISC)) ||
+		 (protocol == htons(ETH_P_PPP_SES))) {
+		struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
+		unsigned short *pmagic;
+
+		switch (method) {
+		case NAT25_CHECK:
+			if (ph->sid == 0)
+				return 0;
+			return 1;
+
+		case NAT25_INSERT:
+			return nat25_handle_pppoe_packet(vif, ph, skb,
+							 network_addr);
+
+		case NAT25_LOOKUP:
+			if (ph->code == PADO_CODE || ph->code == PADS_CODE) {
+				if (vif->eth_br_ext_info.add_pppoe_tag) {
+					struct pppoe_tag *tag;
+					unsigned char *ptr;
+					unsigned short tag_type, tag_len;
+					int offset = 0;
+
+					ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
+					if (ptr == 0) {
+						pr_err("Fail to find PTT_RELAY_SID in FADO!\n");
+						return -1;
+					}
+
+					tag = (struct pppoe_tag *)ptr;
+					tag_type = (unsigned short)((ptr[0] << 8) + ptr[1]);
+					tag_len = (unsigned short)((ptr[2] << 8) + ptr[3]);
+
+					if (tag_type != ntohs(PTT_RELAY_SID) ||
+					    (tag_len < (MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN))) {
+						pr_err("Invalid PTT_RELAY_SID tag length [%d]!\n",
+						       tag_len);
+						return -1;
+					}
+
+					pmagic = (unsigned short *)tag->tag_data;
+					if (ntohs(*pmagic) != MAGIC_CODE) {
+						pr_err("Can't find MAGIC_CODE in %s packet!\n",
+						       (ph->code == PADO_CODE ? "PADO" : "PADS"));
+						return -1;
+					}
+
+					memcpy(skb->data, tag->tag_data + MAGIC_CODE_LEN, ETH_ALEN);
+
+					if (tag_len > MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN)
+						offset = TAG_HDR_LEN;
+
+					if (skb_pull_and_merge(skb, ptr + offset,
+							       TAG_HDR_LEN + MAGIC_CODE_LEN +
+							       RTL_RELAY_TAG_LEN - offset) <
+						0) {
+						pr_err("call skb_pull_and_merge() failed in PADO packet!\n");
+						return -1;
+					}
+					ph->length = htons(ntohs(ph->length) -
+							   (TAG_HDR_LEN + MAGIC_CODE_LEN +
+							    RTL_RELAY_TAG_LEN - offset));
+					if (offset > 0)
+						tag->tag_len =
+							htons(tag_len - MAGIC_CODE_LEN -
+							      RTL_RELAY_TAG_LEN);
+
+					pr_info("NAT25: Lookup PPPoE, forward %s Packet from %s\n",
+						(ph->code == PADO_CODE ? "PADO" : "PADS"),
+						   skb->dev->name);
+				} else { /* not add relay tag */
+					if (!vif->pppoe_connection_in_progress) {
+						pr_err("Discard PPPoE packet due to no connection in progress!\n");
+						return -1;
+					}
+					memcpy(skb->data, vif->pppoe_addr, ETH_ALEN);
+					vif->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
+				}
+			} else {
+				if (ph->sid != 0) {
+					pr_info("NAT25: Lookup PPPoE, lookup session packet from %s\n",
+						skb->dev->name);
+					__nat25_generate_pppoe_network_addr(network_addr,
+									    skb->data +
+									    ETH_ALEN,
+									    &ph->sid);
+
+					__nat25_db_network_lookup_and_replace(vif, skb,
+									      network_addr);
+
+					__nat25_db_print(vif);
+				} else {
+					return -1;
+				}
+			}
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+
+	/*---------------------------------------------------*/
+	/*                 Handle EAP frame                 */
+	/*---------------------------------------------------*/
+	else if (protocol == htons(0x888e)) {
+		switch (method) {
+		case NAT25_CHECK:
+			return -1;
+
+		case NAT25_INSERT:
+			return 0;
+
+		case NAT25_LOOKUP:
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+
+	/*---------------------------------------------------*/
+	/*         Handle C-Media proprietary frame         */
+	/*---------------------------------------------------*/
+	else if ((protocol == htons(0xe2ae)) ||
+		 (protocol == htons(0xe2af))) {
+		switch (method) {
+		case NAT25_CHECK:
+			return -1;
+
+		case NAT25_INSERT:
+			return 0;
+
+		case NAT25_LOOKUP:
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+
+	/*---------------------------------------------------*/
+	/*         Handle IPV6 frame                                */
+	/*---------------------------------------------------*/
+#ifdef CL_IPV6_PASS
+	else if (protocol == htons(ETH_P_IPV6)) {
+		struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
+
+		if (sizeof(*iph) >= (skb->len - ETH_HLEN)) {
+			pr_err("NAT25: malformed IPv6 packet !\n");
+			return -1;
+		}
+
+		switch (method) {
+		case NAT25_CHECK:
+			if (skb->data[0] & 1)
+				return 0;
+			return -1;
+
+		case NAT25_INSERT: {
+			pr_info("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x, DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
+				iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1],
+				iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
+				iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5],
+				iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
+				iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1],
+				iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
+				iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5],
+				iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
+
+			if (memcmp(&iph->saddr,
+				   "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0",
+					   16)) {
+				__nat25_generate_ipv6_network_addr(network_addr,
+								   (unsigned int *)&iph->saddr);
+				__nat25_db_network_insert(vif, skb->data + ETH_ALEN,
+							  network_addr);
+				__nat25_db_print(vif);
+
+				if (iph->nexthdr == IPPROTO_ICMPV6 &&
+				    skb->len > (ETH_HLEN + sizeof(*iph) + 4)) {
+					if (update_nd_link_layer_addr(skb->data +
+								      ETH_HLEN +
+								      sizeof(*iph),
+								      skb->len -
+								      ETH_HLEN -
+								      sizeof(*iph),
+								      vif->ndev->dev_addr)) {
+						struct icmp6hdr *hdr =
+							(struct icmp6hdr *)(skb->data + ETH_HLEN +
+									    sizeof(*iph));
+						hdr->icmp6_cksum = 0;
+						hdr->icmp6_cksum =
+						csum_ipv6_magic(&iph->saddr, &iph->daddr,
+								iph->payload_len, IPPROTO_ICMPV6,
+								csum_partial((__u8 *)hdr,
+									     iph->payload_len,
+									     0));
+					}
+				}
+			}
+		}
+			return 0;
+
+		case NAT25_LOOKUP:
+			pr_info("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x, DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
+				iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1],
+				iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
+				iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5],
+				iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
+				iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1],
+				iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
+				iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5],
+				iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
+
+			__nat25_generate_ipv6_network_addr(network_addr,
+							   (unsigned int *)&iph->daddr);
+			if (!__nat25_db_network_lookup_and_replace(vif, skb, network_addr)) {
+#ifdef SUPPORT_RX_UNI2MCAST
+				if (iph->daddr.s6_addr[0] == 0xff)
+					convert_ipv6_mac_to_mc(skb);
+#endif
+			}
+			return 0;
+
+		default:
+			return -1;
+		}
+	}
+#endif /* CL_IPV6_PASS */
+
+	return -1;
+}
+
+int nat25_handle_frame(struct rwnx_vif *vif, struct sk_buff *skb)
+{
+	// printk("%s : vif_type=%d\n",__func__,RWNX_VIF_TYPE(vif));
+#ifdef BR_SUPPORT_DEBUG
+	if (!vif->eth_br_ext_info.nat25_disable && (!(skb->data[0] & 1))) {
+		pr_info("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n",
+			skb->data[0], skb->data[1], skb->data[2], skb->data[3],
+			skb->data[4], skb->data[5], skb->data[6], skb->data[7],
+			skb->data[8], skb->data[9], skb->data[10], skb->data[11]);
+	}
+#endif
+
+	if (!(skb->data[0] & 1)) {
+		int is_vlan_tag = 0, i, retval = 0;
+		unsigned short vlan_hdr = 0;
+
+		if (*((unsigned short *)(skb->data + ETH_ALEN * 2)) ==
+			htons(ETH_P_8021Q)) {
+			is_vlan_tag = 1;
+			vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2));
+			for (i = 0; i < 6; i++)
+				*((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) =
+					*((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2));
+			skb_pull(skb, 4);
+		}
+
+		if (!vif->eth_br_ext_info.nat25_disable) {
+			unsigned long irqL;
+
+			spin_lock_bh(&vif->br_ext_lock);
+			/*
+			 *  This function look up the destination network address from
+			 *  the NAT2.5 database. Return value = -1 means that the
+			 *  corresponding network protocol is NOT support.
+			 */
+			if (!vif->eth_br_ext_info.nat25sc_disable &&
+			    (*((unsigned short *)(skb->data + ETH_ALEN * 2)) ==
+				 htons(ETH_P_IP)) &&
+				!memcmp(vif->scdb_ip, skb->data + ETH_HLEN + 16, 4)) {
+				memcpy(skb->data, vif->scdb_mac, ETH_ALEN);
+
+				spin_unlock_bh(&vif->br_ext_lock);
+			} else {
+				spin_unlock_bh(&vif->br_ext_lock);
+
+				retval = nat25_db_handle(vif, skb, NAT25_LOOKUP);
+			}
+		} else {
+			if (((*((unsigned short *)(skb->data + ETH_ALEN * 2)) ==
+				  htons(ETH_P_IP)) &&
+				 !memcmp(vif->br_ip, skb->data + ETH_HLEN + 16, 4)) ||
+				((*((unsigned short *)(skb->data + ETH_ALEN * 2)) ==
+				  htons(ETH_P_ARP)) &&
+				 !memcmp(vif->br_ip, skb->data + ETH_HLEN + 24, 4))) {
+				/* for traffic to upper TCP/IP */
+				retval = nat25_db_handle(vif, skb, NAT25_LOOKUP);
+			}
+		}
+
+		if (is_vlan_tag) {
+			skb_push(skb, 4);
+			for (i = 0; i < 6; i++)
+				*((unsigned short *)(skb->data + i * 2)) =
+					*((unsigned short *)(skb->data + 4 + i * 2));
+			*((unsigned short *)(skb->data + ETH_ALEN * 2)) =
+				htons(ETH_P_8021Q);
+			*((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr;
+		}
+
+		if (retval == -1) {
+			/* DEBUG_ERR("NAT25: Lookup fail!\n"); */
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+#define SERVER_PORT    67
+#define CLIENT_PORT    68
+#define DHCP_MAGIC     0x63825363
+#define BROADCAST_FLAG 0x8000
+
+struct dhcp_message {
+	u8 op;
+	u8 htype;
+	u8 hlen;
+	u8 hops;
+	u32 xid;
+	u16 secs;
+	u16 flags;
+	u32 ciaddr;
+	u32 yiaddr;
+	u32 siaddr;
+	u32 giaddr;
+	u8 chaddr[16];
+	u8 sname[64];
+	u8 file[128];
+	u32 cookie;
+	u8 options[308]; /* 312 - cookie */
+};
+
+static inline void dhcp_fix_broadcast_flag(struct dhcp_message *dhcph,
+					   struct udphdr *udph)
+{
+	int sum;
+
+	if (dhcph->cookie == __constant_htonl(DHCP_MAGIC)) {
+		/* match magic word */
+		if (!(dhcph->flags & htons(BROADCAST_FLAG))) {
+			/* if not broadcast */
+			pr_info("DHCP: change flag of DHCP request to broadcast.\n");
+
+			/* OR BROADCAST flag */
+			dhcph->flags |= htons(BROADCAST_FLAG);
+
+			/* recalculate checksum */
+			sum = ~(udph->check) & 0xffff;
+			sum += dhcph->flags;
+			while (sum >> 16)
+				sum = (sum & 0xffff) + (sum >> 16);
+			udph->check = ~sum;
+		}
+	}
+}
+
+void dhcp_flag_bcast(struct rwnx_vif *vif, struct sk_buff *skb)
+{
+	if (!skb)
+		return;
+	// debug trace
+	// print_hex_dump(KERN_ERR, "SKB DUMP: SKB->DATA== ", DUMP_PREFIX_NONE, 32,
+	// 1, skb->data, 64,false);
+	if (!vif->eth_br_ext_info.dhcp_bcst_disable) {
+		unsigned short protocol =
+			*((unsigned short *)(skb->data + 2 * ETH_ALEN));
+		pr_info("%s  protocol: %04x\n", __func__, protocol);
+
+		if (protocol == htons(ETH_P_IP)) { /* IP */
+			struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
+
+			if (iph->protocol == IPPROTO_UDP) { /* UDP */
+				struct udphdr *udph =
+					(struct udphdr *)((u8 *)iph + (iph->ihl << 2));
+
+				if (udph->source == htons(CLIENT_PORT) &&
+				    udph->dest ==
+					 htons(SERVER_PORT)) { /* DHCP request */
+					struct dhcp_message *dhcph =
+						(struct dhcp_message *)((u8 *)udph +
+									sizeof(struct udphdr));
+					dhcp_fix_broadcast_flag(dhcph, udph);
+				}
+			}
+		}
+	}
+}
+
+void *scdb_find_entry(struct rwnx_vif *vif, unsigned char *mac_addr,
+		      unsigned char *ip_addr)
+{
+	unsigned char network_addr[MAX_NETWORK_ADDR_LEN];
+	struct nat25_network_db_entry *db;
+	int hash;
+
+	__nat25_generate_ipv4_network_addr(network_addr, (unsigned int *)ip_addr);
+	hash = __nat25_network_hash(network_addr);
+	db = vif->nethash[hash];
+	while (db) {
+		if (!memcmp(db->network_addr, network_addr, MAX_NETWORK_ADDR_LEN))
+			return (void *)db;
+
+		db = db->next_hash;
+	}
+
+	return NULL;
+}
+
+#endif /* CONFIG_AIC8800_BR_SUPPORT */
drivers/net/wireless/aic/aic8800_fdrv/aic_br_ext.h new file +72 -0

72 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.c new file +1169 -0

1,169 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_btsdio.h new file +472 -0

161 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c new file +1978 -0

1,978 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h new file +127 -0

127 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.c new file +950 -0

950 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aic_vendor.h new file +370 -0

370 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c new file +291 -0

291 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c new file +300 -0

300 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c new file +279 -0

279 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c new file +267 -0

267 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h new file +186 -0

186 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c new file +96 -0

96 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h new file +16 -0
new file mode 100644
index 0000000000000..22f882d3aa3a2

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c new file +505 -0

505 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h new file +22 -0
new file mode 100644
index 0000000000000..12e8d60150452

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c new file +941 -0

941 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h new file +112 -0

112 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c new file +102 -0

102 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h new file +34 -0
new file mode 100644
index 0000000000000..666e2f0027102

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +2816 -0

2,816 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h new file +264 -0

264 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c new file +565 -0

565 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h new file +104 -0

104 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c new file +753 -0

753 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.c new file +1137 -0

1,137 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_wext_linux.h new file +15 -0
new file mode 100644
index 0000000000000..eafd2a9d80b56

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/regdb.c new file +2772 -0

2,772 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c new file +93 -0

93 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h new file +100 -0

100 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c new file +265 -0

265 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h new file +33 -0
new file mode 100644
index 0000000000000..d76179316fe2a

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.c new file +2585 -0

2,585 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_debugfs.h new file +134 -0

134 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.c new file +50 -0

50 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_fw_trace.h new file +28 -0
new file mode 100644
index 0000000000000..9c9df4db93cc3

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.c new file +406 -0

406 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_gki.h new file +46 -0

46 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c new file +5413 -0

5,413 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h new file +35 -0
new file mode 100644
index 0000000000000..e03321c99c42c

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c new file +33 -0
new file mode 100644
index 0000000000000..69d37ecb63be2

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h new file +35 -0
new file mode 100644
index 0000000000000..44de24ea705a1

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c new file +1312 -0

1,312 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h new file +74 -0

74 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c new file +653 -0

653 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h new file +159 -0

159 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c new file +1975 -0

1,975 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h new file +285 -0

285 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c new file +2445 -0

2,445 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c new file +777 -0

777 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h new file +57 -0

57 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h new file +68 -0

68 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c new file +5 -0
new file mode 100644
index 0000000000000..732fca321d965

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c new file +1811 -0

1,811 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h new file +185 -0

185 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c new file +1362 -0

1,362 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c new file +132 -0

132 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h new file +39 -0
new file mode 100644
index 0000000000000..9179dd4a4a916

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

author
#4 lore raw

RFC PATCH v2 4/4 wifi: aic: integrate AIC8800 driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Connect the completed AIC vendor directory to the wireless build and add its MAINTAINERS entry. Keeping integration last prevents an earlier partial source state from being selected by Kconfig.

---
 MAINTAINERS                   | 10 ++++++++++
 drivers/net/wireless/Kconfig  |  1 +
 drivers/net/wireless/Makefile |  1 +
 3 files changed, 12 insertions(+)
MAINTAINERS +10 -0
index 52f1a55eca99b..a64bd3b8e0aa1 100644
@@ -736,6 +736,16 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/scsi/aic7xxx/
 
+AIC8800 WIRELESS DRIVER
+M:	Zhirun Liu <[email protected]>
+M:	Dijia Xu <[email protected]>
+M:	Chunqiu Liu <[email protected]>
+M:	Liheng Wei <[email protected]>
+M:	Yanli Yang <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/net/wireless/aic/
+
 AIMSLAB FM RADIO RECEIVER DRIVER
 M:	Hans Verkuil <[email protected]>
 L:	[email protected]
drivers/net/wireless/Kconfig +1 -0
index c6599594dc995..65ab62d073693 100644
@@ -19,6 +19,7 @@ menuconfig WLAN
 if WLAN
 
 source "drivers/net/wireless/admtek/Kconfig"
+source "drivers/net/wireless/aic/Kconfig"
 source "drivers/net/wireless/ath/Kconfig"
 source "drivers/net/wireless/atmel/Kconfig"
 source "drivers/net/wireless/broadcom/Kconfig"
drivers/net/wireless/Makefile +1 -0
index e1c4141c60044..bb0c29cb3e82f 100644
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_WLAN_VENDOR_ADMTEK) += admtek/
+obj-$(CONFIG_WLAN_VENDOR_AIC) += aic/
 obj-$(CONFIG_WLAN_VENDOR_ATH) += ath/
 obj-$(CONFIG_WLAN_VENDOR_ATMEL) += atmel/
 obj-$(CONFIG_WLAN_VENDOR_BROADCOM) += broadcom/
maintainer
#5 lore raw
In reply to Yanli Yang
Quoted 2 lines · Yanli Yang

Known limitations of this RFC are:

Known to you ;-)

You're not going to go *anywhere* with this if you just resend it more or less as-is without every looking at upstream yourself.

This driver does just about everything that we don't want upstream. I plugged this into an LLM and asked it to do a brief review wrt. things that this does and upstream doesn't like, and it very quickly came up with a huge list, but you really need to do even that work yourself, nobody is going to review the driver in this shape, it's just too awful to even start.

Familiarize yourself with other drivers in the tree first, start much smaller in terms of feature set and especially Android-specific stuff, etc. Using "struct task_struct" in a driver, really?!

So you have a very very long road ahead of you, which quite likely involves more or less rewriting this driver, if you really want to see it upstream.

johannes

maintainer
#6 lore raw
Quoted 2 lines · Johannes Berg

etc. Using "struct task_struct" in a driver, really?!

That caught my eye, but actually it's just excessively so perhaps - some other wireless drivers _do_ use it. Feels a bit outdated though vs. work structs (especially wiphy work.)

Since I had the LLM review anyway, I pasted it below. I'm not saying this is correct or complete, but it may give you a hint as to why I'm not really taking this submission seriously at all.

-------
Quick review done. Here's a prioritized list of the most obvious upstream blockers in drivers/net/wireless/aic/ (~66k lines, forked from the RivieraWaves/rwnx BSP).

Custom/duplicate userspace ABIs (hard blockers)
* Private generic-netlink interface — aic8800_fdrv/aicwf_genl.c + aicwf_genl.h (AIC8800_GENL). A whole string-parsed genl family for "manufacturing and driver debugging." This is the one you mentioned — must be deleted; use nl80211 + (sparingly) cfg80211 testmode/vendor cmds.
* Android priv_cmd ioctl interpreter — aic8800_fdrv/aic_priv_cmd.c, android_priv_cmd()/aic_priv_cmd.c:1731. ~2000 lines of android_wifi_priv_cmd string commands over ifr_data. Classic downstream vendor ABI, not upstreamable.
* cfg80211 internals re-implementation / GKI shim — aic8800_fdrv/rwnx_gki.c does #include "net/wireless/core.h" (private in-tree header), defines its own rwnx_nl80211_fam and reimplements cfg80211_rx_spurious_frame() etc. Also has a bogus #include <include/linux/types.h>. Reaching into cfg80211 internals is a hard no.
* Legacy Wireless Extensions layer — aic8800_fdrv/aicwf_wext_linux.c (AIC8800_USE_WIRELESS_EXT). New drivers are nl80211-only.
* procfs suspend control — proc_create("suspend", …) in aicwf_sdio.c:105 (AIC8800_WIFI_SUSPEND_FOR_LINUX). Use standard PM/cfg80211.
* Vendor-HAL grab-bag with stubs — aic8800_fdrv/aic_vendor.c (mkeep_alive, APF, ring buffers, wake-reason counters). Several are fake/no-op, e.g. aic_dev_start_mkeep_alive() builds a packet then just kfrees it.

Kconfig / Makefile
* Config explosion — ~50+ options across Kconfig, aic8800_bsp/Kconfig, aic8800_fdrv/Kconfig. Many are porting/downstream knobs hidden behind depends on BROKEN (*_FOR_OLD_KERNEL, RWNX_TL4, RWNX_OLD_IPC, AIC8800_GKI, AIC8800_BR_SUPPORT, AIC8800_SDIO_BT, …). Upstream wants these deleted, not gated behind BROKEN.
* ccflags-$(CONFIG_x) += -DCONFIG_y anti-pattern — Makefile launders Kconfig into re-defined CONFIG_* macros to drive #ifdef soup. Use the real CONFIG_ symbols / IS_ENABLED().

Structural
* BSP + fdrv split glued by EXPORT_SYMBOL_GPL — two modules with a private exported ABI (aicbsp_set_subsys, aicbsp_get_feature, aicbsp_resv_mem_*, get_sdio_func, set_irq_handler, btchr_external_write). Should be one cleanly-layered driver.
* Bluetooth-over-SDIO reimplemented — aic8800_fdrv/aic_btsdio.c with its own char device instead of the kernel BT HCI/btsdio framework.
* Bridge "br_ext" repeater hack — aic8800_fdrv/aic_br_ext.c (AIC8800_BR_SUPPORT).
* Reinvented in-tree infra — bundled md5.c in both subdirs (use crypto/lib); own 2772-line regdb.c instead of kernel regulatory; own rwnx_wakelock.c, aicwf_tcp_ack.c (TCP-ACK filtering is stack policy, not a driver's job), Android-style prealloc/reserved-mem pools.

Portability / style
* Kernel-version + Android compat shims — aic8800_fdrv/rwnx_compat.h (LINUX_VERSION_CODE, HIGH_KERNEL_VERSION*, ANDROID_PLATFORM). In-tree code targets current kernel only.
* Private _l typedefs — aic8800_fdrv/lmac_types.h redefines u8_l/u16_l/bool_l. Worse, under CONFIG_RWNX_TL4 it does typedef u16 u8_l; (an 8-bit type aliased to 16-bit). Use kernel types.
* Too many module_params — debug levels, thread priorities, TX/RX tuning, plus country_code, ccode_channels, saved_sdk_ver, testmode as module params. Runtime config belongs in nl80211/DT, not module params.
* Checked-in generated version headers — rwnx_version_gen.h ("241c091M (master)", RELEASE_VERSION "2.0.14"), duplicated across subdirs.
* Dead/commented code & busy-waits — commented module_param/mdelay, mdelay(100) spins in the msg-tx path, msleep(2000) in priv-cmd.

-------

johannes

author
#7 lore raw

v3 cover wifi: aic: add AIC8800D80 SDIO FullMAC driver

Johannes,

Thank you for the detailed review of v2. This RFC updates the AIC8800 driver based on that feedback and narrows the initial upstream target to the AIC8800D80 U02 SDIO station path.

Compared with v2, the AIC directory is reduced from 132 to 109 submitted files and from 67,352 to 53,879 lines. The Kconfig interface is reduced to nine symbols and no longer exposes the old-kernel, GKI, Bluetooth, bridge, Android or other downstream build variants.

For ease of comparison with the v2 review, the status of each item is listed below in the same order and under the same headings. "Addressed" means the reported interface or implementation has been removed or replaced in v3. "Partly addressed" and "Open" items are not claimed as fixed by this RFC.

Custom/duplicate userspace ABIs (hard blockers)

- Private generic-netlink interface -- Open. aicwf_genl.c and aicwf_genl.h, providing the string-based AICWF_NL family, remain as the optional AIC8800_GENL build. We have confirmed this point. The implementation uses the unmodified in-kernel genl_family API, and deployed customer userspace already issues commands through this interface. Therefore we considers these files necessary: deleting them would require a substantial, coordinated change to existing userspace and is not feasible for this revision. We nevertheless understand that use of the standard generic-netlink transport does not by itself answer the upstream objection to an additional private, string-based userspace ABI. This item therefore remains open rather than being claimed as fixed.

- Android priv_cmd ioctl interpreter -- Partly addressed. The netdev ioctl entry point, android_priv_cmd(), struct android_wifi_priv_cmd, and all ifr_data handling have been removed. aic_priv_cmd.c was reduced from about 2,000 to 766 lines and is no longer reachable through that ioctl ABI. After reviewing the reduced implementation, we confirmed that the remaining command set and its firmware helpers are required and must be retained. This revision therefore keeps aic_priv_cmd.c in its reduced form. The remaining commands still need a per-command upstream review to determine whether any can use nl80211/cfg80211, cfg80211 testmode or a narrowly scoped vendor command instead.

- cfg80211 internals reimplementation/GKI shim -- Addressed. rwnx_gki.c was removed. The driver no longer includes net/wireless/core.h, declares a private nl80211 family, reimplements cfg80211 helpers, or uses the invalid include/linux/types.h include path.

- Legacy Wireless Extensions layer -- Addressed. aicwf_wext_linux.c and AIC8800_USE_WIRELESS_EXT were removed; the submitted build uses cfg80211/nl80211.

- procfs suspend control -- Addressed. The "suspend" procfs node and AIC8800_WIFI_SUSPEND_FOR_LINUX path were removed. Suspend and resume are now connected through struct dev_pm_ops on the SDIO drivers.

- Vendor-HAL grab-bag with stubs -- Addressed. aic_vendor.c and its keep-alive, APF, ring-buffer and wake-reason stub interfaces were removed.

Kconfig / Makefile

- Config explosion -- Partly addressed. The visible and hidden Kconfig interface was reduced from more than 50 symbols to nine, and the *_FOR_OLD_KERNEL, RWNX_TL4, RWNX_OLD_IPC, AIC8800_GKI, AIC8800_BR_SUPPORT, AIC8800_SDIO_BT and other downstream switches are no longer present or hidden behind BROKEN. The submitted build is restricted to the AIC8800D80 U02 SDIO station path. Some source for unselected chips/modes and disabled conditional branches still remains; it will be deleted rather than exposed as more Kconfig switches.

- ccflags-$(CONFIG_x) += -DCONFIG_y -- Open. The number of such defines was reduced, but the Makefiles still define CONFIG_SDIO_PWRCTRL, CONFIG_RWNX_FULLMAC and several driver-local feature macros. The remaining real choices need to use Kconfig symbols/IS_ENABLED(), and fixed properties of the initial baseline need ordinary internal constants after the disabled branches are removed.

Structural

- BSP/fdrv split with a private exported ABI -- Open. The two modules and cross-module exports, including aicbsp_set_subsys(), aicbsp_get_feature(), get_sdio_func() and set_irq_handler(), remain. They need to become one cleanly layered driver, with the transport and device lifecycle internal to it and the private exports removed.

- Bluetooth over SDIO -- Addressed. aic_btsdio.c, its private character device and AIC8800_SDIO_BT were removed from the series.

- br_ext repeater bridge -- Addressed. aic_br_ext.c and AIC8800_BR_SUPPORT were removed.

- Reinvented in-tree infrastructure -- Partly addressed. Both bundled md5.c copies were replaced by CRYPTO_LIB_MD5, and rwnx_wakelock.c was removed. The private regdb.c/self-managed regulatory path remains. The RX, TX-queue and reserved-memory preallocation sources or disabled branches, and the TCP-ACK filtering source, also remain in the tree, although their feature macros are not enabled by the submitted build. These remaining implementations must be removed and the normal kernel regulatory and allocation infrastructure used.

Portability / style

- Kernel-version and Android compatibility shims -- Partly addressed. The LINUX_VERSION_CODE/HIGH_KERNEL_VERSION/ANDROID_PLATFORM branches were removed and the submitted code targets current wireless-next. rwnx_compat.h still exists with current-kernel aliases and an obsolete old-kernel comment; those aliases and the stale wrapper structure still need cleanup.

- Private _l typedefs -- Addressed. u8_l, u16_l and bool_l were removed, including the erroneous u16 definition of u8_l. The code now uses kernel fixed-width types.

- Too many module parameters -- Open. Debug levels, SDIO queue/thread tuning, country_code/ccode_channels, saved_sdk_ver and many FullMAC feature parameters remain. Policy/configuration parameters must be removed or replaced by standard nl80211, cfg80211 or firmware/DT interfaces where appropriate.

- Generated version headers -- Addressed. The duplicated rwnx_version_gen.h files and their generated branch/release strings were removed.

- Dead/commented code and busy waits -- Partly addressed. The msleep(2000) private-command path and some dead/commented code were removed, but mdelay(100) remains in rwnx_msg_tx.c, other busy waits remain, and further dead/commented source still needs deletion. Each remaining delay must be audited and changed to a sleepable wait where its calling context permits.

In short, v3 removes the GKI/cfg80211 reimplementation, Wireless Extensions, procfs control, vendor-HAL stubs, Bluetooth character device, bridge extension, bundled MD5, private wakelocks, private _l types and generated version headers. Following confirmation, it retains the private generic-netlink interface and the reduced private command implementation because deployed customer userspace depends on them and removal requires a substantial coordinated userspace change. This dependency does not resolve the upstream ABI objection. The module split/private exports, Makefile CONFIG_* defines, private regulatory implementation and module-parameter cleanup also remain open. Those unresolved hard blockers are why this remains an RFC.

Validation performed for v3 against wireless-next at ac798f757d6475:

- x86-64 GCC 15.2.0 module build with AIC8800_BSP_SUPPORT=m,

    AIC8800_WLAN_SUPPORT=m and AIC8800_GENL=y using W=1;
  - scripts/checkpatch.pl, sparse and coccicheck, with no new compiler or
    sparse warnings;

- sequential application of all four patches; and
- comparison of the generated patch snapshot with the current AIC source directory.

Runtime validation was performed on AIC8800D80 U02 SDIO hardware with firmware fmacfw_8800d80_u02.bin v6.9.1.1. The following tests passed:

- driver probe/firmware boot and module unload/reload, 50 iterations

    each;
  - active and passive scanning on 2.4 and 5 GHz;
  - station mode with open, WPA2-PSK and WPA3-SAE networks;
  - disconnect/reconnect, 50 iterations, and IPv4/IPv6 connectivity;
  - TCP TX/RX throughput of 196/210 Mbps on 2.4 GHz and 375/445 Mbps on
    5 GHz;
  - UDP TX/RX throughput of 218/225 Mbps on 2.4 GHz and 422/511 Mbps on
    5 GHz;

- suspend/resume, 50 iterations, and rfkill; and
- 10 hours of continuous traffic.

No crashes, warnings, lockdep reports or firmware crashes were observed in the kernel log. Built-in and Clang builds, smatch and AP mode were not tested. Firmware redistribution permission and DT power/wake bindings also remain outstanding.

Please review whether the changes made so far meet the upstream community requirements. Since this revision is based on a refreshed set of commits, I would also appreciate another review for regressions or any additional issues exposed by the new changes.

---
v2: https://lore.kernel.org/r/[email protected]
v1: https://lore.kernel.org/r/[email protected]

Zhirun Liu (4):
wifi: aic: add SDIO BSP and build configuration
wifi: aic: add FullMAC firmware and platform interface
wifi: aic: add FullMAC WLAN driver
wifi: aic: integrate AIC8800 driver

 MAINTAINERS                                   |   10 +
 drivers/net/wireless/Kconfig                  |    1 +
 drivers/net/wireless/Makefile                 |    1 +
 drivers/net/wireless/aic/Kconfig              |   40 +
 drivers/net/wireless/aic/Makefile             |    7 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |    3 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   16 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  292 +
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 ++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   34 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1670 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  598 ++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  310 +
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |   98 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 +
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   64 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   69 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2027 ++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 +
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  464 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |   37 +
 .../net/wireless/aic/aic8800_fdrv/Makefile    |   46 +
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  |  766 +++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  103 +
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  251 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  184 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  699 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |   84 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2831 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  275 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  752 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  770 +++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  437 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3101 ++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   22 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   80 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  704 +++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5439 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        |  985 +++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1620 +++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3619 +++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  266 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2868 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  183 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1970 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2320 +++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  773 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1635 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  176 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   35 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 109 files changed, 53891 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h

base-commit: ac798f757d6475dc6fee2ec899980d6740714596

Signature · 1 line
2.34.1
author
#8 lore raw

RFC PATCH v3 1/4 wifi: aic: add SDIO BSP and build configuration

From: Zhirun Liu <[email protected]>

Add the build configuration and SDIO board-support layer for the initial AIC8800D80 U02 upstream target. The BSP handles platform power sequencing, SDIO transport setup, firmware loading and chip initialization.

Limit the selectable configuration to the D80 U02 SDIO station baseline and use the kernel crypto library for firmware MD5 diagnostics.

---
 drivers/net/wireless/aic/Kconfig              |   40 +
 drivers/net/wireless/aic/Makefile             |    7 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |    3 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   16 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  292 +++
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 +++++++++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   34 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1670 ++++++++++++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  598 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  310 +++
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |   98 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 ++
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   64 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   69 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2027 +++++++++++++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  464 ++++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 ++
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |   37 +
 .../net/wireless/aic/aic8800_fdrv/Makefile    |   46 +
 25 files changed, 7884 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
drivers/net/wireless/aic/Kconfig new file +40 -0
new file mode 100644
index 0000000000000..5218351da5e38
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config WLAN_VENDOR_AIC
+	bool "AIC devices"
+	default y
+	help
+	  Say Y to expose the AIC8800D80 U02 SDIO Wi-Fi driver.
+	  The first upstreaming target is a narrow D80 U02 SDIO station
+	  configuration; legacy transport, Bluetooth, Android, test and
+	  manufacturing build switches are intentionally not exposed.
+
+if WLAN_VENDOR_AIC
+
+menuconfig AIC8800_BSP_SUPPORT
+	tristate "AIC8800D80 U02 SDIO bus support"
+	depends on MMC
+	select CRYPTO_LIB_MD5
+	help
+	  Enable the AIC8800D80 U02 SDIO bus support package. It provides
+	  the SDIO transport, chip operations and firmware download path used
+	  by the AIC8800 FullMAC WLAN driver.
+
+	  Firmware files are loaded from the aic8800/ subdirectory of the
+	  kernel firmware search path, normally /lib/firmware/aic8800/.
+
+	  If unsure, say N.
+
+if AIC8800_BSP_SUPPORT
+
+config AIC8800_SDIO_SUPPORT
+	def_bool y
+
+config AIC8800_SDIO_PWRCTRL
+	def_bool y
+
+source "drivers/net/wireless/aic/aic8800_bsp/Kconfig"
+source "drivers/net/wireless/aic/aic8800_fdrv/Kconfig"
+
+endif # AIC8800_BSP_SUPPORT
+endif # WLAN_VENDOR_AIC
drivers/net/wireless/aic/Makefile new file +7 -0
new file mode 100644
index 0000000000000..1ce5651aa4a75
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AIC8800_BSP_SUPPORT) += aic8800_bsp/
+obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
+
+ccflags-y += -DAICWF_SDIO_SUPPORT
+ccflags-y += -DCONFIG_SDIO_PWRCTRL
drivers/net/wireless/aic/aic8800_bsp/Kconfig new file +3 -0
new file mode 100644
index 0000000000000..e82acc8875bc2
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# The D80 U02 SDIO station baseline has no selectable BSP suboptions.
drivers/net/wireless/aic/aic8800_bsp/Makefile new file +16 -0
new file mode 100644
index 0000000000000..ad9763e704b89
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AIC8800_BSP_SUPPORT) += aic8800_bsp.o
+
+aic8800_bsp-y := \
+	aic_chip_8800d80.o \
+	aic_chip_ops.o \
+	aic8800d80_compat.o \
+	aic_bsp_main.o \
+	aic_bsp_driver.o \
+	aicsdio.o \
+	aicsdio_txrxif.o
+
+ccflags-y += -I$(src)/../aic8800_fdrv
+ccflags-y += -DAICWF_SDIO_SUPPORT
+ccflags-y += -DCONFIG_SDIO_PWRCTRL
drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c new file +292 -0

292 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h new file +11 -0
new file mode 100644
index 0000000000000..a22e440b09a66
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800D80_COMPAT_H_
+#define _AIC8800D80_COMPAT_H_
+
+#include "aicsdio.h"
+
+int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c new file +1342 -0

1,342 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h new file +34 -0
new file mode 100644
index 0000000000000..0edee0f8d6cc3
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800DC_COMPAT_H_
+#define _AIC8800DC_COMPAT_H_
+
+#include <linux/types.h>
+
+#include "aicsdio.h"
+typedef u32 (*array2_tbl_t)[2];
+typedef u32 (*array3_tbl_t)[3];
+
+extern u8 chip_sub_id;
+extern u8 chip_mcu_id;
+#define FW_PATH_MAX_LEN 200
+
+void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+int rwnx_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
+int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
+int start_from_bootrom_8800DC(struct aic_sdio_dev *sdiodev);
+
+#ifdef CONFIG_DPD
+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev,
+			   struct rf_misc_ram_lite_t *dpd_res);
+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev,
+				  struct rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev,
+				 struct rf_misc_ram_lite_t *dpd_res);
+#endif /* !CONFIG_FORCE_DPD_CALIB */
+#endif
+
+int set_bbpll_config(struct aic_sdio_dev *rwnx_hw);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c new file +1670 -0

1,255 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h new file +598 -0

598 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h new file +70 -0

70 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +310 -0

310 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c new file +98 -0

98 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c new file +133 -0

133 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c new file +117 -0

117 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c new file +64 -0

64 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h new file +69 -0

69 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.c new file +2027 -0

2,027 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.h new file +176 -0

176 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c new file +464 -0

464 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h new file +180 -0

180 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c new file +72 -0

72 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h new file +8 -0
new file mode 100644
index 0000000000000..680d37ffca931

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/Kconfig new file +37 -0
new file mode 100644
index 0000000000000..59cf740aa6202

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/Makefile new file +46 -0

46 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

#9 lore raw

Re: [RFC PATCH wireless-next v3 1/4] wifi: aic: add SDIO BSP and build configuration

Quoted 11 lines · Yanli Yang

From: Zhirun Liu <[email protected]>

Add the build configuration and SDIO board-support layer for the initial AIC8800D80 U02 upstream target. The BSP handles platform power sequencing, SDIO transport setup, firmware loading and chip initialization.

Limit the selectable configuration to the D80 U02 SDIO station baseline and use the kernel crypto library for firmware MD5 diagnostics.

You still did not run checkpatch and has obvious issues pointed out by it, but more importantly - you still did not document bindings for your device.

...

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c line 181

Quoted 6 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +6 -0
+
+static DEVICE_ATTR_RW(hwinfo);
+
+static DEVICE_ATTR_RW(fwdebug);
+
+static DEVICE_ATTR_RW(adapt);

Where did you document the sysfs ABI?

Quoted 5 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +5 -0
+
+static struct attribute *aicbsp_attributes[] = {
+	&dev_attr_hwinfo.attr,
+	&dev_attr_fwdebug.attr,
+	&dev_attr_adapt.attr,

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c line 196

Quoted 10 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +10 -0
+	NULL,
+};
+
+static struct attribute_group aicbsp_attribute_group = {
+	.name = "aicbsp_info",
+	.attrs = aicbsp_attributes,
+};
+
+int testmode = AICBSP_CPMODE_DEFAULT;
+int adap_test;

Drop, not suitable for module params.

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c line 201

Quoted 5 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +5 -0
+module_param(adap_test, int, 0660);
+
+#if defined CONFIG_PLATFORM_EXTERNAL && defined CONFIG_CUSTOM_PWF
+int gpio_pwr;
+bool gpio_pwr_assert;

You should not have globals. You need properly organize Linux device driver structures.

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c line 214

Quoted 13 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +13 -0
+
+void nxp_pwr_ctrl(int value)
+{
+	pr_info("aic_bsp: %s: %d\n", __func__, value);
+	gpio_set_value(gpio_pwr, value);
+}
+
+static int aicbsp_pwr_node(void)
+{
+	struct device_node *np;
+	int err;
+
+	np = of_find_compatible_node(NULL, NULL, "aic,wifi-power");

Undocumented compatible. But also unlikely to be accepted. Please read writing bindings, DTS101 slides or some other guidelines for beginners, how to properly describe hardware in DTS.

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c line 220

Quoted 6 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +6 -0
+	if (!np) {
+		pr_err("aic_bsp: %s np not found\n", __func__);
+		return -ENODEV;
+	}
+
+	gpio_pwr = of_get_named_gpio(np, "wifi-power", 0);

Do not use legacy API. Please open recent Linux drivers and look how they manage GPIOs.

Quoted 5 lines
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +5 -0
+	if (!gpio_is_valid(gpio_pwr)) {
+		pr_err("aic_bsp: %s is invalid\n", __func__);
+		return -ENODEV;
+	}
+

...

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c line 21

Quoted 2 lines
drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c new file +2 -0
+
+	(void)testmode;

Heh?

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c line 27

Quoted 6 lines
drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c new file +6 -0
+	aicbsp_firmware_list = fw_8800d80_u02;
+	aicbsp_info.cpmode = AICBSP_CPMODE_WORK;
+	if (!fw_path)
+		return -ENOENT;
+
+	pr_info("aicbsp 8800d80 u02 wifi firmware: %s\n", fw_path);

Why your driver does not use dev_* calls? And why does it print so much?

Drivers should be silent on success:
https://elixir.bootlin.com/linux/v6.15-rc7/source/Documentation/process/coding-style.rst#L913
https://elixir.bootlin.com/linux/v6.15-rc7/source/Documentation/process/debugging/driver_development_debugging_guide.rst#L79

...

Quoted 33 lines
drivers/net/wireless/aic/aic8800_fdrv/Makefile new file +33 -0
+
+aic8800_fdrv-y := \
+	rwnx_msg_tx.o \
+	rwnx_msg_rx.o \
+	rwnx_utils.o \
+	rwnx_cmds.o \
+	rwnx_irqs.o \
+	rwnx_cfgfile.o \
+	rwnx_strs.o \
+	rwnx_rx.o \
+	rwnx_tx.o \
+	rwnx_txq.o \
+	rwnx_main.o \
+	rwnx_mod_params.o \
+	rwnx_platform.o \
+	aicwf_chip_8800d80.o \
+	aicwf_chip_ops.o \
+	rwnx_v7.o \
+	ipc_host.o \
+	aicwf_compat_8800d80.o \
+	regdb.o \
+	aic_priv_cmd.o \
+	sdio_host.o \
+	aicwf_txrxif.o \
+	aicwf_sdio.o \
+	aicwf_rx_prealloc.o
+
+aic8800_fdrv-$(CONFIG_AIC8800_NONSTA_SUPPORT) += rwnx_mesh.o rwnx_tdls.o
+
+aic8800_fdrv-$(CONFIG_AIC8800_GENL) += aicwf_genl.o
+
+ccflags-y += -I$(srctree)
+ccflags-y += -I$(src)

drivers/net/wireless/aic/aic8800_fdrv/Makefile line 46

Quoted 10 lines
drivers/net/wireless/aic/aic8800_fdrv/Makefile new file +10 -0
+ccflags-y += -I$(src)/../aic8800_bsp
+ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src)
+ccflags-y += -DAICWF_SDIO_SUPPORT
+ccflags-y += -DCONFIG_SDIO_PWRCTRL
+ccflags-y += -DCONFIG_RWNX_FULLMAC
+ccflags-y += -DUSE_5G
+ccflags-y += -DAICWF_RX_REORDER
+ccflags-y += -DAICWF_ARP_OFFLOAD
+ccflags-y += -DCONFIG_RX_NETIF_RECV_SKB
+ccflags-y += -DCONFIG_AIC8800_RX_NETIF_RECV_SKB

I do not understand what is a ll this. Looks like out of tree module build. We do not define defines via Makefile. Integrate the driver into Linux.

Best regards,
Krzysztof

author
#10 lore raw

RFC PATCH v3 2/4 wifi: aic: add FullMAC firmware and platform interface

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the LMAC message definitions, IPC host support, firmware command/event handling and platform bring-up required by the AIC8800D80 U02 FullMAC firmware.

The interface is scoped to the current in-tree kernel APIs and the SDIO station baseline selected by the first patch.

---
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  770 ++++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  437 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3101 ++++++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   22 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   80 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  704 ++++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1620 ++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3619 +++++++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  266 ++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2868 +++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  183 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   35 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 32 files changed, 17088 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h new file +62 -0
new file mode 100644
index 0000000000000..11b414df42ce3
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __AIC_BSP_EXPORT_H
+#define __AIC_BSP_EXPORT_H
+
+#include <linux/types.h>
+
+enum aicbsp_subsys {
+	AIC_BLUETOOTH,
+	AIC_WIFI,
+};
+
+enum aicbsp_pwr_state {
+	AIC_PWR_OFF,
+	AIC_PWR_ON,
+};
+
+struct aicbsp_feature_t {
+	int hwinfo;
+	u32 sdio_clock;
+	u8 sdio_phase;
+	int fwlog_en;
+	u8 irqf;
+	u8 cpmode;
+	int adapt;
+};
+
+enum skb_buff_id {
+	AIC_RESV_MEM_TXDATA,
+};
+
+#ifdef CONFIG_DPD
+struct rf_misc_ram_t {
+	u32 bit_mask[3];
+	u32 reserved;
+	u32 dpd_high[96];
+	u32 dpd_11b[96];
+	u32 dpd_low[96];
+	u32 idac_11b[48];
+	u32 idac_high[48];
+	u32 idac_low[48];
+	u32 loft_res[18];
+	u32 rx_iqim_res[16];
+};
+
+struct rf_misc_ram_lite_t {
+	u32 bit_mask[4];
+	u32 dpd_high[96];
+	u32 loft_res[18];
+};
+
+#define MEMBER_SIZE(type, member) sizeof_field(type, member)
+#define DPD_RESULT_SIZE_8800DC    sizeof(struct rf_misc_ram_lite_t)
+
+extern struct rf_misc_ram_lite_t dpd_res;
+#endif
+
+int aicbsp_set_subsys(int, int);
+int aicbsp_get_feature(struct aicbsp_feature_t *feature);
+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);
+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id);
+
+#endif
drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h new file +191 -0

191 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h new file +37 -0
new file mode 100644
index 0000000000000..4a49c16f15a31
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_DEBUG_H_
+#define _AICWF_DEBUG_H_
+
+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
+
+/* message levels */
+#define LOGERROR    0x0001
+#define LOGINFO     0x0002
+#define LOGTRACE    0x0004
+#define LOGDEBUG    0x0008
+#define LOGDATA     0x0010
+#define LOGIRQ      0x0020
+#define LOGSDPWRC   0x0040
+#define LOGWAKELOCK 0x0080
+#define LOGRXPOLL   0x0100
+
+extern int aicwf_dbg_level;
+void rwnx_data_dump(char *tag, void *data, unsigned long len);
+
+#define AICWF_LOG "AICWFDBG("
+
+#define AICWFDBG(level, args, arg...)                                          \
+	do {                                                                       \
+		if (aicwf_dbg_level & (level)) {                                         \
+			pr_debug(AICWF_LOG #level ")\t" args, ##arg);                        \
+		}                                                                      \
+	} while (0)
+
+#define RWNX_DBG(fmt, ...)                                                     \
+	do {                                                                       \
+		if (aicwf_dbg_level & LOGTRACE) {                                      \
+			pr_debug(AICWF_LOG "LOGTRACE)\t" fmt, ##__VA_ARGS__);                \
+		}                                                                      \
+	} while (0)
+
+#endif /* _AICWF_DEBUG_H_ */
drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h new file +359 -0

359 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h new file +25 -0
new file mode 100644
index 0000000000000..cf1fe0d737b84
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ ****************************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ ****************************************************************************************
+ */
+
+#ifndef _IPC_H_
+#define _IPC_H_
+
+#define __INLINE inline
+
+#define __ALIGN4 __aligned(4)
+
+#define ASSERT_ERR(condition)                                                  \
+	do {                                                                       \
+		if (unlikely(!(condition))) {                                          \
+			pr_err("%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__,    \
+				   __LINE__);                                                  \
+		}                                                                      \
+	} while (0)
+
+#endif /* _IPC_H_ */
drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c new file +42 -0

42 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h new file +169 -0

169 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h new file +770 -0

770 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h new file +437 -0

437 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h new file +3101 -0

908 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h new file +22 -0
new file mode 100644
index 0000000000000..76f251607a7b9

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/reg_access.h new file +146 -0

146 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c new file +471 -0

471 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h new file +99 -0

99 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h new file +80 -0

80 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h new file +704 -0

704 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h new file +938 -0

938 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c new file +49 -0

49 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h new file +12 -0
new file mode 100644
index 0000000000000..ff6c766c727c3

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c new file +1620 -0

1,620 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h new file +8 -0
new file mode 100644
index 0000000000000..211f2e616cbf4

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c new file +3619 -0

3,619 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h new file +266 -0

266 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c new file +2868 -0

2,868 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h new file +183 -0

183 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h new file +142 -0

142 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c new file +269 -0

269 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h new file +31 -0
new file mode 100644
index 0000000000000..1b4df40f2a912

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c new file +35 -0
new file mode 100644
index 0000000000000..73e8ab7c8af5c

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h new file +131 -0

131 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c new file +181 -0

181 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h new file +21 -0
new file mode 100644
index 0000000000000..709553f96c2a1

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

author
#11 lore raw

RFC PATCH v3 3/4 wifi: aic: add FullMAC WLAN driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the cfg80211 FullMAC implementation, TX/RX data paths, SDIO host glue and AIC8800D80 U02 chip operations. Normal Wi-Fi control is exposed through cfg80211/nl80211 and system suspend is handled through the SDIO dev_pm_ops.

The Android private ioctl, Wireless Extensions, GKI shim, vendor-HAL stubs, Bluetooth character device and bridge extension present in earlier RFCs are not included.

---
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  |  766 +++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  103 +
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  251 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  184 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  699 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |   84 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2831 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  275 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  752 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5439 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        |  985 +++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1970 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2320 +++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  773 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1635 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  176 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 49 files changed, 28907 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h
drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c new file +766 -0
new file mode 100644
index 0000000000000..b5f5869284dfa
@@ -0,0 +1,766 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ ******************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ * @brief private command definition
+ *
+ ******************************************************************************
+ */
+
+#include "aic_priv_cmd.h"
+#include "aicwf_sdio.h"
+#include "rwnx_defs.h"
+#include "rwnx_main.h"
+#include "rwnx_mod_params.h"
+#include "rwnx_msg_tx.h"
+#include "rwnx_platform.h"
+#include <linux/ctype.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+#include "aicwf_compat_8800d80.h"
+#endif
+
+static void print_help(const char *cmd);
+struct dbg_rftest_cmd_cfm cfm = {{
+	0,
+}};
+
+struct cmd_ef_usrdata {
+	u8 func;
+	u8 cnt;
+	u8 reserved[2];
+	u32 usrdata[3];
+};
+
+#define CMD_MAXARGS 224
+
+static int parse_line(char *line, char *argv[])
+{
+	int nargs = 0;
+
+	while (nargs < CMD_MAXARGS) {
+		/* skip any white space */
+		while ((*line == ' ') || (*line == '\t'))
+			++line;
+
+		if (*line == '\0') { /* end of line, no more args    */
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		/* Argument include space should be bracketed by quotation mark */
+		if (*line == '\"') {
+			/* Skip quotation mark */
+			line++;
+
+			/* Begin of argument string */
+			argv[nargs++] = line;
+
+			/* Until end of argument */
+			while (*line && (*line != '\"'))
+				++line;
+		} else {
+			argv[nargs++] = line; /* begin of argument string    */
+
+			/* find end of string */
+			while (*line && (*line != ' ') && (*line != '\t'))
+				++line;
+		}
+
+		if (*line == '\0') { /* end of line, no more args    */
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		*line++ = '\0'; /* terminate current arg     */
+	}
+
+	pr_info("** Too many args (max. %d) **\n", CMD_MAXARGS);
+
+	return nargs;
+}
+
+unsigned int command_strtoul(const char *cp, char **endp, unsigned int base)
+{
+	unsigned int result = 0, value, is_neg = 0;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+	if (*cp == '-') {
+		is_neg = 1;
+		cp++;
+	}
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp - '0'
+		: (islower(*cp) ? toupper(*cp) : *cp) - 'A' +
+		10) < base) {
+		result = result * base + value;
+		cp++;
+	}
+	if (is_neg)
+		result = (unsigned int)((int)result * (-1));
+
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+/*
+ * aic_priv_cmd handers.
+ */
+
+static int aic_priv_cmd_set_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	u8 mac_addr[6];
+
+	if (argc < 7)
+		return -EINVAL;
+
+	mac_addr[5] = command_strtoul(argv[1], NULL, 16);
+	mac_addr[4] = command_strtoul(argv[2], NULL, 16);
+	mac_addr[3] = command_strtoul(argv[3], NULL, 16);
+	mac_addr[2] = command_strtoul(argv[4], NULL, 16);
+	mac_addr[1] = command_strtoul(argv[5], NULL, 16);
+	mac_addr[0] = command_strtoul(argv[6], NULL, 16);
+	AICWFDBG(LOGINFO, "set macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5],
+		 mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]);
+	rwnx_send_rftest_req(rwnx_hw, SET_MAC_ADDR, sizeof(mac_addr),
+			     (u8 *)&mac_addr, NULL);
+	return 0;
+}
+
+static int aic_priv_cmd_get_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	aic_chip_priv_cmd_get_mac_addr(rwnx_hw, argc, argv, command);
+	return 8;
+}
+
+static int aic_priv_cmd_set_bt_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	u8 mac_addr[6];
+
+	if (argc < 7)
+		return -EINVAL;
+
+	mac_addr[5] = command_strtoul(argv[1], NULL, 16);
+	mac_addr[4] = command_strtoul(argv[2], NULL, 16);
+	mac_addr[3] = command_strtoul(argv[3], NULL, 16);
+	mac_addr[2] = command_strtoul(argv[4], NULL, 16);
+	mac_addr[1] = command_strtoul(argv[5], NULL, 16);
+	mac_addr[0] = command_strtoul(argv[6], NULL, 16);
+	AICWFDBG(LOGINFO, "set bt macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5],
+		 mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]);
+	rwnx_send_rftest_req(rwnx_hw, SET_BT_MAC_ADDR, sizeof(mac_addr),
+			     (u8 *)&mac_addr, NULL);
+	return 0;
+}
+
+static int aic_priv_cmd_get_bt_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	aic_chip_priv_cmd_get_bt_mac_addr(rwnx_hw, argc, argv, command);
+	return 8;
+}
+
+#ifdef CONFIG_AIC8800_AUTO_CUSTREG
+static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	int ret = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]);
+	if (strncmp(argv[1], "AUTO", 4) == 0) {
+		rwnx_hw->ccode.auto_set = true;
+		rwnx_hw->ccode.ccode_set = false;
+		rwnx_hw->ccode.ccode_cnt = 0;
+		rwnx_hw->ccode.ccode_rssi = -100;
+	} else if (strncmp(argv[1], "MANUAL", 6) == 0) {
+		rwnx_hw->ccode.auto_set = false;
+		rwnx_hw->ccode.ccode_set = true;
+	} else {
+		rwnx_hw->ccode.ccode_set = true;
+		ret = rwnx_regulatory_set_wiphy_regd(rwnx_hw->wiphy,
+						     get_regdomain_from_rwnx_db(rwnx_hw->wiphy,
+										argv[1]));
+		memcpy(rwnx_hw->country_abbr, argv[1], 2);
+		rwnx_hw->ccode.ccode_cnt = 0;
+#ifdef CONFIG_AIC8800_REGION_PW
+		rwnx_send_txpwr_lvl_v3_req(rwnx_hw, get_ccode_region(rwnx_hw->country_abbr));
+#endif
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+		aic_chip_powerlimit_load(rwnx_hw);
+		if (!rwnx_hw->testmode)
+			rwnx_send_me_chan_config_req(rwnx_hw);
+#endif
+	}
+	return ret;
+}
+
+static int aic_priv_cmd_country_get(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	const struct ieee80211_regdomain *regd;
+	u8 buf[3];
+	int bytes_written = 0;
+
+	rcu_read_lock();
+	regd = rcu_dereference(rwnx_hw->wiphy->regd);
+	if (!regd) {
+		rcu_read_unlock();
+		return -ENODATA;
+	}
+	buf[0] = regd->alpha2[0];
+	buf[1] = regd->alpha2[1];
+	rcu_read_unlock();
+	buf[2] = rwnx_hw->ccode.auto_set;
+	memcpy(command, &buf[0], 3);
+	bytes_written = 3;
+	AICWFDBG(LOGINFO, "cmd country_get: %c%c\n", command[0], command[1]);
+
+	return bytes_written;
+}
+#endif
+
+#ifdef CONFIG_AIC8800_TEMP_CONTROL
+static int aic_priv_cmd_temp_ctrl_sw(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	if (command_strtoul(argv[1], NULL, 10) == 0) {
+		AICWFDBG(LOGINFO, "tp to off\n");
+		rwnx_hw->sdiodev->tp_ctrl.on_off = false;
+		rwnx_hw->sdiodev->tp_ctrl.get_level = 0;
+		spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+		rwnx_hw->sdiodev->tp_ctrl.tm_start = 0;
+		if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer))
+			//del_timer_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+			timer_delete_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+		spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+	} else if (command_strtoul(argv[1], NULL, 10) == 1) {
+		AICWFDBG(LOGINFO, "tp to on\n");
+		rwnx_hw->sdiodev->tp_ctrl.on_off = true;
+		spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+		rwnx_hw->sdiodev->tp_ctrl.tm_start = 1;
+		mod_timer(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer,
+			  jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL));
+		spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+	} else {
+		AICWFDBG(LOGINFO, "tp err param\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int aic_priv_cmd_temp_sget(struct rwnx_hw *rwnx_hw, int argc,
+				  char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+	s8 tp_res[4];
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 0) {                            // get
+		if (rwnx_hw->sdiodev->tp_ctrl.on_off) { // on
+			tp_res[0] = 1;
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level == 0)
+				tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.get_level;
+			else
+				tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.set_level;
+			AICWFDBG(LOGINFO, "tp_get on-off: %d, ctrl-level: %d\n", tp_res[0],
+				 tp_res[1]);
+			memcpy(command, &tp_res[0], 2);
+			bytes_written = 2;
+		} else { // off
+			tp_res[0] = 0;
+			AICWFDBG(LOGINFO, "tp_get on-off: %d\n", tp_res[0]);
+			memcpy(command, &tp_res[0], 1);
+			bytes_written = 1;
+		}
+	} else if (func == 1) { // set
+		if (!rwnx_hw->sdiodev->tp_ctrl.on_off) {
+			AICWFDBG(LOGINFO, "tp_set sw is off, return\n");
+			tp_res[0] = 0;
+			memcpy(command, &tp_res[0], 1);
+			bytes_written = 1;
+		} else {
+			if (argc < 3) {
+				AICWFDBG(LOGINFO, "%s param err\n", __func__);
+				return -1;
+			}
+			rwnx_hw->sdiodev->tp_ctrl.set_level =
+				command_strtoul(argv[2], NULL, 10);
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level < 0 ||
+			    rwnx_hw->sdiodev->tp_ctrl.set_level > 2) {
+				AICWFDBG(LOGINFO, "set_level out of range\n");
+				rwnx_hw->sdiodev->tp_ctrl.set_level = 0;
+			}
+			rwnx_hw->sdiodev->tp_ctrl.get_level = 0;
+			tp_res[0] = 1;
+			tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.set_level;
+			AICWFDBG(LOGINFO, "tp_set ctrl-level: %d\n",
+				 rwnx_hw->sdiodev->tp_ctrl.set_level);
+			memcpy(command, &tp_res[0], 2);
+			bytes_written = 2;
+
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level != 0) {
+				spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+				rwnx_hw->sdiodev->tp_ctrl.tm_start = 0;
+				if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer))
+					//del_timer_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+					timer_delete_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+				spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+			} else if (rwnx_hw->sdiodev->tp_ctrl.set_level == 0) {
+				spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+				rwnx_hw->sdiodev->tp_ctrl.tm_start = 1;
+				mod_timer(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer,
+					  jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL));
+				spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+			}
+		}
+	} else {
+		AICWFDBG(LOGINFO, "tp command err\n");
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_set_tmr_intval(struct rwnx_hw *rwnx_hw, int argc,
+				       char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 3) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 1) {
+		rwnx_hw->sdiodev->tp_ctrl.interval_t1 =
+			command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGDEBUG, "set tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t1, 4);
+		bytes_written = 4;
+	} else if (func == 2) {
+		rwnx_hw->sdiodev->tp_ctrl.interval_t2 =
+			command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGDEBUG, "set tmr_intval_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t2, 4);
+		bytes_written = 4;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_get_tmr_intval(struct rwnx_hw *rwnx_hw, int argc,
+				       char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 1) {
+		AICWFDBG(LOGDEBUG, "get tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t1, 4);
+		bytes_written = 4;
+	} else if (func == 2) {
+		AICWFDBG(LOGDEBUG, "get tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t2, 4);
+		bytes_written = 4;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_temp_get(struct rwnx_hw *rwnx_hw, int argc,
+				 char *argv[], char *command)
+{
+	int bytes_written = 0;
+	struct mm_set_vendor_swconfig_cfm tp_cfm;
+
+	if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer)) {
+		if (jiffies_to_msecs(jiffies - rwnx_hw->started_jiffies) < 5000) {
+			AICWFDBG(LOGINFO, "tp_get temp_1: %d\n", rwnx_hw->temp);
+			memcpy(command, &rwnx_hw->temp, 1);
+		} else {
+			if (rwnx_send_get_temp_req(rwnx_hw, &tp_cfm))
+				return -1;
+			AICWFDBG(LOGINFO, "tp_get temp_2: %d\n",
+				 tp_cfm.temp_comp_get_cfm.degree);
+			rwnx_hw->sdiodev->tp_ctrl.cur_temp =
+				tp_cfm.temp_comp_get_cfm.degree;
+			memcpy(command, &tp_cfm.temp_comp_get_cfm.degree, 1);
+		}
+	} else {
+		if (rwnx_send_get_temp_req(rwnx_hw, &tp_cfm))
+			return -1;
+		AICWFDBG(LOGINFO, "tp_get temp_3: %d\n",
+			 tp_cfm.temp_comp_get_cfm.degree);
+		memcpy(command, &tp_cfm.temp_comp_get_cfm.degree, 1);
+	}
+	bytes_written = 1;
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_tp_thd_set(struct rwnx_hw *rwnx_hw, int argc,
+				   char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 3) {
+		AICWFDBG(LOGERROR, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+	if (func == 1) {
+		rwnx_hw->sdiodev->tp_ctrl.tp_thd_1 = command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGINFO, "set tp_thd_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_1, 1);
+		bytes_written = 1;
+	} else if (func == 2) {
+		rwnx_hw->sdiodev->tp_ctrl.tp_thd_2 = command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGINFO, "set tp_thd_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_2, 1);
+		bytes_written = 1;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+	return bytes_written;
+}
+
+static int aic_priv_cmd_tp_thd_get(struct rwnx_hw *rwnx_hw, int argc,
+				   char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGERROR, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+	if (func == 1) {
+		AICWFDBG(LOGINFO, "get tp_thd_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_1, 1);
+		bytes_written = 1;
+	} else if (func == 2) {
+		AICWFDBG(LOGINFO, "set tp_thd_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_2, 1);
+		bytes_written = 1;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+	return bytes_written;
+}
+
+#endif
+static int aic_priv_cmd_set_suspend(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	u8 func = 0;
+	s8 err = -1;
+	int ret = 0;
+
+	if (argc < 2 || rwnx_hw->testmode != 0) {
+		AICWFDBG(LOGERROR, "%s param err or in rf_test mode\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+#ifndef CONFIG_AIC8800_AUTO_POWERSAVE
+	if (func == 0) {
+		AICWFDBG(LOGINFO, "priv_cmd suspend 0\n");
+		ret = rwnx_send_me_set_lp_level(rwnx_hw, 0, 1);
+	} else if (func == 1) {
+		AICWFDBG(LOGINFO, "priv_cmd suspend 1\n");
+		ret = rwnx_send_me_set_lp_level(rwnx_hw, 1, 0);
+		if (rwnx_hw->scan_request && rwnx_hw->scanning) {
+			pr_info("AICWF enter suspend, stop scan\n");
+			ret = rwnx_send_scanu_cancel_req(rwnx_hw, NULL);
+			/* make sure fw take effect */
+			msleep(50);
+			if (ret) {
+				pr_info("AICWF %s scanu_cancel fail\n", __func__);
+				return ret;
+			}
+		}
+	} else {
+		AICWFDBG(LOGERROR, "param err\n");
+		ret = -1;
+	}
+#else
+	func = 15;
+#endif
+
+	if (ret == 0) {
+		memcpy(command, &func, 1);
+		return 1;
+	}
+	memcpy(command, &err, 1);
+	return 1;
+}
+
+static int aic_priv_cmd_get_version(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	int bytes_written = 0;
+
+	AICWFDBG(LOGINFO, "Firmware Version: %s\n", rwnx_hw->fw_version);
+	memcpy(command, rwnx_hw->fw_version, 32);
+	bytes_written = 32;
+	return bytes_written;
+}
+
+static int aic_priv_cmd_get_link_status(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	struct rwnx_vif *rwnx_vif = NULL;
+	struct rwnx_vif *rwnx_vif_st = NULL;
+	struct wf_bss_info bi;
+
+	bi.length = 0;
+	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
+		if (rwnx_vif && rwnx_vif->up &&
+		    (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION))
+			rwnx_vif_st = rwnx_vif;
+	}
+	if (!rwnx_vif_st) {
+		AICWFDBG(LOGINFO, "rwnx_vif_st is NULL\n");
+		memcpy(command, &bi, 4);
+		return 4;
+	}
+	if (atomic_read(&rwnx_vif_st->drv_conn_state) !=
+		(int)RWNX_DRV_STATUS_CONNECTED) {
+		AICWFDBG(LOGINFO, "rwnx_vif_st is not conncet\n");
+		memcpy(command, &bi, 4);
+		return 4;
+	}
+
+	bi.ssid_len = rwnx_vif_st->sta.ssid_len;
+	bi.band = rwnx_vif_st->sta.ap->band;
+	bi.width = rwnx_vif_st->sta.ap->width;
+	bi.center_freq = rwnx_vif_st->sta.ap->center_freq;
+	bi.center_freq1 = rwnx_vif_st->sta.ap->center_freq1;
+	bi.center_freq2 = rwnx_vif_st->sta.ap->center_freq2;
+	bi.ht = rwnx_vif_st->sta.ap->ht;
+	bi.vht = rwnx_vif_st->sta.ap->vht;
+	bi.chan = ieee80211_frequency_to_channel(bi.center_freq);
+	memcpy(bi.bssid, rwnx_vif_st->sta.bssid, ETH_ALEN);
+	memset(bi.ssid, 0, sizeof(bi.ssid));
+	memcpy(bi.ssid, rwnx_vif_st->sta.ssid, rwnx_vif_st->sta.ssid_len);
+	bi.length = sizeof(bi);
+
+	memcpy(command, &bi, bi.length);
+	return bi.length;
+}
+
+static int aic_priv_cmd_get_auth_type(struct rwnx_hw *rwnx_hw, int argc,
+				      char *argv[], char *command)
+{
+	struct rwnx_vif *rwnx_vif = NULL;
+	s32 val = -1;
+
+	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
+		if (rwnx_vif && rwnx_vif->up &&
+		    (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION) &&
+			atomic_read(&rwnx_vif->drv_conn_state) ==
+				(int)RWNX_DRV_STATUS_CONNECTED)
+			val = rwnx_vif->sta.auth_type;
+	}
+
+	memcpy(command, &val, 4);
+	return 4;
+}
+
+static int aic_priv_cmd_help(struct rwnx_hw *rwnx_hw, int argc, char *argv[],
+			     char *command)
+{
+	print_help(argc > 0 ? argv[0] : NULL);
+	return 0;
+}
+
+struct aic_priv_cmd {
+	const char *cmd;
+	int (*handler)(struct rwnx_hw *rwnx_hw, int argc, char *argv[],
+		       char *command);
+	const char *usage;
+};
+
+static const struct aic_priv_cmd aic_priv_commands[] = {
+	{"set_mac_addr", aic_priv_cmd_set_mac_addr,
+	 "= write WiFi MAC into efuse or flash is limited to a maximum of two times"
+	 },
+	{"get_mac_addr", aic_priv_cmd_get_mac_addr,
+	 "= display WiFi MAC stored in efuse or flash"},
+	{"set_bt_mac_addr", aic_priv_cmd_set_bt_mac_addr,
+	 "= write BT MAC into efuse or flash is limited to a maximum of two times"},
+	{"get_bt_mac_addr", aic_priv_cmd_get_bt_mac_addr,
+	 "= display BT MAC stored in efuse or flash"},
+
+	/* The following is not an RF cmd */
+#ifdef CONFIG_AIC8800_AUTO_CUSTREG
+	{"country_set", aic_priv_cmd_country_set, "<ccode>"},
+	{"country_get", aic_priv_cmd_country_get, "no param"},
+#endif
+#ifdef CONFIG_AIC8800_TEMP_CONTROL
+	{"TEMP_CTRL_SW", aic_priv_cmd_temp_ctrl_sw, "<val> 1--open, 0--close"},
+	{"TEMP_CTRL_SET_GET", aic_priv_cmd_temp_sget,
+	 "<option> <val> option--0-get,1-set; val--0/1/2"},
+	{"SET_TMR_INTVAL", aic_priv_cmd_set_tmr_intval,
+	 "<index> <time> index--0/1, time ms"},
+	{"GET_TMR_INTVAL", aic_priv_cmd_get_tmr_intval, "<index> index--0/1"},
+	{"TEMP_GET", aic_priv_cmd_temp_get, "no param"},
+	{"TEMP_THRESHOLD_SET", aic_priv_cmd_tp_thd_set,
+	 "<index> <val> index--0/1, val--degree centigrade"},
+	{"TEMP_THRESHOLD_GET", aic_priv_cmd_tp_thd_get, "<index> inddex--0/1"},
+#endif
+	{"set_suspend", aic_priv_cmd_set_suspend,
+	 "<mode>, 1/0----enter/exit lp_level"},
+	{"get_version", aic_priv_cmd_get_version, "no param, get fw version"},
+	{"status", aic_priv_cmd_get_link_status, "no param, get link status"},
+	{"wpa_auth", aic_priv_cmd_get_auth_type,
+	 "no param, get AuthenticationType"},
+
+	// Reserve for new aic_priv_cmd.
+	{"help", aic_priv_cmd_help, "= show usage help"},
+	{NULL, NULL, NULL}
+
+};
+
+/*
+ * Prints command usage, lines are padded with the specified string.
+ */
+static void print_help(const char *cmd)
+{
+	int n;
+
+	pr_info("commands:\n");
+	for (n = 0; aic_priv_commands[n].cmd; n++) {
+		if (cmd)
+			pr_info("%s %s\n", aic_priv_commands[n].cmd,
+				aic_priv_commands[n].usage);
+	}
+}
+
+int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
+{
+	const struct aic_priv_cmd *cmd, *match = NULL;
+	int count;
+	int bytes_written = 0;
+	char **argv = NULL;
+	int argc;
+	struct rwnx_vif *vif =
+		container_of(net->ieee80211_ptr, struct rwnx_vif, wdev);
+	struct rwnx_hw *p_rwnx_hw = vif->rwnx_hw;
+
+	RWNX_DBG(RWNX_FN_ENTRY_STR);
+
+	argv = kzalloc((CMD_MAXARGS + 1) * sizeof(char *), GFP_KERNEL);
+	if (!argv) {
+		AICWFDBG(LOGERROR, "%s alloc argv fail\n", __func__);
+		return -ENOMEM;
+	}
+
+	argc = parse_line(command, argv);
+	if (argc == 0 || argc > CMD_MAXARGS) {
+		AICWFDBG(LOGERROR, "%s params error, count: %d\n", __func__, argc);
+		kfree(argv);
+		return -EINVAL;
+	}
+
+	count = 0;
+	cmd = aic_priv_commands;
+	while (cmd->cmd) {
+		if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0 &&
+		    strncasecmp(cmd->cmd, argv[0], strlen(cmd->cmd)) == 0) {
+			match = cmd;
+			if (strcasecmp(cmd->cmd, argv[0]) == 0) {
+				/* we have an exact match */
+				count = 1;
+				break;
+			}
+			count++;
+		}
+		cmd++;
+	}
+
+	if (count > 1) {
+		AICWFDBG(LOGINFO,
+			 "Ambiguous command '%s'; possible commands:", argv[0]);
+		cmd = aic_priv_commands;
+		while (cmd->cmd) {
+			if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0)
+				AICWFDBG(LOGINFO, " %s", cmd->cmd);
+			cmd++;
+		}
+		AICWFDBG(LOGINFO, "\n");
+	} else if (count == 0) {
+		AICWFDBG(LOGERROR, "Unknown command '%s'\n", argv[0]);
+		kfree(argv);
+		return -EINVAL;
+	}
+	AICWFDBG(LOGINFO, "match %s", match->cmd);
+	bytes_written = match->handler(p_rwnx_hw, argc, &argv[0], command);
+
+	if (bytes_written < 0)
+		AICWFDBG(LOGERROR, "wrong param\n");
+
+	kfree(argv);
+	return bytes_written;
+}
drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h new file +103 -0

103 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c new file +291 -0

291 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c new file +300 -0

300 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c new file +279 -0

279 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c new file +251 -0

251 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h new file +184 -0

184 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c new file +96 -0

96 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h new file +16 -0
new file mode 100644
index 0000000000000..22f882d3aa3a2
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_COMPAT_8800D80_H_
+#define _AICWF_COMPAT_8800D80_H_
+#include "reg_access.h"
+#include "rwnx_main.h"
+#include "rwnx_msg_tx.h"
+#include <linux/types.h>
+
+int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw,
+				struct mm_set_rf_calib_cfm *cfm);
+int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
+#endif
+
+#endif
drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c new file +505 -0

505 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h new file +22 -0
new file mode 100644
index 0000000000000..12e8d60150452
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_COMPAT_8800DC_H_
+#define _AICWF_COMPAT_8800DC_H_
+
+#include "aic_bsp_export.h"
+#include <linux/types.h>
+
+#ifdef CONFIG_DPD
+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw,
+				       struct rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw,
+				      struct rf_misc_ram_lite_t *dpd_res);
+#endif
+#endif
+int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
+int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw,
+			       struct mm_set_rf_calib_cfm *cfm);
+int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw);
+int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);
+
+#endif /* _AICWF_COMPAT_8800DC_H_ */
drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c new file +699 -0

187 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h new file +84 -0

84 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c new file +102 -0

102 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h new file +34 -0
new file mode 100644
index 0000000000000..666e2f0027102

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +2831 -0

2,831 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h new file +275 -0

275 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c new file +565 -0

565 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h new file +104 -0

104 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c new file +752 -0

752 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/regdb.c new file +2772 -0

2,772 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c new file +93 -0

93 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h new file +100 -0

100 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c new file +265 -0

265 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h new file +33 -0
new file mode 100644
index 0000000000000..d76179316fe2a

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c new file +5439 -0

5,439 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h new file +35 -0
new file mode 100644
index 0000000000000..e03321c99c42c

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c new file +33 -0
new file mode 100644
index 0000000000000..69d37ecb63be2

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h new file +35 -0
new file mode 100644
index 0000000000000..44de24ea705a1

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c new file +985 -0

985 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h new file +74 -0

74 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c new file +653 -0

653 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h new file +159 -0

159 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c new file +1970 -0

1,970 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h new file +285 -0

285 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c new file +2320 -0

2,320 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c new file +773 -0

773 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h new file +57 -0

57 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h new file +68 -0

68 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c new file +5 -0
new file mode 100644
index 0000000000000..732fca321d965

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c new file +1635 -0

1,635 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h new file +176 -0

176 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c new file +1362 -0

1,362 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c new file +132 -0

132 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h new file +39 -0
new file mode 100644
index 0000000000000..17a1cde69c27d

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

#12 lore raw

Re: [RFC PATCH wireless-next v3 3/4] wifi: aic: add FullMAC WLAN driver

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c line 553

Quoted 8 lines · Yanli Yang
drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +8 -0
+
+#ifndef CONFIG_PLATFORM_EXTERNAL
+#ifdef CONFIG_GPIO_WAKEUP
+static int wakeup_enable;
+static u32 hostwake_irq_num;
+#endif
+#endif
+

What?

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c line 562

Quoted 9 lines
drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +9 -0
+/* debug trace */
+// static struct wakeup_source *ws_rx_sdio;
+// static struct wakeup_source *ws_sdio_pwrctrl;
+// static struct wakeup_source *ws_tx_sdio;
+#ifdef CONFIG_GPIO_WAKEUP
+// static struct wakeup_source *ws;
+#endif
+
+#ifdef CONFIG_PLATFORM_EXTERNAL

NAK, there is no such CONFIG symbol.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c line 565

Quoted 3 lines
drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +3 -0
+
+#define ENTER() (pr_info("AICWF enter %s\n", __func__))
+#define LEAVE() (pr_info("AICWF exit %s\n", __func__))

No. You cannot re-implement tracing. Drop this from EVERYWHERE.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c line 575

Quoted 10 lines
drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +10 -0
+
+int regist_wakeup_irq(struct aic_sdio_dev *sdiodev)
+{
+	int ret = -EINVAL;
+	struct device *dev = sdiodev->dev;
+	struct device_node *node;
+
+	ENTER();
+
+	node = of_find_compatible_node(NULL, NULL, "aic,wifi-wake-host");

Undocumented ABI. Would not be accepted anyway.

Review

Quoted 3 lines
(quoted diff) +2 -0
+	if (!node)
+		goto err_exit;

This driver does not look like upstream code at all. You should clean it up before you post next v4.

Best regards,
Krzysztof

author
#13 lore raw

RFC PATCH v3 4/4 wifi: aic: integrate AIC8800 driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Connect the completed AIC vendor directory to the wireless build and add its MAINTAINERS entry. Keeping integration last prevents an earlier partial source state from being selected by Kconfig.

---
 MAINTAINERS                   | 10 ++++++++++
 drivers/net/wireless/Kconfig  |  1 +
 drivers/net/wireless/Makefile |  1 +
 3 files changed, 12 insertions(+)
MAINTAINERS +10 -0
index 52f1a55eca99b..a64bd3b8e0aa1 100644
@@ -736,6 +736,16 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/scsi/aic7xxx/
 
+AIC8800 WIRELESS DRIVER
+M:	Zhirun Liu <[email protected]>
+M:	Dijia Xu <[email protected]>
+M:	Chunqiu Liu <[email protected]>
+M:	Liheng Wei <[email protected]>
+M:	Yanli Yang <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/net/wireless/aic/
+
 AIMSLAB FM RADIO RECEIVER DRIVER
 M:	Hans Verkuil <[email protected]>
 L:	[email protected]
drivers/net/wireless/Kconfig +1 -0
index c6599594dc995..65ab62d073693 100644
@@ -19,6 +19,7 @@ menuconfig WLAN
 if WLAN
 
 source "drivers/net/wireless/admtek/Kconfig"
+source "drivers/net/wireless/aic/Kconfig"
 source "drivers/net/wireless/ath/Kconfig"
 source "drivers/net/wireless/atmel/Kconfig"
 source "drivers/net/wireless/broadcom/Kconfig"
drivers/net/wireless/Makefile +1 -0
index e1c4141c60044..bb0c29cb3e82f 100644
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_WLAN_VENDOR_ADMTEK) += admtek/
+obj-$(CONFIG_WLAN_VENDOR_AIC) += aic/
 obj-$(CONFIG_WLAN_VENDOR_ATH) += ath/
 obj-$(CONFIG_WLAN_VENDOR_ATMEL) += atmel/
 obj-$(CONFIG_WLAN_VENDOR_BROADCOM) += broadcom/
Signature · 1 line
2.34.1
author
#14 lore raw

v4 cover wifi: aic: add AIC8800D80 SDIO FullMAC driver

In reply to Yanli Yang

Johannes,

This v4 fixes the build failure in v3 against current wireless-next.

Commit 914781c72813 ("wifi: cfg80211: convert cookie output to input parameter") changed the cfg80211 remain_on_channel and mgmt_tx callbacks from u64 pointer output parameters to preassigned u64 input parameters. The driver now accepts each cookie by value, carries it through the remain-on-channel and management-TX state, and reports the same cookie in the corresponding cfg80211 completion notification. The obsolete local remain-on-channel cookie counter has been removed.

This revision also removes two unused global definitions found during the rebuild. The feature scope and the status of the outstanding RFC review items are otherwise unchanged from v3.

Validation performed for v4 against wireless-next at ca800a9302764:

- x86-64 GCC build with AIC8800_BSP_SUPPORT=m,

    AIC8800_WLAN_SUPPORT=m and W=1;

- sequential application of all four patches; and
- comparison of the applied series with the current AIC source tree.

No runtime retest was performed for v4. The AIC8800D80 U02 SDIO hardware validation reported with v3 is unchanged.

Changes since v3:

- rebase on current wireless-next;
- adapt remain_on_channel and mgmt_tx to cfg80211's cookie-by-value API;
- preserve cfg80211-assigned cookies through asynchronous completion;
- remove the obsolete local ROC cookie counter; and
- remove two unused global definitions.

v3: https://lore.kernel.org/r/[email protected]
v2: https://lore.kernel.org/r/[email protected]
v1: https://lore.kernel.org/r/[email protected]

Zhirun Liu (4):
wifi: aic: add SDIO BSP and build configuration
wifi: aic: add FullMAC firmware and platform interface
wifi: aic: add FullMAC WLAN driver
wifi: aic: integrate AIC8800 driver

 MAINTAINERS                                   |   10 +
 drivers/net/wireless/Kconfig                  |    1 +
 drivers/net/wireless/Makefile                 |    1 +
 drivers/net/wireless/aic/Kconfig              |   40 +
 drivers/net/wireless/aic/Makefile             |    7 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |    3 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   16 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  290 +
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 ++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   34 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1670 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  598 ++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  310 +
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |   98 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 +
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   64 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   69 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2027 ++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 +
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  464 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |   37 +
 .../net/wireless/aic/aic8800_fdrv/Makefile    |   46 +
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  |  763 +++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  103 +
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  251 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  184 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  699 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |   84 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2831 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  275 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  752 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  770 +++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  437 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3101 ++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   22 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   80 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  704 +++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5435 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        |  985 +++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1614 +++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3619 +++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  266 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2868 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  183 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1970 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2320 +++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  772 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1634 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  178 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   35 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 109 files changed, 53876 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h

base-commit: ca800a9302764c445de0da0e84d2252400a770ee

Signature · 1 line
2.34.1
author
#15 lore raw

RFC PATCH v4 1/4 wifi: aic: add SDIO BSP and build configuration

From: Zhirun Liu <[email protected]>

Add the build configuration and SDIO board-support layer for the initial AIC8800D80 U02 upstream target. The BSP handles platform power sequencing, SDIO transport setup, firmware loading and chip initialization.

Limit the selectable configuration to the D80 U02 SDIO station baseline and use the kernel crypto library for firmware MD5 diagnostics.

---
 drivers/net/wireless/aic/Kconfig              |   40 +
 drivers/net/wireless/aic/Makefile             |    7 +
 drivers/net/wireless/aic/aic8800_bsp/Kconfig  |    3 +
 drivers/net/wireless/aic/aic8800_bsp/Makefile |   16 +
 .../aic/aic8800_bsp/aic8800d80_compat.c       |  290 +++
 .../aic/aic8800_bsp/aic8800d80_compat.h       |   11 +
 .../aic/aic8800_bsp/aic8800dc_compat.c        | 1342 +++++++++++
 .../aic/aic8800_bsp/aic8800dc_compat.h        |   34 +
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.c | 1670 ++++++++++++++
 .../wireless/aic/aic8800_bsp/aic_bsp_driver.h |  598 +++++
 .../wireless/aic/aic8800_bsp/aic_bsp_export.h |   70 +
 .../wireless/aic/aic8800_bsp/aic_bsp_main.c   |  310 +++
 .../aic/aic8800_bsp/aic_chip_8800d80.c        |   98 +
 .../aic/aic8800_bsp/aic_chip_8800dc.c         |  133 ++
 .../wireless/aic/aic8800_bsp/aic_chip_8801.c  |  117 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.c   |   64 +
 .../wireless/aic/aic8800_bsp/aic_chip_ops.h   |   69 +
 .../net/wireless/aic/aic8800_bsp/aicsdio.c    | 2027 +++++++++++++++++
 .../net/wireless/aic/aic8800_bsp/aicsdio.h    |  176 ++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.c |  464 ++++
 .../wireless/aic/aic8800_bsp/aicsdio_txrxif.h |  180 ++
 .../aic/aic8800_bsp/aicwf_txq_prealloc.c      |   72 +
 .../aic/aic8800_bsp/aicwf_txq_prealloc.h      |    8 +
 drivers/net/wireless/aic/aic8800_fdrv/Kconfig |   37 +
 .../net/wireless/aic/aic8800_fdrv/Makefile    |   46 +
 25 files changed, 7882 insertions(+)
 create mode 100644 drivers/net/wireless/aic/Kconfig
 create mode 100644 drivers/net/wireless/aic/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/Makefile
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Kconfig
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/Makefile
drivers/net/wireless/aic/Kconfig new file +40 -0
new file mode 100644
index 0000000000000..5218351da5e38
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config WLAN_VENDOR_AIC
+	bool "AIC devices"
+	default y
+	help
+	  Say Y to expose the AIC8800D80 U02 SDIO Wi-Fi driver.
+	  The first upstreaming target is a narrow D80 U02 SDIO station
+	  configuration; legacy transport, Bluetooth, Android, test and
+	  manufacturing build switches are intentionally not exposed.
+
+if WLAN_VENDOR_AIC
+
+menuconfig AIC8800_BSP_SUPPORT
+	tristate "AIC8800D80 U02 SDIO bus support"
+	depends on MMC
+	select CRYPTO_LIB_MD5
+	help
+	  Enable the AIC8800D80 U02 SDIO bus support package. It provides
+	  the SDIO transport, chip operations and firmware download path used
+	  by the AIC8800 FullMAC WLAN driver.
+
+	  Firmware files are loaded from the aic8800/ subdirectory of the
+	  kernel firmware search path, normally /lib/firmware/aic8800/.
+
+	  If unsure, say N.
+
+if AIC8800_BSP_SUPPORT
+
+config AIC8800_SDIO_SUPPORT
+	def_bool y
+
+config AIC8800_SDIO_PWRCTRL
+	def_bool y
+
+source "drivers/net/wireless/aic/aic8800_bsp/Kconfig"
+source "drivers/net/wireless/aic/aic8800_fdrv/Kconfig"
+
+endif # AIC8800_BSP_SUPPORT
+endif # WLAN_VENDOR_AIC
drivers/net/wireless/aic/Makefile new file +7 -0
new file mode 100644
index 0000000000000..1ce5651aa4a75
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AIC8800_BSP_SUPPORT) += aic8800_bsp/
+obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
+
+ccflags-y += -DAICWF_SDIO_SUPPORT
+ccflags-y += -DCONFIG_SDIO_PWRCTRL
drivers/net/wireless/aic/aic8800_bsp/Kconfig new file +3 -0
new file mode 100644
index 0000000000000..e82acc8875bc2
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# The D80 U02 SDIO station baseline has no selectable BSP suboptions.
drivers/net/wireless/aic/aic8800_bsp/Makefile new file +16 -0
new file mode 100644
index 0000000000000..ad9763e704b89
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AIC8800_BSP_SUPPORT) += aic8800_bsp.o
+
+aic8800_bsp-y := \
+	aic_chip_8800d80.o \
+	aic_chip_ops.o \
+	aic8800d80_compat.o \
+	aic_bsp_main.o \
+	aic_bsp_driver.o \
+	aicsdio.o \
+	aicsdio_txrxif.o
+
+ccflags-y += -I$(src)/../aic8800_fdrv
+ccflags-y += -DAICWF_SDIO_SUPPORT
+ccflags-y += -DCONFIG_SDIO_PWRCTRL
drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.c new file +290 -0

290 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800d80_compat.h new file +11 -0
new file mode 100644
index 0000000000000..a22e440b09a66
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800D80_COMPAT_H_
+#define _AIC8800D80_COMPAT_H_
+
+#include "aicsdio.h"
+
+int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev);
+int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.c new file +1342 -0

1,342 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic8800dc_compat.h new file +34 -0
new file mode 100644
index 0000000000000..0edee0f8d6cc3
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AIC8800DC_COMPAT_H_
+#define _AIC8800DC_COMPAT_H_
+
+#include <linux/types.h>
+
+#include "aicsdio.h"
+typedef u32 (*array2_tbl_t)[2];
+typedef u32 (*array3_tbl_t)[3];
+
+extern u8 chip_sub_id;
+extern u8 chip_mcu_id;
+#define FW_PATH_MAX_LEN 200
+
+void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
+int rwnx_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
+int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
+int start_from_bootrom_8800DC(struct aic_sdio_dev *sdiodev);
+
+#ifdef CONFIG_DPD
+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev,
+			   struct rf_misc_ram_lite_t *dpd_res);
+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev,
+				  struct rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev,
+				 struct rf_misc_ram_lite_t *dpd_res);
+#endif /* !CONFIG_FORCE_DPD_CALIB */
+#endif
+
+int set_bbpll_config(struct aic_sdio_dev *rwnx_hw);
+
+#endif
drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.c new file +1670 -0

1,257 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_driver.h new file +598 -0

598 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_export.h new file +70 -0

70 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_bsp_main.c new file +310 -0

310 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800d80.c new file +98 -0

98 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8800dc.c new file +133 -0

133 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_8801.c new file +117 -0

117 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.c new file +64 -0

64 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aic_chip_ops.h new file +69 -0

69 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.c new file +2027 -0

2,027 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio.h new file +176 -0

176 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.c new file +464 -0

464 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicsdio_txrxif.h new file +180 -0

180 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.c new file +72 -0

72 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_bsp/aicwf_txq_prealloc.h new file +8 -0
new file mode 100644
index 0000000000000..680d37ffca931

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/Kconfig new file +37 -0
new file mode 100644
index 0000000000000..59cf740aa6202

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/Makefile new file +46 -0

46 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

author
#16 lore raw

RFC PATCH v4 2/4 wifi: aic: add FullMAC firmware and platform interface

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the LMAC message definitions, IPC host support, firmware command/event handling and platform bring-up required by the AIC8800D80 U02 FullMAC firmware.

The interface is scoped to the current in-tree kernel APIs and the SDIO station baseline selected by the first patch.

---
 .../aic/aic8800_fdrv/aic_bsp_export.h         |   62 +
 .../net/wireless/aic/aic8800_fdrv/aic_bus.h   |  191 +
 .../wireless/aic/aic8800_fdrv/aicwf_debug.h   |   37 +
 .../net/wireless/aic/aic8800_fdrv/hal_desc.h  |  359 ++
 .../wireless/aic/aic8800_fdrv/ipc_compat.h    |   25 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.c  |   42 +
 .../net/wireless/aic/aic8800_fdrv/ipc_host.h  |  169 +
 .../wireless/aic/aic8800_fdrv/ipc_shared.h    |  770 ++++
 .../net/wireless/aic/aic8800_fdrv/lmac_mac.h  |  437 ++
 .../net/wireless/aic/aic8800_fdrv/lmac_msg.h  | 3101 ++++++++++++++
 .../wireless/aic/aic8800_fdrv/lmac_types.h    |   22 +
 .../wireless/aic/aic8800_fdrv/reg_access.h    |  146 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.c |  471 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_cmds.h |   99 +
 .../wireless/aic/aic8800_fdrv/rwnx_compat.h   |   80 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_defs.h |  704 ++++
 .../wireless/aic/aic8800_fdrv/rwnx_events.h   |  938 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.c |   49 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_irqs.h |   12 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.c   | 1614 ++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_rx.h   |    8 +
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.c   | 3619 +++++++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_msg_tx.h   |  266 ++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.c | 2868 +++++++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_platform.h |  183 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_prof.h |  142 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.c |  269 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_strs.h |   31 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.c    |   35 +
 .../wireless/aic/aic8800_fdrv/rwnx_utils.h    |  131 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.c   |  181 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_v7.h   |   21 +
 32 files changed, 17082 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/reg_access.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h
drivers/net/wireless/aic/aic8800_fdrv/aic_bsp_export.h new file +62 -0
new file mode 100644
index 0000000000000..11b414df42ce3
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __AIC_BSP_EXPORT_H
+#define __AIC_BSP_EXPORT_H
+
+#include <linux/types.h>
+
+enum aicbsp_subsys {
+	AIC_BLUETOOTH,
+	AIC_WIFI,
+};
+
+enum aicbsp_pwr_state {
+	AIC_PWR_OFF,
+	AIC_PWR_ON,
+};
+
+struct aicbsp_feature_t {
+	int hwinfo;
+	u32 sdio_clock;
+	u8 sdio_phase;
+	int fwlog_en;
+	u8 irqf;
+	u8 cpmode;
+	int adapt;
+};
+
+enum skb_buff_id {
+	AIC_RESV_MEM_TXDATA,
+};
+
+#ifdef CONFIG_DPD
+struct rf_misc_ram_t {
+	u32 bit_mask[3];
+	u32 reserved;
+	u32 dpd_high[96];
+	u32 dpd_11b[96];
+	u32 dpd_low[96];
+	u32 idac_11b[48];
+	u32 idac_high[48];
+	u32 idac_low[48];
+	u32 loft_res[18];
+	u32 rx_iqim_res[16];
+};
+
+struct rf_misc_ram_lite_t {
+	u32 bit_mask[4];
+	u32 dpd_high[96];
+	u32 loft_res[18];
+};
+
+#define MEMBER_SIZE(type, member) sizeof_field(type, member)
+#define DPD_RESULT_SIZE_8800DC    sizeof(struct rf_misc_ram_lite_t)
+
+extern struct rf_misc_ram_lite_t dpd_res;
+#endif
+
+int aicbsp_set_subsys(int, int);
+int aicbsp_get_feature(struct aicbsp_feature_t *feature);
+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);
+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id);
+
+#endif
drivers/net/wireless/aic/aic8800_fdrv/aic_bus.h new file +191 -0

191 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_debug.h new file +37 -0
new file mode 100644
index 0000000000000..4a49c16f15a31
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_DEBUG_H_
+#define _AICWF_DEBUG_H_
+
+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
+
+/* message levels */
+#define LOGERROR    0x0001
+#define LOGINFO     0x0002
+#define LOGTRACE    0x0004
+#define LOGDEBUG    0x0008
+#define LOGDATA     0x0010
+#define LOGIRQ      0x0020
+#define LOGSDPWRC   0x0040
+#define LOGWAKELOCK 0x0080
+#define LOGRXPOLL   0x0100
+
+extern int aicwf_dbg_level;
+void rwnx_data_dump(char *tag, void *data, unsigned long len);
+
+#define AICWF_LOG "AICWFDBG("
+
+#define AICWFDBG(level, args, arg...)                                          \
+	do {                                                                       \
+		if (aicwf_dbg_level & (level)) {                                         \
+			pr_debug(AICWF_LOG #level ")\t" args, ##arg);                        \
+		}                                                                      \
+	} while (0)
+
+#define RWNX_DBG(fmt, ...)                                                     \
+	do {                                                                       \
+		if (aicwf_dbg_level & LOGTRACE) {                                      \
+			pr_debug(AICWF_LOG "LOGTRACE)\t" fmt, ##__VA_ARGS__);                \
+		}                                                                      \
+	} while (0)
+
+#endif /* _AICWF_DEBUG_H_ */
drivers/net/wireless/aic/aic8800_fdrv/hal_desc.h new file +359 -0

359 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_compat.h new file +25 -0
new file mode 100644
index 0000000000000..cf1fe0d737b84
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ ****************************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ ****************************************************************************************
+ */
+
+#ifndef _IPC_H_
+#define _IPC_H_
+
+#define __INLINE inline
+
+#define __ALIGN4 __aligned(4)
+
+#define ASSERT_ERR(condition)                                                  \
+	do {                                                                       \
+		if (unlikely(!(condition))) {                                          \
+			pr_err("%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__,    \
+				   __LINE__);                                                  \
+		}                                                                      \
+	} while (0)
+
+#endif /* _IPC_H_ */
drivers/net/wireless/aic/aic8800_fdrv/ipc_host.c new file +42 -0

42 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_host.h new file +169 -0

169 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/ipc_shared.h new file +770 -0

770 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_mac.h new file +437 -0

437 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_msg.h new file +3101 -0

908 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/lmac_types.h new file +22 -0
new file mode 100644
index 0000000000000..76f251607a7b9

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/reg_access.h new file +146 -0

146 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.c new file +471 -0

471 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cmds.h new file +99 -0

99 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_compat.h new file +80 -0

80 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_defs.h new file +704 -0

704 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_events.h new file +938 -0

938 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.c new file +49 -0

49 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_irqs.h new file +12 -0
new file mode 100644
index 0000000000000..ff6c766c727c3

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.c new file +1614 -0

1,614 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_rx.h new file +8 -0
new file mode 100644
index 0000000000000..211f2e616cbf4

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.c new file +3619 -0

3,619 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_msg_tx.h new file +266 -0

266 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.c new file +2868 -0

2,868 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_platform.h new file +183 -0

183 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_prof.h new file +142 -0

142 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.c new file +269 -0

269 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_strs.h new file +31 -0
new file mode 100644
index 0000000000000..1b4df40f2a912

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.c new file +35 -0
new file mode 100644
index 0000000000000..73e8ab7c8af5c

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_utils.h new file +131 -0

131 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.c new file +181 -0

181 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_v7.h new file +21 -0
new file mode 100644
index 0000000000000..709553f96c2a1

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

author
#17 lore raw

RFC PATCH v4 3/4 wifi: aic: add FullMAC WLAN driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Add the cfg80211 FullMAC implementation, TX/RX data paths, SDIO host glue and AIC8800D80 U02 chip operations. Normal Wi-Fi control is exposed through cfg80211/nl80211 and system suspend is handled through the SDIO dev_pm_ops.

The Android private ioctl, Wireless Extensions, GKI shim, vendor-HAL stubs, Bluetooth character device and bridge extension present in earlier RFCs are not included.

---
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.c  |  763 +++
 .../wireless/aic/aic8800_fdrv/aic_priv_cmd.h  |  103 +
 .../aic/aic8800_fdrv/aicwf_chip_8800d80.c     |  291 +
 .../aic/aic8800_fdrv/aicwf_chip_8800dc.c      |  300 +
 .../aic/aic8800_fdrv/aicwf_chip_8801.c        |  279 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.c         |  251 +
 .../aic/aic8800_fdrv/aicwf_chip_ops.h         |  184 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.c   |   96 +
 .../aic/aic8800_fdrv/aicwf_compat_8800d80.h   |   16 +
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.c    |  505 ++
 .../aic/aic8800_fdrv/aicwf_compat_8800dc.h    |   22 +
 .../wireless/aic/aic8800_fdrv/aicwf_genl.c    |  699 +++
 .../wireless/aic/aic8800_fdrv/aicwf_genl.h    |   84 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.c      |  102 +
 .../aic/aic8800_fdrv/aicwf_rx_prealloc.h      |   34 +
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.c    | 2831 +++++++++
 .../wireless/aic/aic8800_fdrv/aicwf_sdio.h    |  275 +
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c |  565 ++
 .../wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h |  104 +
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.c  |  752 +++
 .../wireless/aic/aic8800_fdrv/aicwf_txrxif.h  |  217 +
 drivers/net/wireless/aic/aic8800_fdrv/regdb.c | 2772 +++++++++
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.c    |   93 +
 .../wireless/aic/aic8800_fdrv/rwnx_bfmer.h    |  100 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.c  |  265 +
 .../wireless/aic/aic8800_fdrv/rwnx_cfgfile.h  |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.c | 5435 +++++++++++++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_main.h |   35 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.c |   33 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_mesh.h |   35 +
 .../aic/aic8800_fdrv/rwnx_mod_params.c        |  985 +++
 .../aic/aic8800_fdrv/rwnx_mod_params.h        |   74 +
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.c |  653 ++
 .../wireless/aic/aic8800_fdrv/rwnx_mu_group.h |  159 +
 .../wireless/aic/aic8800_fdrv/rwnx_radar.c    | 1970 ++++++
 .../wireless/aic/aic8800_fdrv/rwnx_radar.h    |  285 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.c   | 2320 +++++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_rx.h   |  358 ++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.c |  772 +++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tdls.h |   57 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.c |  217 +
 .../wireless/aic/aic8800_fdrv/rwnx_testmode.h |   68 +
 .../wireless/aic/aic8800_fdrv/rwnx_trace.c    |    5 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.c   | 1634 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_tx.h   |  178 +
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.c  | 1362 +++++
 .../net/wireless/aic/aic8800_fdrv/rwnx_txq.h  |  358 ++
 .../net/wireless/aic/aic8800_fdrv/sdio_host.c |  132 +
 .../net/wireless/aic/aic8800_fdrv/sdio_host.h |   39 +
 49 files changed, 28900 insertions(+)
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/regdb.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c
 create mode 100644 drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h
drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.c new file +763 -0
new file mode 100644
index 0000000000000..36b4267f73b16
@@ -0,0 +1,763 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ ******************************************************************************
+ *
+ * Copyright (C) 2020 AIC semiconductor.
+ *
+ * @brief private command definition
+ *
+ ******************************************************************************
+ */
+
+#include "aic_priv_cmd.h"
+#include "aicwf_sdio.h"
+#include "rwnx_defs.h"
+#include "rwnx_main.h"
+#include "rwnx_mod_params.h"
+#include "rwnx_msg_tx.h"
+#include "rwnx_platform.h"
+#include <linux/ctype.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+#include "aicwf_compat_8800d80.h"
+#endif
+
+static void print_help(const char *cmd);
+
+struct cmd_ef_usrdata {
+	u8 func;
+	u8 cnt;
+	u8 reserved[2];
+	u32 usrdata[3];
+};
+
+#define CMD_MAXARGS 224
+
+static int parse_line(char *line, char *argv[])
+{
+	int nargs = 0;
+
+	while (nargs < CMD_MAXARGS) {
+		/* skip any white space */
+		while ((*line == ' ') || (*line == '\t'))
+			++line;
+
+		if (*line == '\0') { /* end of line, no more args    */
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		/* Argument include space should be bracketed by quotation mark */
+		if (*line == '\"') {
+			/* Skip quotation mark */
+			line++;
+
+			/* Begin of argument string */
+			argv[nargs++] = line;
+
+			/* Until end of argument */
+			while (*line && (*line != '\"'))
+				++line;
+		} else {
+			argv[nargs++] = line; /* begin of argument string    */
+
+			/* find end of string */
+			while (*line && (*line != ' ') && (*line != '\t'))
+				++line;
+		}
+
+		if (*line == '\0') { /* end of line, no more args    */
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		*line++ = '\0'; /* terminate current arg     */
+	}
+
+	pr_info("** Too many args (max. %d) **\n", CMD_MAXARGS);
+
+	return nargs;
+}
+
+unsigned int command_strtoul(const char *cp, char **endp, unsigned int base)
+{
+	unsigned int result = 0, value, is_neg = 0;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+	if (*cp == '-') {
+		is_neg = 1;
+		cp++;
+	}
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp - '0'
+		: (islower(*cp) ? toupper(*cp) : *cp) - 'A' +
+		10) < base) {
+		result = result * base + value;
+		cp++;
+	}
+	if (is_neg)
+		result = (unsigned int)((int)result * (-1));
+
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+/*
+ * aic_priv_cmd handers.
+ */
+
+static int aic_priv_cmd_set_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	u8 mac_addr[6];
+
+	if (argc < 7)
+		return -EINVAL;
+
+	mac_addr[5] = command_strtoul(argv[1], NULL, 16);
+	mac_addr[4] = command_strtoul(argv[2], NULL, 16);
+	mac_addr[3] = command_strtoul(argv[3], NULL, 16);
+	mac_addr[2] = command_strtoul(argv[4], NULL, 16);
+	mac_addr[1] = command_strtoul(argv[5], NULL, 16);
+	mac_addr[0] = command_strtoul(argv[6], NULL, 16);
+	AICWFDBG(LOGINFO, "set macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5],
+		 mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]);
+	rwnx_send_rftest_req(rwnx_hw, SET_MAC_ADDR, sizeof(mac_addr),
+			     (u8 *)&mac_addr, NULL);
+	return 0;
+}
+
+static int aic_priv_cmd_get_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	aic_chip_priv_cmd_get_mac_addr(rwnx_hw, argc, argv, command);
+	return 8;
+}
+
+static int aic_priv_cmd_set_bt_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	u8 mac_addr[6];
+
+	if (argc < 7)
+		return -EINVAL;
+
+	mac_addr[5] = command_strtoul(argv[1], NULL, 16);
+	mac_addr[4] = command_strtoul(argv[2], NULL, 16);
+	mac_addr[3] = command_strtoul(argv[3], NULL, 16);
+	mac_addr[2] = command_strtoul(argv[4], NULL, 16);
+	mac_addr[1] = command_strtoul(argv[5], NULL, 16);
+	mac_addr[0] = command_strtoul(argv[6], NULL, 16);
+	AICWFDBG(LOGINFO, "set bt macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5],
+		 mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]);
+	rwnx_send_rftest_req(rwnx_hw, SET_BT_MAC_ADDR, sizeof(mac_addr),
+			     (u8 *)&mac_addr, NULL);
+	return 0;
+}
+
+static int aic_priv_cmd_get_bt_mac_addr(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	aic_chip_priv_cmd_get_bt_mac_addr(rwnx_hw, argc, argv, command);
+	return 8;
+}
+
+#ifdef CONFIG_AIC8800_AUTO_CUSTREG
+static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	int ret = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]);
+	if (strncmp(argv[1], "AUTO", 4) == 0) {
+		rwnx_hw->ccode.auto_set = true;
+		rwnx_hw->ccode.ccode_set = false;
+		rwnx_hw->ccode.ccode_cnt = 0;
+		rwnx_hw->ccode.ccode_rssi = -100;
+	} else if (strncmp(argv[1], "MANUAL", 6) == 0) {
+		rwnx_hw->ccode.auto_set = false;
+		rwnx_hw->ccode.ccode_set = true;
+	} else {
+		rwnx_hw->ccode.ccode_set = true;
+		ret = rwnx_regulatory_set_wiphy_regd(rwnx_hw->wiphy,
+						     get_regdomain_from_rwnx_db(rwnx_hw->wiphy,
+										argv[1]));
+		memcpy(rwnx_hw->country_abbr, argv[1], 2);
+		rwnx_hw->ccode.ccode_cnt = 0;
+#ifdef CONFIG_AIC8800_REGION_PW
+		rwnx_send_txpwr_lvl_v3_req(rwnx_hw, get_ccode_region(rwnx_hw->country_abbr));
+#endif
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+		aic_chip_powerlimit_load(rwnx_hw);
+		if (!rwnx_hw->testmode)
+			rwnx_send_me_chan_config_req(rwnx_hw);
+#endif
+	}
+	return ret;
+}
+
+static int aic_priv_cmd_country_get(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	const struct ieee80211_regdomain *regd;
+	u8 buf[3];
+	int bytes_written = 0;
+
+	rcu_read_lock();
+	regd = rcu_dereference(rwnx_hw->wiphy->regd);
+	if (!regd) {
+		rcu_read_unlock();
+		return -ENODATA;
+	}
+	buf[0] = regd->alpha2[0];
+	buf[1] = regd->alpha2[1];
+	rcu_read_unlock();
+	buf[2] = rwnx_hw->ccode.auto_set;
+	memcpy(command, &buf[0], 3);
+	bytes_written = 3;
+	AICWFDBG(LOGINFO, "cmd country_get: %c%c\n", command[0], command[1]);
+
+	return bytes_written;
+}
+#endif
+
+#ifdef CONFIG_AIC8800_TEMP_CONTROL
+static int aic_priv_cmd_temp_ctrl_sw(struct rwnx_hw *rwnx_hw, int argc,
+				     char *argv[], char *command)
+{
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	if (command_strtoul(argv[1], NULL, 10) == 0) {
+		AICWFDBG(LOGINFO, "tp to off\n");
+		rwnx_hw->sdiodev->tp_ctrl.on_off = false;
+		rwnx_hw->sdiodev->tp_ctrl.get_level = 0;
+		spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+		rwnx_hw->sdiodev->tp_ctrl.tm_start = 0;
+		if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer))
+			//del_timer_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+			timer_delete_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+		spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+	} else if (command_strtoul(argv[1], NULL, 10) == 1) {
+		AICWFDBG(LOGINFO, "tp to on\n");
+		rwnx_hw->sdiodev->tp_ctrl.on_off = true;
+		spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+		rwnx_hw->sdiodev->tp_ctrl.tm_start = 1;
+		mod_timer(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer,
+			  jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL));
+		spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+	} else {
+		AICWFDBG(LOGINFO, "tp err param\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int aic_priv_cmd_temp_sget(struct rwnx_hw *rwnx_hw, int argc,
+				  char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+	s8 tp_res[4];
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 0) {                            // get
+		if (rwnx_hw->sdiodev->tp_ctrl.on_off) { // on
+			tp_res[0] = 1;
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level == 0)
+				tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.get_level;
+			else
+				tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.set_level;
+			AICWFDBG(LOGINFO, "tp_get on-off: %d, ctrl-level: %d\n", tp_res[0],
+				 tp_res[1]);
+			memcpy(command, &tp_res[0], 2);
+			bytes_written = 2;
+		} else { // off
+			tp_res[0] = 0;
+			AICWFDBG(LOGINFO, "tp_get on-off: %d\n", tp_res[0]);
+			memcpy(command, &tp_res[0], 1);
+			bytes_written = 1;
+		}
+	} else if (func == 1) { // set
+		if (!rwnx_hw->sdiodev->tp_ctrl.on_off) {
+			AICWFDBG(LOGINFO, "tp_set sw is off, return\n");
+			tp_res[0] = 0;
+			memcpy(command, &tp_res[0], 1);
+			bytes_written = 1;
+		} else {
+			if (argc < 3) {
+				AICWFDBG(LOGINFO, "%s param err\n", __func__);
+				return -1;
+			}
+			rwnx_hw->sdiodev->tp_ctrl.set_level =
+				command_strtoul(argv[2], NULL, 10);
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level < 0 ||
+			    rwnx_hw->sdiodev->tp_ctrl.set_level > 2) {
+				AICWFDBG(LOGINFO, "set_level out of range\n");
+				rwnx_hw->sdiodev->tp_ctrl.set_level = 0;
+			}
+			rwnx_hw->sdiodev->tp_ctrl.get_level = 0;
+			tp_res[0] = 1;
+			tp_res[1] = rwnx_hw->sdiodev->tp_ctrl.set_level;
+			AICWFDBG(LOGINFO, "tp_set ctrl-level: %d\n",
+				 rwnx_hw->sdiodev->tp_ctrl.set_level);
+			memcpy(command, &tp_res[0], 2);
+			bytes_written = 2;
+
+			if (rwnx_hw->sdiodev->tp_ctrl.set_level != 0) {
+				spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+				rwnx_hw->sdiodev->tp_ctrl.tm_start = 0;
+				if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer))
+					//del_timer_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+					timer_delete_sync(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer);
+				spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+			} else if (rwnx_hw->sdiodev->tp_ctrl.set_level == 0) {
+				spin_lock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+				rwnx_hw->sdiodev->tp_ctrl.tm_start = 1;
+				mod_timer(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer,
+					  jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL));
+				spin_unlock_bh(&rwnx_hw->sdiodev->tp_ctrl.tm_lock);
+			}
+		}
+	} else {
+		AICWFDBG(LOGINFO, "tp command err\n");
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_set_tmr_intval(struct rwnx_hw *rwnx_hw, int argc,
+				       char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 3) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 1) {
+		rwnx_hw->sdiodev->tp_ctrl.interval_t1 =
+			command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGDEBUG, "set tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t1, 4);
+		bytes_written = 4;
+	} else if (func == 2) {
+		rwnx_hw->sdiodev->tp_ctrl.interval_t2 =
+			command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGDEBUG, "set tmr_intval_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t2, 4);
+		bytes_written = 4;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_get_tmr_intval(struct rwnx_hw *rwnx_hw, int argc,
+				       char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGINFO, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+	if (func == 1) {
+		AICWFDBG(LOGDEBUG, "get tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t1, 4);
+		bytes_written = 4;
+	} else if (func == 2) {
+		AICWFDBG(LOGDEBUG, "get tmr_intval_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.interval_t2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.interval_t2, 4);
+		bytes_written = 4;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_temp_get(struct rwnx_hw *rwnx_hw, int argc,
+				 char *argv[], char *command)
+{
+	int bytes_written = 0;
+	struct mm_set_vendor_swconfig_cfm tp_cfm;
+
+	if (timer_pending(&rwnx_hw->sdiodev->tp_ctrl.tp_ctrl_timer)) {
+		if (jiffies_to_msecs(jiffies - rwnx_hw->started_jiffies) < 5000) {
+			AICWFDBG(LOGINFO, "tp_get temp_1: %d\n", rwnx_hw->temp);
+			memcpy(command, &rwnx_hw->temp, 1);
+		} else {
+			if (rwnx_send_get_temp_req(rwnx_hw, &tp_cfm))
+				return -1;
+			AICWFDBG(LOGINFO, "tp_get temp_2: %d\n",
+				 tp_cfm.temp_comp_get_cfm.degree);
+			rwnx_hw->sdiodev->tp_ctrl.cur_temp =
+				tp_cfm.temp_comp_get_cfm.degree;
+			memcpy(command, &tp_cfm.temp_comp_get_cfm.degree, 1);
+		}
+	} else {
+		if (rwnx_send_get_temp_req(rwnx_hw, &tp_cfm))
+			return -1;
+		AICWFDBG(LOGINFO, "tp_get temp_3: %d\n",
+			 tp_cfm.temp_comp_get_cfm.degree);
+		memcpy(command, &tp_cfm.temp_comp_get_cfm.degree, 1);
+	}
+	bytes_written = 1;
+
+	return bytes_written;
+}
+
+static int aic_priv_cmd_tp_thd_set(struct rwnx_hw *rwnx_hw, int argc,
+				   char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 3) {
+		AICWFDBG(LOGERROR, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+	if (func == 1) {
+		rwnx_hw->sdiodev->tp_ctrl.tp_thd_1 = command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGINFO, "set tp_thd_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_1, 1);
+		bytes_written = 1;
+	} else if (func == 2) {
+		rwnx_hw->sdiodev->tp_ctrl.tp_thd_2 = command_strtoul(argv[2], NULL, 10);
+		AICWFDBG(LOGINFO, "set tp_thd_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_2, 1);
+		bytes_written = 1;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+	return bytes_written;
+}
+
+static int aic_priv_cmd_tp_thd_get(struct rwnx_hw *rwnx_hw, int argc,
+				   char *argv[], char *command)
+{
+	u8 func = 0;
+	int bytes_written = 0;
+
+	if (argc < 2) {
+		AICWFDBG(LOGERROR, "%s param err\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+	if (func == 1) {
+		AICWFDBG(LOGINFO, "get tp_thd_1: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_1);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_1, 1);
+		bytes_written = 1;
+	} else if (func == 2) {
+		AICWFDBG(LOGINFO, "set tp_thd_2: %d\n",
+			 rwnx_hw->sdiodev->tp_ctrl.tp_thd_2);
+		memcpy(command, &rwnx_hw->sdiodev->tp_ctrl.tp_thd_2, 1);
+		bytes_written = 1;
+	} else {
+		AICWFDBG(LOGERROR, "%s command err\n", __func__);
+		return -1;
+	}
+	return bytes_written;
+}
+
+#endif
+static int aic_priv_cmd_set_suspend(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	u8 func = 0;
+	s8 err = -1;
+	int ret = 0;
+
+	if (argc < 2 || rwnx_hw->testmode != 0) {
+		AICWFDBG(LOGERROR, "%s param err or in rf_test mode\n", __func__);
+		return -1;
+	}
+	func = (u8)command_strtoul(argv[1], NULL, 10);
+
+#ifndef CONFIG_AIC8800_AUTO_POWERSAVE
+	if (func == 0) {
+		AICWFDBG(LOGINFO, "priv_cmd suspend 0\n");
+		ret = rwnx_send_me_set_lp_level(rwnx_hw, 0, 1);
+	} else if (func == 1) {
+		AICWFDBG(LOGINFO, "priv_cmd suspend 1\n");
+		ret = rwnx_send_me_set_lp_level(rwnx_hw, 1, 0);
+		if (rwnx_hw->scan_request && rwnx_hw->scanning) {
+			pr_info("AICWF enter suspend, stop scan\n");
+			ret = rwnx_send_scanu_cancel_req(rwnx_hw, NULL);
+			/* make sure fw take effect */
+			msleep(50);
+			if (ret) {
+				pr_info("AICWF %s scanu_cancel fail\n", __func__);
+				return ret;
+			}
+		}
+	} else {
+		AICWFDBG(LOGERROR, "param err\n");
+		ret = -1;
+	}
+#else
+	func = 15;
+#endif
+
+	if (ret == 0) {
+		memcpy(command, &func, 1);
+		return 1;
+	}
+	memcpy(command, &err, 1);
+	return 1;
+}
+
+static int aic_priv_cmd_get_version(struct rwnx_hw *rwnx_hw, int argc,
+				    char *argv[], char *command)
+{
+	int bytes_written = 0;
+
+	AICWFDBG(LOGINFO, "Firmware Version: %s\n", rwnx_hw->fw_version);
+	memcpy(command, rwnx_hw->fw_version, 32);
+	bytes_written = 32;
+	return bytes_written;
+}
+
+static int aic_priv_cmd_get_link_status(struct rwnx_hw *rwnx_hw, int argc,
+					char *argv[], char *command)
+{
+	struct rwnx_vif *rwnx_vif = NULL;
+	struct rwnx_vif *rwnx_vif_st = NULL;
+	struct wf_bss_info bi;
+
+	bi.length = 0;
+	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
+		if (rwnx_vif && rwnx_vif->up &&
+		    (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION))
+			rwnx_vif_st = rwnx_vif;
+	}
+	if (!rwnx_vif_st) {
+		AICWFDBG(LOGINFO, "rwnx_vif_st is NULL\n");
+		memcpy(command, &bi, 4);
+		return 4;
+	}
+	if (atomic_read(&rwnx_vif_st->drv_conn_state) !=
+		(int)RWNX_DRV_STATUS_CONNECTED) {
+		AICWFDBG(LOGINFO, "rwnx_vif_st is not conncet\n");
+		memcpy(command, &bi, 4);
+		return 4;
+	}
+
+	bi.ssid_len = rwnx_vif_st->sta.ssid_len;
+	bi.band = rwnx_vif_st->sta.ap->band;
+	bi.width = rwnx_vif_st->sta.ap->width;
+	bi.center_freq = rwnx_vif_st->sta.ap->center_freq;
+	bi.center_freq1 = rwnx_vif_st->sta.ap->center_freq1;
+	bi.center_freq2 = rwnx_vif_st->sta.ap->center_freq2;
+	bi.ht = rwnx_vif_st->sta.ap->ht;
+	bi.vht = rwnx_vif_st->sta.ap->vht;
+	bi.chan = ieee80211_frequency_to_channel(bi.center_freq);
+	memcpy(bi.bssid, rwnx_vif_st->sta.bssid, ETH_ALEN);
+	memset(bi.ssid, 0, sizeof(bi.ssid));
+	memcpy(bi.ssid, rwnx_vif_st->sta.ssid, rwnx_vif_st->sta.ssid_len);
+	bi.length = sizeof(bi);
+
+	memcpy(command, &bi, bi.length);
+	return bi.length;
+}
+
+static int aic_priv_cmd_get_auth_type(struct rwnx_hw *rwnx_hw, int argc,
+				      char *argv[], char *command)
+{
+	struct rwnx_vif *rwnx_vif = NULL;
+	s32 val = -1;
+
+	list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
+		if (rwnx_vif && rwnx_vif->up &&
+		    (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION) &&
+			atomic_read(&rwnx_vif->drv_conn_state) ==
+				(int)RWNX_DRV_STATUS_CONNECTED)
+			val = rwnx_vif->sta.auth_type;
+	}
+
+	memcpy(command, &val, 4);
+	return 4;
+}
+
+static int aic_priv_cmd_help(struct rwnx_hw *rwnx_hw, int argc, char *argv[],
+			     char *command)
+{
+	print_help(argc > 0 ? argv[0] : NULL);
+	return 0;
+}
+
+struct aic_priv_cmd {
+	const char *cmd;
+	int (*handler)(struct rwnx_hw *rwnx_hw, int argc, char *argv[],
+		       char *command);
+	const char *usage;
+};
+
+static const struct aic_priv_cmd aic_priv_commands[] = {
+	{"set_mac_addr", aic_priv_cmd_set_mac_addr,
+	 "= write WiFi MAC into efuse or flash is limited to a maximum of two times"
+	 },
+	{"get_mac_addr", aic_priv_cmd_get_mac_addr,
+	 "= display WiFi MAC stored in efuse or flash"},
+	{"set_bt_mac_addr", aic_priv_cmd_set_bt_mac_addr,
+	 "= write BT MAC into efuse or flash is limited to a maximum of two times"},
+	{"get_bt_mac_addr", aic_priv_cmd_get_bt_mac_addr,
+	 "= display BT MAC stored in efuse or flash"},
+
+	/* The following is not an RF cmd */
+#ifdef CONFIG_AIC8800_AUTO_CUSTREG
+	{"country_set", aic_priv_cmd_country_set, "<ccode>"},
+	{"country_get", aic_priv_cmd_country_get, "no param"},
+#endif
+#ifdef CONFIG_AIC8800_TEMP_CONTROL
+	{"TEMP_CTRL_SW", aic_priv_cmd_temp_ctrl_sw, "<val> 1--open, 0--close"},
+	{"TEMP_CTRL_SET_GET", aic_priv_cmd_temp_sget,
+	 "<option> <val> option--0-get,1-set; val--0/1/2"},
+	{"SET_TMR_INTVAL", aic_priv_cmd_set_tmr_intval,
+	 "<index> <time> index--0/1, time ms"},
+	{"GET_TMR_INTVAL", aic_priv_cmd_get_tmr_intval, "<index> index--0/1"},
+	{"TEMP_GET", aic_priv_cmd_temp_get, "no param"},
+	{"TEMP_THRESHOLD_SET", aic_priv_cmd_tp_thd_set,
+	 "<index> <val> index--0/1, val--degree centigrade"},
+	{"TEMP_THRESHOLD_GET", aic_priv_cmd_tp_thd_get, "<index> inddex--0/1"},
+#endif
+	{"set_suspend", aic_priv_cmd_set_suspend,
+	 "<mode>, 1/0----enter/exit lp_level"},
+	{"get_version", aic_priv_cmd_get_version, "no param, get fw version"},
+	{"status", aic_priv_cmd_get_link_status, "no param, get link status"},
+	{"wpa_auth", aic_priv_cmd_get_auth_type,
+	 "no param, get AuthenticationType"},
+
+	// Reserve for new aic_priv_cmd.
+	{"help", aic_priv_cmd_help, "= show usage help"},
+	{NULL, NULL, NULL}
+
+};
+
+/*
+ * Prints command usage, lines are padded with the specified string.
+ */
+static void print_help(const char *cmd)
+{
+	int n;
+
+	pr_info("commands:\n");
+	for (n = 0; aic_priv_commands[n].cmd; n++) {
+		if (cmd)
+			pr_info("%s %s\n", aic_priv_commands[n].cmd,
+				aic_priv_commands[n].usage);
+	}
+}
+
+int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
+{
+	const struct aic_priv_cmd *cmd, *match = NULL;
+	int count;
+	int bytes_written = 0;
+	char **argv = NULL;
+	int argc;
+	struct rwnx_vif *vif =
+		container_of(net->ieee80211_ptr, struct rwnx_vif, wdev);
+	struct rwnx_hw *p_rwnx_hw = vif->rwnx_hw;
+
+	RWNX_DBG(RWNX_FN_ENTRY_STR);
+
+	argv = kzalloc((CMD_MAXARGS + 1) * sizeof(char *), GFP_KERNEL);
+	if (!argv) {
+		AICWFDBG(LOGERROR, "%s alloc argv fail\n", __func__);
+		return -ENOMEM;
+	}
+
+	argc = parse_line(command, argv);
+	if (argc == 0 || argc > CMD_MAXARGS) {
+		AICWFDBG(LOGERROR, "%s params error, count: %d\n", __func__, argc);
+		kfree(argv);
+		return -EINVAL;
+	}
+
+	count = 0;
+	cmd = aic_priv_commands;
+	while (cmd->cmd) {
+		if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0 &&
+		    strncasecmp(cmd->cmd, argv[0], strlen(cmd->cmd)) == 0) {
+			match = cmd;
+			if (strcasecmp(cmd->cmd, argv[0]) == 0) {
+				/* we have an exact match */
+				count = 1;
+				break;
+			}
+			count++;
+		}
+		cmd++;
+	}
+
+	if (count > 1) {
+		AICWFDBG(LOGINFO,
+			 "Ambiguous command '%s'; possible commands:", argv[0]);
+		cmd = aic_priv_commands;
+		while (cmd->cmd) {
+			if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0)
+				AICWFDBG(LOGINFO, " %s", cmd->cmd);
+			cmd++;
+		}
+		AICWFDBG(LOGINFO, "\n");
+	} else if (count == 0) {
+		AICWFDBG(LOGERROR, "Unknown command '%s'\n", argv[0]);
+		kfree(argv);
+		return -EINVAL;
+	}
+	AICWFDBG(LOGINFO, "match %s", match->cmd);
+	bytes_written = match->handler(p_rwnx_hw, argc, &argv[0], command);
+
+	if (bytes_written < 0)
+		AICWFDBG(LOGERROR, "wrong param\n");
+
+	kfree(argv);
+	return bytes_written;
+}
drivers/net/wireless/aic/aic8800_fdrv/aic_priv_cmd.h new file +103 -0

103 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800d80.c new file +291 -0

291 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8800dc.c new file +300 -0

300 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_8801.c new file +279 -0

279 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.c new file +251 -0

251 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_chip_ops.h new file +184 -0

184 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.c new file +96 -0

96 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800d80.h new file +16 -0
new file mode 100644
index 0000000000000..22f882d3aa3a2
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_COMPAT_8800D80_H_
+#define _AICWF_COMPAT_8800D80_H_
+#include "reg_access.h"
+#include "rwnx_main.h"
+#include "rwnx_msg_tx.h"
+#include <linux/types.h>
+
+int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw,
+				struct mm_set_rf_calib_cfm *cfm);
+int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
+#ifdef CONFIG_AIC8800_POWER_LIMIT
+int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
+#endif
+
+#endif
drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.c new file +505 -0

505 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_compat_8800dc.h new file +22 -0
new file mode 100644
index 0000000000000..12e8d60150452
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AICWF_COMPAT_8800DC_H_
+#define _AICWF_COMPAT_8800DC_H_
+
+#include "aic_bsp_export.h"
+#include <linux/types.h>
+
+#ifdef CONFIG_DPD
+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw,
+				       struct rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw,
+				      struct rf_misc_ram_lite_t *dpd_res);
+#endif
+#endif
+int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
+int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw,
+			       struct mm_set_rf_calib_cfm *cfm);
+int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw);
+int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);
+
+#endif /* _AICWF_COMPAT_8800DC_H_ */
drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.c new file +699 -0

190 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_genl.h new file +84 -0

84 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.c new file +102 -0

102 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_rx_prealloc.h new file +34 -0
new file mode 100644
index 0000000000000..666e2f0027102

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.c new file +2831 -0

2,831 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_sdio.h new file +275 -0

275 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.c new file +565 -0

565 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_tcp_ack.h new file +104 -0

104 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.c new file +752 -0

752 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/aicwf_txrxif.h new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/regdb.c new file +2772 -0

2,772 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.c new file +93 -0

93 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_bfmer.h new file +100 -0

100 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.c new file +265 -0

265 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_cfgfile.h new file +33 -0
new file mode 100644
index 0000000000000..d76179316fe2a

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.c new file +5435 -0

5,435 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_main.h new file +35 -0
new file mode 100644
index 0000000000000..e03321c99c42c

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.c new file +33 -0
new file mode 100644
index 0000000000000..69d37ecb63be2

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mesh.h new file +35 -0
new file mode 100644
index 0000000000000..44de24ea705a1

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.c new file +985 -0

985 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mod_params.h new file +74 -0

74 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.c new file +653 -0

653 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_mu_group.h new file +159 -0

159 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.c new file +1970 -0

1,970 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_radar.h new file +285 -0

285 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.c new file +2320 -0

2,320 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_rx.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.c new file +772 -0

772 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tdls.h new file +57 -0

57 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.c new file +217 -0

217 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_testmode.h new file +68 -0

68 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_trace.c new file +5 -0
new file mode 100644
index 0000000000000..732fca321d965

Lines of this file are not shown. View the raw message.

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.c new file +1634 -0

1,634 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_tx.h new file +178 -0

178 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.c new file +1362 -0

1,362 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/rwnx_txq.h new file +358 -0

358 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.c new file +132 -0

132 lines not on this page · raw message

drivers/net/wireless/aic/aic8800_fdrv/sdio_host.h new file +39 -0
new file mode 100644
index 0000000000000..17a1cde69c27d

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.34.1

Part of the diff is not shown here. View the raw message.

author
#18 lore raw

RFC PATCH v4 4/4 wifi: aic: integrate AIC8800 driver

In reply to Yanli Yang

From: Zhirun Liu <[email protected]>

Connect the completed AIC vendor directory to the wireless build and add its MAINTAINERS entry. Keeping integration last prevents an earlier partial source state from being selected by Kconfig.

---
 MAINTAINERS                   | 10 ++++++++++
 drivers/net/wireless/Kconfig  |  1 +
 drivers/net/wireless/Makefile |  1 +
 3 files changed, 12 insertions(+)
MAINTAINERS +10 -0
index 2d420d40782e3..886a60e7c237e 100644
@@ -736,6 +736,16 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/scsi/aic7xxx/
 
+AIC8800 WIRELESS DRIVER
+M:	Zhirun Liu <[email protected]>
+M:	Dijia Xu <[email protected]>
+M:	Chunqiu Liu <[email protected]>
+M:	Liheng Wei <[email protected]>
+M:	Yanli Yang <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/net/wireless/aic/
+
 AIMSLAB FM RADIO RECEIVER DRIVER
 M:	Hans Verkuil <[email protected]>
 L:	[email protected]
drivers/net/wireless/Kconfig +1 -0
index f4f969fdbc020..964e633898ca8 100644
@@ -19,6 +19,7 @@ menuconfig WLAN
 if WLAN
 
 source "drivers/net/wireless/admtek/Kconfig"
+source "drivers/net/wireless/aic/Kconfig"
 source "drivers/net/wireless/ath/Kconfig"
 source "drivers/net/wireless/atmel/Kconfig"
 source "drivers/net/wireless/broadcom/Kconfig"
drivers/net/wireless/Makefile +1 -0
index fa3100ff3bf7b..47b999e8014ca 100644
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_WLAN_VENDOR_ADMTEK) += admtek/
+obj-$(CONFIG_WLAN_VENDOR_AIC) += aic/
 obj-$(CONFIG_WLAN_VENDOR_ATH) += ath/
 obj-$(CONFIG_WLAN_VENDOR_ATMEL) += atmel/
 obj-$(CONFIG_WLAN_VENDOR_BROADCOM) += broadcom/
Signature · 1 line
2.34.1
#19 lore raw

Re: [RFC PATCH wireless-next v4 0/4] wifi: aic: add AIC8800D80 SDIO FullMAC driver

In reply to Yanli Yang
Quoted 20 lines · Yanli Yang

Johannes,

This v4 fixes the build failure in v3 against current wireless-next.

Commit 914781c72813 ("wifi: cfg80211: convert cookie output to input parameter") changed the cfg80211 remain_on_channel and mgmt_tx callbacks from u64 pointer output parameters to preassigned u64 input parameters. The driver now accepts each cookie by value, carries it through the remain-on-channel and management-TX state, and reports the same cookie in the corresponding cfg80211 completion notification. The obsolete local remain-on-channel cookie counter has been removed.

This revision also removes two unused global definitions found during the rebuild. The feature scope and the status of the outstanding RFC review items are otherwise unchanged from v3.

Validation performed for v4 against wireless-next at ca800a9302764:

Quoted 7 lines

- x86-64 GCC build with AIC8800_BSP_SUPPORT=m, AIC8800_WLAN_SUPPORT=m and W=1;
- sequential application of all four patches; and
- comparison of the applied series with the current AIC source tree.

No runtime retest was performed for v4. The AIC8800D80 U02 SDIO hardware validation reported with v3 is unchanged.

I picked the four patches in this series into my rockchip-7.2.y kernel branch [0] and compile failed. Claude Opus suggested fixes [1] which allowed compile to succeed. Sadly I've no idea if the changes resulted in a working driver as I've enthusiastically powered up a Radxa Rock4D board and rediscovered its AIC8800 is connected via USB not SDIO; but I figured I'd share the finding anyway, in case it's valid.

Keep up the good work, I look forward to USB support in the future!

Christian

[0] https://github.com/chewitt/linux/commits/rockchip-7.2.y
[1] https://github.com/chewitt/linux/commit/9bc092d55a76ec5a647494223147dfc1f1700853

maintainer
#20 lore raw

Re: [RFC PATCH wireless-next v3 0/4] wifi: aic: add AIC8800D80 SDIO FullMAC driver

In reply to Yanli Yang
Quoted 3 lines · Yanli Yang

Johannes,

Thank you for the detailed review of v2.

I think you misunderstood. That was *not* a detailed review of the driver, and it was emphatically not a list of "fix these things and I'll consider looking at it".

Quite on the contrary - it was a "you've so obviously misunderstood the upstream process that my LLM can find a huge list of things".

In fact, your answers like "we now have AIC8800_GENL" make it clear that you've really not bothered to even attempt to understand the upstream process. We don't care about what you deployed to your existing customers while your driver was out of tree.

The only way you can reconcile this is to actually learn about upstream and be proactive, not reactive. I will not review this until you've demonstrated at least a willingness to do so.

johannes