From f54ec58fee837ec847cb8b50593e81bfaa46107f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Oct 2020 21:12:12 +0100 Subject: wimax: move out to staging There are no known users of this driver as of October 2020, and it will be removed unless someone turns out to still need it in future releases. According to https://en.wikipedia.org/wiki/List_of_WiMAX_networks, there have been many public wimax networks, but it appears that many of these have migrated to LTE or discontinued their service altogether. As most PCs and phones lack WiMAX hardware support, the remaining networks tend to use standalone routers. These almost certainly run Linux, but not a modern kernel or the mainline wimax driver stack. NetworkManager appears to have dropped userspace support in 2015 https://bugzilla.gnome.org/show_bug.cgi?id=747846, the www.linuxwimax.org site had already shut down earlier. WiMax is apparently still being deployed on airport campus networks ("AeroMACS"), but in a frequency band that was not supported by the old Intel 2400m (used in Sandy Bridge laptops and earlier), which is the only driver using the kernel's wimax stack. Move all files into drivers/staging/wimax, including the uapi header files and documentation, to make it easier to remove it when it gets to that. Only minimal changes are made to the source files, in order to make it possible to port patches across the move. Also remove the MAINTAINERS entry that refers to a broken mailing list and website. Acked-by: Jakub Kicinski Acked-by: Greg Kroah-Hartman Acked-By: Inaky Perez-Gonzalez Acked-by: Johannes Berg Suggested-by: Inaky Perez-Gonzalez Signed-off-by: Arnd Bergmann --- Documentation/admin-guide/index.rst | 1 - Documentation/admin-guide/wimax/i2400m.rst | 283 ---- Documentation/admin-guide/wimax/index.rst | 19 - Documentation/admin-guide/wimax/wimax.rst | 89 -- Documentation/networking/kapi.rst | 21 - .../translations/zh_CN/admin-guide/index.rst | 1 - MAINTAINERS | 22 - drivers/net/Kconfig | 2 - drivers/net/Makefile | 1 - drivers/net/wimax/Kconfig | 18 - drivers/net/wimax/Makefile | 2 - drivers/net/wimax/i2400m/Kconfig | 37 - drivers/net/wimax/i2400m/Makefile | 23 - drivers/net/wimax/i2400m/control.c | 1434 ----------------- drivers/net/wimax/i2400m/debug-levels.h | 32 - drivers/net/wimax/i2400m/debugfs.c | 253 --- drivers/net/wimax/i2400m/driver.c | 1002 ------------ drivers/net/wimax/i2400m/fw.c | 1653 -------------------- drivers/net/wimax/i2400m/i2400m-usb.h | 275 ---- drivers/net/wimax/i2400m/i2400m.h | 970 ------------ drivers/net/wimax/i2400m/netdev.c | 603 ------- drivers/net/wimax/i2400m/op-rfkill.c | 196 --- drivers/net/wimax/i2400m/rx.c | 1395 ----------------- drivers/net/wimax/i2400m/sysfs.c | 65 - drivers/net/wimax/i2400m/tx.c | 1011 ------------ drivers/net/wimax/i2400m/usb-debug-levels.h | 28 - drivers/net/wimax/i2400m/usb-fw.c | 365 ----- drivers/net/wimax/i2400m/usb-notif.c | 258 --- drivers/net/wimax/i2400m/usb-rx.c | 462 ------ drivers/net/wimax/i2400m/usb-tx.c | 273 ---- drivers/net/wimax/i2400m/usb.c | 764 --------- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/wimax/Documentation/i2400m.rst | 283 ++++ drivers/staging/wimax/Documentation/index.rst | 19 + drivers/staging/wimax/Documentation/wimax.rst | 89 ++ drivers/staging/wimax/Kconfig | 46 + drivers/staging/wimax/Makefile | 15 + drivers/staging/wimax/TODO | 18 + drivers/staging/wimax/debug-levels.h | 29 + drivers/staging/wimax/debugfs.c | 38 + drivers/staging/wimax/i2400m/Kconfig | 37 + drivers/staging/wimax/i2400m/Makefile | 23 + drivers/staging/wimax/i2400m/control.c | 1434 +++++++++++++++++ drivers/staging/wimax/i2400m/debug-levels.h | 32 + drivers/staging/wimax/i2400m/debugfs.c | 253 +++ drivers/staging/wimax/i2400m/driver.c | 1002 ++++++++++++ drivers/staging/wimax/i2400m/fw.c | 1653 ++++++++++++++++++++ drivers/staging/wimax/i2400m/i2400m-usb.h | 275 ++++ drivers/staging/wimax/i2400m/i2400m.h | 970 ++++++++++++ drivers/staging/wimax/i2400m/linux-wimax-i2400m.h | 572 +++++++ drivers/staging/wimax/i2400m/netdev.c | 603 +++++++ drivers/staging/wimax/i2400m/op-rfkill.c | 196 +++ drivers/staging/wimax/i2400m/rx.c | 1395 +++++++++++++++++ drivers/staging/wimax/i2400m/sysfs.c | 65 + drivers/staging/wimax/i2400m/tx.c | 1011 ++++++++++++ drivers/staging/wimax/i2400m/usb-debug-levels.h | 28 + drivers/staging/wimax/i2400m/usb-fw.c | 365 +++++ drivers/staging/wimax/i2400m/usb-notif.c | 258 +++ drivers/staging/wimax/i2400m/usb-rx.c | 462 ++++++ drivers/staging/wimax/i2400m/usb-tx.c | 273 ++++ drivers/staging/wimax/i2400m/usb.c | 764 +++++++++ drivers/staging/wimax/id-table.c | 130 ++ drivers/staging/wimax/linux-wimax-debug.h | 491 ++++++ drivers/staging/wimax/linux-wimax.h | 239 +++ drivers/staging/wimax/net-wimax.h | 503 ++++++ drivers/staging/wimax/op-msg.c | 391 +++++ drivers/staging/wimax/op-reset.c | 108 ++ drivers/staging/wimax/op-rfkill.c | 431 +++++ drivers/staging/wimax/op-state-get.c | 52 + drivers/staging/wimax/stack.c | 616 ++++++++ drivers/staging/wimax/wimax-internal.h | 85 + include/linux/wimax/debug.h | 491 ------ include/net/wimax.h | 503 ------ include/uapi/linux/wimax.h | 239 --- include/uapi/linux/wimax/i2400m.h | 572 ------- net/Kconfig | 2 - net/Makefile | 1 - net/wimax/Kconfig | 40 - net/wimax/Makefile | 13 - net/wimax/debug-levels.h | 29 - net/wimax/debugfs.c | 38 - net/wimax/id-table.c | 130 -- net/wimax/op-msg.c | 391 ----- net/wimax/op-reset.c | 108 -- net/wimax/op-rfkill.c | 431 ----- net/wimax/op-state-get.c | 52 - net/wimax/stack.c | 616 -------- net/wimax/wimax-internal.h | 85 - 89 files changed, 15257 insertions(+), 15299 deletions(-) delete mode 100644 Documentation/admin-guide/wimax/i2400m.rst delete mode 100644 Documentation/admin-guide/wimax/index.rst delete mode 100644 Documentation/admin-guide/wimax/wimax.rst delete mode 100644 drivers/net/wimax/Kconfig delete mode 100644 drivers/net/wimax/Makefile delete mode 100644 drivers/net/wimax/i2400m/Kconfig delete mode 100644 drivers/net/wimax/i2400m/Makefile delete mode 100644 drivers/net/wimax/i2400m/control.c delete mode 100644 drivers/net/wimax/i2400m/debug-levels.h delete mode 100644 drivers/net/wimax/i2400m/debugfs.c delete mode 100644 drivers/net/wimax/i2400m/driver.c delete mode 100644 drivers/net/wimax/i2400m/fw.c delete mode 100644 drivers/net/wimax/i2400m/i2400m-usb.h delete mode 100644 drivers/net/wimax/i2400m/i2400m.h delete mode 100644 drivers/net/wimax/i2400m/netdev.c delete mode 100644 drivers/net/wimax/i2400m/op-rfkill.c delete mode 100644 drivers/net/wimax/i2400m/rx.c delete mode 100644 drivers/net/wimax/i2400m/sysfs.c delete mode 100644 drivers/net/wimax/i2400m/tx.c delete mode 100644 drivers/net/wimax/i2400m/usb-debug-levels.h delete mode 100644 drivers/net/wimax/i2400m/usb-fw.c delete mode 100644 drivers/net/wimax/i2400m/usb-notif.c delete mode 100644 drivers/net/wimax/i2400m/usb-rx.c delete mode 100644 drivers/net/wimax/i2400m/usb-tx.c delete mode 100644 drivers/net/wimax/i2400m/usb.c create mode 100644 drivers/staging/wimax/Documentation/i2400m.rst create mode 100644 drivers/staging/wimax/Documentation/index.rst create mode 100644 drivers/staging/wimax/Documentation/wimax.rst create mode 100644 drivers/staging/wimax/Kconfig create mode 100644 drivers/staging/wimax/Makefile create mode 100644 drivers/staging/wimax/TODO create mode 100644 drivers/staging/wimax/debug-levels.h create mode 100644 drivers/staging/wimax/debugfs.c create mode 100644 drivers/staging/wimax/i2400m/Kconfig create mode 100644 drivers/staging/wimax/i2400m/Makefile create mode 100644 drivers/staging/wimax/i2400m/control.c create mode 100644 drivers/staging/wimax/i2400m/debug-levels.h create mode 100644 drivers/staging/wimax/i2400m/debugfs.c create mode 100644 drivers/staging/wimax/i2400m/driver.c create mode 100644 drivers/staging/wimax/i2400m/fw.c create mode 100644 drivers/staging/wimax/i2400m/i2400m-usb.h create mode 100644 drivers/staging/wimax/i2400m/i2400m.h create mode 100644 drivers/staging/wimax/i2400m/linux-wimax-i2400m.h create mode 100644 drivers/staging/wimax/i2400m/netdev.c create mode 100644 drivers/staging/wimax/i2400m/op-rfkill.c create mode 100644 drivers/staging/wimax/i2400m/rx.c create mode 100644 drivers/staging/wimax/i2400m/sysfs.c create mode 100644 drivers/staging/wimax/i2400m/tx.c create mode 100644 drivers/staging/wimax/i2400m/usb-debug-levels.h create mode 100644 drivers/staging/wimax/i2400m/usb-fw.c create mode 100644 drivers/staging/wimax/i2400m/usb-notif.c create mode 100644 drivers/staging/wimax/i2400m/usb-rx.c create mode 100644 drivers/staging/wimax/i2400m/usb-tx.c create mode 100644 drivers/staging/wimax/i2400m/usb.c create mode 100644 drivers/staging/wimax/id-table.c create mode 100644 drivers/staging/wimax/linux-wimax-debug.h create mode 100644 drivers/staging/wimax/linux-wimax.h create mode 100644 drivers/staging/wimax/net-wimax.h create mode 100644 drivers/staging/wimax/op-msg.c create mode 100644 drivers/staging/wimax/op-reset.c create mode 100644 drivers/staging/wimax/op-rfkill.c create mode 100644 drivers/staging/wimax/op-state-get.c create mode 100644 drivers/staging/wimax/stack.c create mode 100644 drivers/staging/wimax/wimax-internal.h delete mode 100644 include/linux/wimax/debug.h delete mode 100644 include/net/wimax.h delete mode 100644 include/uapi/linux/wimax.h delete mode 100644 include/uapi/linux/wimax/i2400m.h delete mode 100644 net/wimax/Kconfig delete mode 100644 net/wimax/Makefile delete mode 100644 net/wimax/debug-levels.h delete mode 100644 net/wimax/debugfs.c delete mode 100644 net/wimax/id-table.c delete mode 100644 net/wimax/op-msg.c delete mode 100644 net/wimax/op-reset.c delete mode 100644 net/wimax/op-rfkill.c delete mode 100644 net/wimax/op-state-get.c delete mode 100644 net/wimax/stack.c delete mode 100644 net/wimax/wimax-internal.h diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst index ed1cf94ea50c..d53986a424c4 100644 --- a/Documentation/admin-guide/index.rst +++ b/Documentation/admin-guide/index.rst @@ -115,7 +115,6 @@ configure specific aspects of kernel behavior to your liking. unicode vga-softcursor video-output - wimax/index xfs .. only:: subproject and html diff --git a/Documentation/admin-guide/wimax/i2400m.rst b/Documentation/admin-guide/wimax/i2400m.rst deleted file mode 100644 index 194388c0c351..000000000000 --- a/Documentation/admin-guide/wimax/i2400m.rst +++ /dev/null @@ -1,283 +0,0 @@ -.. include:: - -==================================================== -Driver for the Intel Wireless Wimax Connection 2400m -==================================================== - -:Copyright: |copy| 2008 Intel Corporation < linux-wimax@intel.com > - - This provides a driver for the Intel Wireless WiMAX Connection 2400m - and a basic Linux kernel WiMAX stack. - -1. Requirements -=============== - - * Linux installation with Linux kernel 2.6.22 or newer (if building - from a separate tree) - * Intel i2400m Echo Peak or Baxter Peak; this includes the Intel - Wireless WiMAX/WiFi Link 5x50 series. - * build tools: - - + Linux kernel development package for the target kernel; to - build against your currently running kernel, you need to have - the kernel development package corresponding to the running - image installed (usually if your kernel is named - linux-VERSION, the development package is called - linux-dev-VERSION or linux-headers-VERSION). - + GNU C Compiler, make - -2. Compilation and installation -=============================== - -2.1. Compilation of the drivers included in the kernel ------------------------------------------------------- - - Configure the kernel; to enable the WiMAX drivers select Drivers > - Networking Drivers > WiMAX device support. Enable all of them as - modules (easier). - - If USB or SDIO are not enabled in the kernel configuration, the options - to build the i2400m USB or SDIO drivers will not show. Enable said - subsystems and go back to the WiMAX menu to enable the drivers. - - Compile and install your kernel as usual. - -2.2. Compilation of the drivers distributed as an standalone module -------------------------------------------------------------------- - - To compile:: - - $ cd source/directory - $ make - - Once built you can load and unload using the provided load.sh script; - load.sh will load the modules, load.sh u will unload them. - - To install in the default kernel directories (and enable auto loading - when the device is plugged):: - - $ make install - $ depmod -a - - If your kernel development files are located in a non standard - directory or if you want to build for a kernel that is not the - currently running one, set KDIR to the right location:: - - $ make KDIR=/path/to/kernel/dev/tree - - For more information, please contact linux-wimax@intel.com. - -3. Installing the firmware --------------------------- - - The firmware can be obtained from http://linuxwimax.org or might have - been supplied with your hardware. - - It has to be installed in the target system:: - - $ cp FIRMWAREFILE.sbcf /lib/firmware/i2400m-fw-BUSTYPE-1.3.sbcf - - * NOTE: if your firmware came in an .rpm or .deb file, just install - it as normal, with the rpm (rpm -i FIRMWARE.rpm) or dpkg - (dpkg -i FIRMWARE.deb) commands. No further action is needed. - * BUSTYPE will be usb or sdio, depending on the hardware you have. - Each hardware type comes with its own firmware and will not work - with other types. - -4. Design -========= - - This package contains two major parts: a WiMAX kernel stack and a - driver for the Intel i2400m. - - The WiMAX stack is designed to provide for common WiMAX control - services to current and future WiMAX devices from any vendor; please - see README.wimax for details. - - The i2400m kernel driver is broken up in two main parts: the bus - generic driver and the bus-specific drivers. The bus generic driver - forms the drivercore and contain no knowledge of the actual method we - use to connect to the device. The bus specific drivers are just the - glue to connect the bus-generic driver and the device. Currently only - USB and SDIO are supported. See drivers/net/wimax/i2400m/i2400m.h for - more information. - - The bus generic driver is logically broken up in two parts: OS-glue and - hardware-glue. The OS-glue interfaces with Linux. The hardware-glue - interfaces with the device on using an interface provided by the - bus-specific driver. The reason for this breakup is to be able to - easily reuse the hardware-glue to write drivers for other OSes; note - the hardware glue part is written as a native Linux driver; no - abstraction layers are used, so to port to another OS, the Linux kernel - API calls should be replaced with the target OS's. - -5. Usage -======== - - To load the driver, follow the instructions in the install section; - once the driver is loaded, plug in the device (unless it is permanently - plugged in). The driver will enumerate the device, upload the firmware - and output messages in the kernel log (dmesg, /var/log/messages or - /var/log/kern.log) such as:: - - ... - i2400m_usb 5-4:1.0: firmware interface version 8.0.0 - i2400m_usb 5-4:1.0: WiMAX interface wmx0 (00:1d:e1:01:94:2c) ready - - At this point the device is ready to work. - - Current versions require the Intel WiMAX Network Service in userspace - to make things work. See the network service's README for instructions - on how to scan, connect and disconnect. - -5.1. Module parameters ----------------------- - - Module parameters can be set at kernel or module load time or by - echoing values:: - - $ echo VALUE > /sys/module/MODULENAME/parameters/PARAMETERNAME - - To make changes permanent, for example, for the i2400m module, you can - also create a file named /etc/modprobe.d/i2400m containing:: - - options i2400m idle_mode_disabled=1 - - To find which parameters are supported by a module, run:: - - $ modinfo path/to/module.ko - - During kernel bootup (if the driver is linked in the kernel), specify - the following to the kernel command line:: - - i2400m.PARAMETER=VALUE - -5.1.1. i2400m: idle_mode_disabled -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The i2400m module supports a parameter to disable idle mode. This - parameter, once set, will take effect only when the device is - reinitialized by the driver (eg: following a reset or a reconnect). - -5.2. Debug operations: debugfs entries --------------------------------------- - - The driver will register debugfs entries that allow the user to tweak - debug settings. There are three main container directories where - entries are placed, which correspond to the three blocks a i2400m WiMAX - driver has: - - * /sys/kernel/debug/wimax:DEVNAME/ for the generic WiMAX stack - controls - * /sys/kernel/debug/wimax:DEVNAME/i2400m for the i2400m generic - driver controls - * /sys/kernel/debug/wimax:DEVNAME/i2400m-usb (or -sdio) for the - bus-specific i2400m-usb or i2400m-sdio controls). - - Of course, if debugfs is mounted in a directory other than - /sys/kernel/debug, those paths will change. - -5.2.1. Increasing debug output -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The files named *dl_* indicate knobs for controlling the debug output - of different submodules:: - - # find /sys/kernel/debug/wimax\:wmx0 -name \*dl_\* - /sys/kernel/debug/wimax:wmx0/i2400m-usb/dl_tx - /sys/kernel/debug/wimax:wmx0/i2400m-usb/dl_rx - /sys/kernel/debug/wimax:wmx0/i2400m-usb/dl_notif - /sys/kernel/debug/wimax:wmx0/i2400m-usb/dl_fw - /sys/kernel/debug/wimax:wmx0/i2400m-usb/dl_usb - /sys/kernel/debug/wimax:wmx0/i2400m/dl_tx - /sys/kernel/debug/wimax:wmx0/i2400m/dl_rx - /sys/kernel/debug/wimax:wmx0/i2400m/dl_rfkill - /sys/kernel/debug/wimax:wmx0/i2400m/dl_netdev - /sys/kernel/debug/wimax:wmx0/i2400m/dl_fw - /sys/kernel/debug/wimax:wmx0/i2400m/dl_debugfs - /sys/kernel/debug/wimax:wmx0/i2400m/dl_driver - /sys/kernel/debug/wimax:wmx0/i2400m/dl_control - /sys/kernel/debug/wimax:wmx0/wimax_dl_stack - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_rfkill - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_reset - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_msg - /sys/kernel/debug/wimax:wmx0/wimax_dl_id_table - /sys/kernel/debug/wimax:wmx0/wimax_dl_debugfs - - By reading the file you can obtain the current value of said debug - level; by writing to it, you can set it. - - To increase the debug level of, for example, the i2400m's generic TX - engine, just write:: - - $ echo 3 > /sys/kernel/debug/wimax:wmx0/i2400m/dl_tx - - Increasing numbers yield increasing debug information; for details of - what is printed and the available levels, check the source. The code - uses 0 for disabled and increasing values until 8. - -5.2.2. RX and TX statistics -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The i2400m/rx_stats and i2400m/tx_stats provide statistics about the - data reception/delivery from the device:: - - $ cat /sys/kernel/debug/wimax:wmx0/i2400m/rx_stats - 45 1 3 34 3104 48 480 - - The numbers reported are: - - * packets/RX-buffer: total, min, max - * RX-buffers: total RX buffers received, accumulated RX buffer size - in bytes, min size received, max size received - - Thus, to find the average buffer size received, divide accumulated - RX-buffer / total RX-buffers. - - To clear the statistics back to 0, write anything to the rx_stats file:: - - $ echo 1 > /sys/kernel/debug/wimax:wmx0/i2400m_rx_stats - - Likewise for TX. - - Note the packets this debug file refers to are not network packet, but - packets in the sense of the device-specific protocol for communication - to the host. See drivers/net/wimax/i2400m/tx.c. - -5.2.3. Tracing messages received from user space -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - To echo messages received from user space into the trace pipe that the - i2400m driver creates, set the debug file i2400m/trace_msg_from_user to - 1:: - - $ echo 1 > /sys/kernel/debug/wimax:wmx0/i2400m/trace_msg_from_user - -5.2.4. Performing a device reset -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - By writing a 0, a 1 or a 2 to the file - /sys/kernel/debug/wimax:wmx0/reset, the driver performs a warm (without - disconnecting from the bus), cold (disconnecting from the bus) or bus - (bus specific) reset on the device. - -5.2.5. Asking the device to enter power saving mode -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - By writing any value to the /sys/kernel/debug/wimax:wmx0 file, the - device will attempt to enter power saving mode. - -6. Troubleshooting -================== - -6.1. Driver complains about ``i2400m-fw-usb-1.2.sbcf: request failed`` ----------------------------------------------------------------------- - - If upon connecting the device, the following is output in the kernel - log:: - - i2400m_usb 5-4:1.0: fw i2400m-fw-usb-1.3.sbcf: request failed: -2 - - This means that the driver cannot locate the firmware file named - /lib/firmware/i2400m-fw-usb-1.2.sbcf. Check that the file is present in - the right location. diff --git a/Documentation/admin-guide/wimax/index.rst b/Documentation/admin-guide/wimax/index.rst deleted file mode 100644 index fdf7c1f99ff5..000000000000 --- a/Documentation/admin-guide/wimax/index.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -=============== -WiMAX subsystem -=============== - -.. toctree:: - :maxdepth: 2 - - wimax - - i2400m - -.. only:: subproject and html - - Indices - ======= - - * :ref:`genindex` diff --git a/Documentation/admin-guide/wimax/wimax.rst b/Documentation/admin-guide/wimax/wimax.rst deleted file mode 100644 index 817ee8ba2732..000000000000 --- a/Documentation/admin-guide/wimax/wimax.rst +++ /dev/null @@ -1,89 +0,0 @@ -.. include:: - -======================== -Linux kernel WiMAX stack -======================== - -:Copyright: |copy| 2008 Intel Corporation < linux-wimax@intel.com > - - This provides a basic Linux kernel WiMAX stack to provide a common - control API for WiMAX devices, usable from kernel and user space. - -1. Design -========= - - The WiMAX stack is designed to provide for common WiMAX control - services to current and future WiMAX devices from any vendor. - - Because currently there is only one and we don't know what would be the - common services, the APIs it currently provides are very minimal. - However, it is done in such a way that it is easily extensible to - accommodate future requirements. - - The stack works by embedding a struct wimax_dev in your device's - control structures. This provides a set of callbacks that the WiMAX - stack will call in order to implement control operations requested by - the user. As well, the stack provides API functions that the driver - calls to notify about changes of state in the device. - - The stack exports the API calls needed to control the device to user - space using generic netlink as a marshalling mechanism. You can access - them using your own code or use the wrappers provided for your - convenience in libwimax (in the wimax-tools package). - - For detailed information on the stack, please see - include/linux/wimax.h. - -2. Usage -======== - - For usage in a driver (registration, API, etc) please refer to the - instructions in the header file include/linux/wimax.h. - - When a device is registered with the WiMAX stack, a set of debugfs - files will appear in /sys/kernel/debug/wimax:wmxX can tweak for - control. - -2.1. Obtaining debug information: debugfs entries -------------------------------------------------- - - The WiMAX stack is compiled, by default, with debug messages that can - be used to diagnose issues. By default, said messages are disabled. - - The drivers will register debugfs entries that allow the user to tweak - debug settings. - - Each driver, when registering with the stack, will cause a debugfs - directory named wimax:DEVICENAME to be created; optionally, it might - create more subentries below it. - -2.1.1. Increasing debug output ------------------------------- - - The files named *dl_* indicate knobs for controlling the debug output - of different submodules of the WiMAX stack:: - - # find /sys/kernel/debug/wimax\:wmx0 -name \*dl_\* - /sys/kernel/debug/wimax:wmx0/wimax_dl_stack - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_rfkill - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_reset - /sys/kernel/debug/wimax:wmx0/wimax_dl_op_msg - /sys/kernel/debug/wimax:wmx0/wimax_dl_id_table - /sys/kernel/debug/wimax:wmx0/wimax_dl_debugfs - /sys/kernel/debug/wimax:wmx0/.... # other driver specific files - - NOTE: - Of course, if debugfs is mounted in a directory other than - /sys/kernel/debug, those paths will change. - - By reading the file you can obtain the current value of said debug - level; by writing to it, you can set it. - - To increase the debug level of, for example, the id-table submodule, - just write: - - $ echo 3 > /sys/kernel/debug/wimax:wmx0/wimax_dl_id_table - - Increasing numbers yield increasing debug information; for details of - what is printed and the available levels, check the source. The code - uses 0 for disabled and increasing values until 8. diff --git a/Documentation/networking/kapi.rst b/Documentation/networking/kapi.rst index d198fa5eaacd..ea55f462cefa 100644 --- a/Documentation/networking/kapi.rst +++ b/Documentation/networking/kapi.rst @@ -83,27 +83,6 @@ SUN RPC subsystem .. kernel-doc:: net/sunrpc/clnt.c :export: -WiMAX ------ - -.. kernel-doc:: net/wimax/op-msg.c - :export: - -.. kernel-doc:: net/wimax/op-reset.c - :export: - -.. kernel-doc:: net/wimax/op-rfkill.c - :export: - -.. kernel-doc:: net/wimax/stack.c - :export: - -.. kernel-doc:: include/net/wimax.h - :internal: - -.. kernel-doc:: include/uapi/linux/wimax.h - :internal: - Network device support ====================== diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index ed5ab7e37f38..48bbd3ebad48 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -114,7 +114,6 @@ Todolist: unicode vga-softcursor video-output - wimax/index xfs .. only:: subproject and html diff --git a/MAINTAINERS b/MAINTAINERS index e73636b75f29..17f5571788c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9106,16 +9106,6 @@ W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git F: drivers/net/wireless/intel/iwlwifi/ -INTEL WIRELESS WIMAX CONNECTION 2400 -M: Inaky Perez-Gonzalez -M: linux-wimax@intel.com -L: wimax@linuxwimax.org (subscribers-only) -S: Supported -W: http://linuxwimax.org -F: Documentation/admin-guide/wimax/i2400m.rst -F: drivers/net/wimax/i2400m/ -F: include/uapi/linux/wimax/i2400m.h - INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER M: Jithu Joseph R: Maurice Ma @@ -18907,18 +18897,6 @@ S: Supported W: https://wireless.wiki.kernel.org/en/users/Drivers/wil6210 F: drivers/net/wireless/ath/wil6210/ -WIMAX STACK -M: Inaky Perez-Gonzalez -M: linux-wimax@intel.com -L: wimax@linuxwimax.org (subscribers-only) -S: Supported -W: http://linuxwimax.org -F: Documentation/admin-guide/wimax/wimax.rst -F: include/linux/wimax/debug.h -F: include/net/wimax.h -F: include/uapi/linux/wimax.h -F: net/wimax/ - WINBOND CIR DRIVER M: David Härdeman S: Maintained diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c3dbe64e628e..c0af2dc8b938 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -489,8 +489,6 @@ source "drivers/net/usb/Kconfig" source "drivers/net/wireless/Kconfig" -source "drivers/net/wimax/Kconfig" - source "drivers/net/wan/Kconfig" source "drivers/net/ieee802154/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 72e18d505d1a..b27e8633c305 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -66,7 +66,6 @@ obj-$(CONFIG_NET_SB1000) += sb1000.o obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_WLAN) += wireless/ -obj-$(CONFIG_WIMAX) += wimax/ obj-$(CONFIG_IEEE802154) += ieee802154/ obj-$(CONFIG_VMXNET3) += vmxnet3/ diff --git a/drivers/net/wimax/Kconfig b/drivers/net/wimax/Kconfig deleted file mode 100644 index 2249e3d77a76..000000000000 --- a/drivers/net/wimax/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# WiMAX LAN device drivers configuration -# - - -comment "Enable WiMAX (Networking options) to see the WiMAX drivers" - depends on WIMAX = n - -if WIMAX - -menu "WiMAX Wireless Broadband devices" - -source "drivers/net/wimax/i2400m/Kconfig" - -endmenu - -endif diff --git a/drivers/net/wimax/Makefile b/drivers/net/wimax/Makefile deleted file mode 100644 index b4575bacf994..000000000000 --- a/drivers/net/wimax/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_WIMAX_I2400M) += i2400m/ diff --git a/drivers/net/wimax/i2400m/Kconfig b/drivers/net/wimax/i2400m/Kconfig deleted file mode 100644 index 843b905a26a3..000000000000 --- a/drivers/net/wimax/i2400m/Kconfig +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -config WIMAX_I2400M - tristate - depends on WIMAX - select FW_LOADER - -comment "Enable USB support to see WiMAX USB drivers" - depends on USB = n - -config WIMAX_I2400M_USB - tristate "Intel Wireless WiMAX Connection 2400 over USB (including 5x50)" - depends on WIMAX && USB - select WIMAX_I2400M - help - Select if you have a device based on the Intel WiMAX - Connection 2400 over USB (like any of the Intel Wireless - WiMAX/WiFi Link 5x50 series). - - If unsure, it is safe to select M (module). - -config WIMAX_I2400M_DEBUG_LEVEL - int "WiMAX i2400m debug level" - depends on WIMAX_I2400M - default 8 - help - - Select the maximum debug verbosity level to be compiled into - the WiMAX i2400m driver code. - - By default, this is disabled at runtime and can be - selectively enabled at runtime for different parts of the - code using the sysfs debug-levels file. - - If set at zero, this will compile out all the debug code. - - It is recommended that it is left at 8. diff --git a/drivers/net/wimax/i2400m/Makefile b/drivers/net/wimax/i2400m/Makefile deleted file mode 100644 index b1db1eff0648..000000000000 --- a/drivers/net/wimax/i2400m/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -obj-$(CONFIG_WIMAX_I2400M) += i2400m.o -obj-$(CONFIG_WIMAX_I2400M_USB) += i2400m-usb.o - -i2400m-y := \ - control.o \ - driver.o \ - fw.o \ - op-rfkill.o \ - sysfs.o \ - netdev.o \ - tx.o \ - rx.o - -i2400m-$(CONFIG_DEBUG_FS) += debugfs.o - -i2400m-usb-y := \ - usb-fw.o \ - usb-notif.o \ - usb-tx.o \ - usb-rx.o \ - usb.o diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c deleted file mode 100644 index 8df98757d901..000000000000 --- a/drivers/net/wimax/i2400m/control.c +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * Intel Wireless WiMAX Connection 2400m - * Miscellaneous control functions for managing the device - * - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Intel Corporation - * Inaky Perez-Gonzalez - * - Initial implementation - * - * This is a collection of functions used to control the device (plus - * a few helpers). - * - * There are utilities for handling TLV buffers, hooks on the device's - * reports to act on device changes of state [i2400m_report_hook()], - * on acks to commands [i2400m_msg_ack_hook()], a helper for sending - * commands to the device and blocking until a reply arrives - * [i2400m_msg_to_dev()], a few high level commands for manipulating - * the device state, powersving mode and configuration plus the - * routines to setup the device once communication is stablished with - * it [i2400m_dev_initialize()]. - * - * ROADMAP - * - * i2400m_dev_initialize() Called by i2400m_dev_start() - * i2400m_set_init_config() - * i2400m_cmd_get_state() - * i2400m_dev_shutdown() Called by i2400m_dev_stop() - * i2400m_reset() - * - * i2400m_{cmd,get,set}_*() - * i2400m_msg_to_dev() - * i2400m_msg_check_status() - * - * i2400m_report_hook() Called on reception of an event - * i2400m_report_state_hook() - * i2400m_tlv_buffer_walk() - * i2400m_tlv_match() - * i2400m_report_tlv_system_state() - * i2400m_report_tlv_rf_switches_status() - * i2400m_report_tlv_media_status() - * i2400m_cmd_enter_powersave() - * - * i2400m_msg_ack_hook() Called on reception of a reply to a - * command, get or set - */ - -#include -#include "i2400m.h" -#include -#include -#include -#include -#include - - -#define D_SUBMODULE control -#include "debug-levels.h" - -static int i2400m_idle_mode_disabled;/* 0 (idle mode enabled) by default */ -module_param_named(idle_mode_disabled, i2400m_idle_mode_disabled, int, 0644); -MODULE_PARM_DESC(idle_mode_disabled, - "If true, the device will not enable idle mode negotiation " - "with the base station (when connected) to save power."); - -/* 0 (power saving enabled) by default */ -static int i2400m_power_save_disabled; -module_param_named(power_save_disabled, i2400m_power_save_disabled, int, 0644); -MODULE_PARM_DESC(power_save_disabled, - "If true, the driver will not tell the device to enter " - "power saving mode when it reports it is ready for it. " - "False by default (so the device is told to do power " - "saving)."); - -static int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ -module_param_named(passive_mode, i2400m_passive_mode, int, 0644); -MODULE_PARM_DESC(passive_mode, - "If true, the driver will not do any device setup " - "and leave it up to user space, who must be properly " - "setup."); - - -/* - * Return if a TLV is of a give type and size - * - * @tlv_hdr: pointer to the TLV - * @tlv_type: type of the TLV we are looking for - * @tlv_size: expected size of the TLV we are looking for (if -1, - * don't check the size). This includes the header - * Returns: 0 if the TLV matches - * < 0 if it doesn't match at all - * > 0 total TLV + payload size, if the type matches, but not - * the size - */ -static -ssize_t i2400m_tlv_match(const struct i2400m_tlv_hdr *tlv, - enum i2400m_tlv tlv_type, ssize_t tlv_size) -{ - if (le16_to_cpu(tlv->type) != tlv_type) /* Not our type? skip */ - return -1; - if (tlv_size != -1 - && le16_to_cpu(tlv->length) + sizeof(*tlv) != tlv_size) { - size_t size = le16_to_cpu(tlv->length) + sizeof(*tlv); - printk(KERN_WARNING "W: tlv type 0x%x mismatched because of " - "size (got %zu vs %zd expected)\n", - tlv_type, size, tlv_size); - return size; - } - return 0; -} - - -/* - * Given a buffer of TLVs, iterate over them - * - * @i2400m: device instance - * @tlv_buf: pointer to the beginning of the TLV buffer - * @buf_size: buffer size in bytes - * @tlv_pos: seek position; this is assumed to be a pointer returned - * by i2400m_tlv_buffer_walk() [and thus, validated]. The - * TLV returned will be the one following this one. - * - * Usage: - * - * tlv_itr = NULL; - * while (tlv_itr = i2400m_tlv_buffer_walk(i2400m, buf, size, tlv_itr)) { - * ... - * // Do stuff with tlv_itr, DON'T MODIFY IT - * ... - * } - */ -static -const struct i2400m_tlv_hdr *i2400m_tlv_buffer_walk( - struct i2400m *i2400m, - const void *tlv_buf, size_t buf_size, - const struct i2400m_tlv_hdr *tlv_pos) -{ - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_tlv_hdr *tlv_top = tlv_buf + buf_size; - size_t offset, length, avail_size; - unsigned type; - - if (tlv_pos == NULL) /* Take the first one? */ - tlv_pos = tlv_buf; - else /* Nope, the next one */ - tlv_pos = (void *) tlv_pos - + le16_to_cpu(tlv_pos->length) + sizeof(*tlv_pos); - if (tlv_pos == tlv_top) { /* buffer done */ - tlv_pos = NULL; - goto error_beyond_end; - } - if (tlv_pos > tlv_top) { - tlv_pos = NULL; - WARN_ON(1); - goto error_beyond_end; - } - offset = (void *) tlv_pos - (void *) tlv_buf; - avail_size = buf_size - offset; - if (avail_size < sizeof(*tlv_pos)) { - dev_err(dev, "HW BUG? tlv_buf %p [%zu bytes], tlv @%zu: " - "short header\n", tlv_buf, buf_size, offset); - goto error_short_header; - } - type = le16_to_cpu(tlv_pos->type); - length = le16_to_cpu(tlv_pos->length); - if (avail_size < sizeof(*tlv_pos) + length) { - dev_err(dev, "HW BUG? tlv_buf %p [%zu bytes], " - "tlv type 0x%04x @%zu: " - "short data (%zu bytes vs %zu needed)\n", - tlv_buf, buf_size, type, offset, avail_size, - sizeof(*tlv_pos) + length); - goto error_short_header; - } -error_short_header: -error_beyond_end: - return tlv_pos; -} - - -/* - * Find a TLV in a buffer of sequential TLVs - * - * @i2400m: device descriptor - * @tlv_hdr: pointer to the first TLV in the sequence - * @size: size of the buffer in bytes; all TLVs are assumed to fit - * fully in the buffer (otherwise we'll complain). - * @tlv_type: type of the TLV we are looking for - * @tlv_size: expected size of the TLV we are looking for (if -1, - * don't check the size). This includes the header - * - * Returns: NULL if the TLV is not found, otherwise a pointer to - * it. If the sizes don't match, an error is printed and NULL - * returned. - */ -static -const struct i2400m_tlv_hdr *i2400m_tlv_find( - struct i2400m *i2400m, - const struct i2400m_tlv_hdr *tlv_hdr, size_t size, - enum i2400m_tlv tlv_type, ssize_t tlv_size) -{ - ssize_t match; - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_tlv_hdr *tlv = NULL; - while ((tlv = i2400m_tlv_buffer_walk(i2400m, tlv_hdr, size, tlv))) { - match = i2400m_tlv_match(tlv, tlv_type, tlv_size); - if (match == 0) /* found it :) */ - break; - if (match > 0) - dev_warn(dev, "TLV type 0x%04x found with size " - "mismatch (%zu vs %zd needed)\n", - tlv_type, match, tlv_size); - } - return tlv; -} - - -static const struct -{ - char *msg; - int errno; -} ms_to_errno[I2400M_MS_MAX] = { - [I2400M_MS_DONE_OK] = { "", 0 }, - [I2400M_MS_DONE_IN_PROGRESS] = { "", 0 }, - [I2400M_MS_INVALID_OP] = { "invalid opcode", -ENOSYS }, - [I2400M_MS_BAD_STATE] = { "invalid state", -EILSEQ }, - [I2400M_MS_ILLEGAL_VALUE] = { "illegal value", -EINVAL }, - [I2400M_MS_MISSING_PARAMS] = { "missing parameters", -ENOMSG }, - [I2400M_MS_VERSION_ERROR] = { "bad version", -EIO }, - [I2400M_MS_ACCESSIBILITY_ERROR] = { "accesibility error", -EIO }, - [I2400M_MS_BUSY] = { "busy", -EBUSY }, - [I2400M_MS_CORRUPTED_TLV] = { "corrupted TLV", -EILSEQ }, - [I2400M_MS_UNINITIALIZED] = { "uninitialized", -EILSEQ }, - [I2400M_MS_UNKNOWN_ERROR] = { "unknown error", -EIO }, - [I2400M_MS_PRODUCTION_ERROR] = { "production error", -EIO }, - [I2400M_MS_NO_RF] = { "no RF", -EIO }, - [I2400M_MS_NOT_READY_FOR_POWERSAVE] = - { "not ready for powersave", -EACCES }, - [I2400M_MS_THERMAL_CRITICAL] = { "thermal critical", -EL3HLT }, -}; - - -/* - * i2400m_msg_check_status - translate a message's status code - * - * @i2400m: device descriptor - * @l3l4_hdr: message header - * @strbuf: buffer to place a formatted error message (unless NULL). - * @strbuf_size: max amount of available space; larger messages will - * be truncated. - * - * Returns: errno code corresponding to the status code in @l3l4_hdr - * and a message in @strbuf describing the error. - */ -int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *l3l4_hdr, - char *strbuf, size_t strbuf_size) -{ - int result; - enum i2400m_ms status = le16_to_cpu(l3l4_hdr->status); - const char *str; - - if (status == 0) - return 0; - if (status >= ARRAY_SIZE(ms_to_errno)) { - str = "unknown status code"; - result = -EBADR; - } else { - str = ms_to_errno[status].msg; - result = ms_to_errno[status].errno; - } - if (strbuf) - snprintf(strbuf, strbuf_size, "%s (%d)", str, status); - return result; -} - - -/* - * Act on a TLV System State reported by the device - * - * @i2400m: device descriptor - * @ss: validated System State TLV - */ -static -void i2400m_report_tlv_system_state(struct i2400m *i2400m, - const struct i2400m_tlv_system_state *ss) -{ - struct device *dev = i2400m_dev(i2400m); - struct wimax_dev *wimax_dev = &i2400m->wimax_dev; - enum i2400m_system_state i2400m_state = le32_to_cpu(ss->state); - - d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state); - - if (i2400m->state != i2400m_state) { - i2400m->state = i2400m_state; - wake_up_all(&i2400m->state_wq); - } - switch (i2400m_state) { - case I2400M_SS_UNINITIALIZED: - case I2400M_SS_INIT: - case I2400M_SS_CONFIG: - case I2400M_SS_PRODUCTION: - wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); - break; - - case I2400M_SS_RF_OFF: - case I2400M_SS_RF_SHUTDOWN: - wimax_state_change(wimax_dev, WIMAX_ST_RADIO_OFF); - break; - - case I2400M_SS_READY: - case I2400M_SS_STANDBY: - case I2400M_SS_SLEEPACTIVE: - wimax_state_change(wimax_dev, WIMAX_ST_READY); - break; - - case I2400M_SS_CONNECTING: - case I2400M_SS_WIMAX_CONNECTED: - wimax_state_change(wimax_dev, WIMAX_ST_READY); - break; - - case I2400M_SS_SCAN: - case I2400M_SS_OUT_OF_ZONE: - wimax_state_change(wimax_dev, WIMAX_ST_SCANNING); - break; - - case I2400M_SS_IDLE: - d_printf(1, dev, "entering BS-negotiated idle mode\n"); - fallthrough; - case I2400M_SS_DISCONNECTING: - case I2400M_SS_DATA_PATH_CONNECTED: - wimax_state_change(wimax_dev, WIMAX_ST_CONNECTED); - break; - - default: - /* Huh? just in case, shut it down */ - dev_err(dev, "HW BUG? unknown state %u: shutting down\n", - i2400m_state); - i2400m_reset(i2400m, I2400M_RT_WARM); - break; - } - d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", - i2400m, ss, i2400m_state); -} - - -/* - * Parse and act on a TLV Media Status sent by the device - * - * @i2400m: device descriptor - * @ms: validated Media Status TLV - * - * This will set the carrier up on down based on the device's link - * report. This is done asides of what the WiMAX stack does based on - * the device's state as sometimes we need to do a link-renew (the BS - * wants us to renew a DHCP lease, for example). - * - * In fact, doc says that every time we get a link-up, we should do a - * DHCP negotiation... - */ -static -void i2400m_report_tlv_media_status(struct i2400m *i2400m, - const struct i2400m_tlv_media_status *ms) -{ - struct device *dev = i2400m_dev(i2400m); - struct wimax_dev *wimax_dev = &i2400m->wimax_dev; - struct net_device *net_dev = wimax_dev->net_dev; - enum i2400m_media_status status = le32_to_cpu(ms->media_status); - - d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status); - - switch (status) { - case I2400M_MEDIA_STATUS_LINK_UP: - netif_carrier_on(net_dev); - break; - case I2400M_MEDIA_STATUS_LINK_DOWN: - netif_carrier_off(net_dev); - break; - /* - * This is the network telling us we need to retrain the DHCP - * lease -- so far, we are trusting the WiMAX Network Service - * in user space to pick this up and poke the DHCP client. - */ - case I2400M_MEDIA_STATUS_LINK_RENEW: - netif_carrier_on(net_dev); - break; - default: - dev_err(dev, "HW BUG? unknown media status %u\n", - status); - } - d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n", - i2400m, ms, status); -} - - -/* - * Process a TLV from a 'state report' - * - * @i2400m: device descriptor - * @tlv: pointer to the TLV header; it has been already validated for - * consistent size. - * @tag: for error messages - * - * Act on the TLVs from a 'state report'. - */ -static -void i2400m_report_state_parse_tlv(struct i2400m *i2400m, - const struct i2400m_tlv_hdr *tlv, - const char *tag) -{ - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_tlv_media_status *ms; - const struct i2400m_tlv_system_state *ss; - const struct i2400m_tlv_rf_switches_status *rfss; - - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) { - ss = container_of(tlv, typeof(*ss), hdr); - d_printf(2, dev, "%s: system state TLV " - "found (0x%04x), state 0x%08x\n", - tag, I2400M_TLV_SYSTEM_STATE, - le32_to_cpu(ss->state)); - i2400m_report_tlv_system_state(i2400m, ss); - } - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) { - rfss = container_of(tlv, typeof(*rfss), hdr); - d_printf(2, dev, "%s: RF status TLV " - "found (0x%04x), sw 0x%02x hw 0x%02x\n", - tag, I2400M_TLV_RF_STATUS, - le32_to_cpu(rfss->sw_rf_switch), - le32_to_cpu(rfss->hw_rf_switch)); - i2400m_report_tlv_rf_switches_status(i2400m, rfss); - } - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) { - ms = container_of(tlv, typeof(*ms), hdr); - d_printf(2, dev, "%s: Media Status TLV: %u\n", - tag, le32_to_cpu(ms->media_status)); - i2400m_report_tlv_media_status(i2400m, ms); - } -} - - -/* - * Parse a 'state report' and extract information - * - * @i2400m: device descriptor - * @l3l4_hdr: pointer to message; it has been already validated for - * consistent size. - * @size: size of the message (header + payload). The header length - * declaration is assumed to be congruent with @size (as in - * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) - * - * Walk over the TLVs in a report state and act on them. - */ -static -void i2400m_report_state_hook(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, - size_t size, const char *tag) -{ - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_tlv_hdr *tlv; - size_t tlv_size = le16_to_cpu(l3l4_hdr->length); - - d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n", - i2400m, l3l4_hdr, size, tag); - tlv = NULL; - - while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl, - tlv_size, tlv))) - i2400m_report_state_parse_tlv(i2400m, tlv, tag); - d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n", - i2400m, l3l4_hdr, size, tag); -} - - -/* - * i2400m_report_hook - (maybe) act on a report - * - * @i2400m: device descriptor - * @l3l4_hdr: pointer to message; it has been already validated for - * consistent size. - * @size: size of the message (header + payload). The header length - * declaration is assumed to be congruent with @size (as in - * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) - * - * Extract information we might need (like carrien on/off) from a - * device report. - */ -void i2400m_report_hook(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) -{ - struct device *dev = i2400m_dev(i2400m); - unsigned msg_type; - - d_fnstart(3, dev, "(i2400m %p l3l4_hdr %p size %zu)\n", - i2400m, l3l4_hdr, size); - /* Chew on the message, we might need some information from - * here */ - msg_type = le16_to_cpu(l3l4_hdr->type); - switch (msg_type) { - case I2400M_MT_REPORT_STATE: /* carrier detection... */ - i2400m_report_state_hook(i2400m, - l3l4_hdr, size, "REPORT STATE"); - break; - /* If the device is ready for power save, then ask it to do - * it. */ - case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ - if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { - if (i2400m_power_save_disabled) - d_printf(1, dev, "ready for powersave, " - "not requesting (disabled by module " - "parameter)\n"); - else { - d_printf(1, dev, "ready for powersave, " - "requesting\n"); - i2400m_cmd_enter_powersave(i2400m); - } - } - break; - } - d_fnend(3, dev, "(i2400m %p l3l4_hdr %p size %zu) = void\n", - i2400m, l3l4_hdr, size); -} - - -/* - * i2400m_msg_ack_hook - process cmd/set/get ack for internal status - * - * @i2400m: device descriptor - * @l3l4_hdr: pointer to message; it has been already validated for - * consistent size. - * @size: size of the message - * - * Extract information we might need from acks to commands and act on - * it. This is akin to i2400m_report_hook(). Note most of this - * processing should be done in the function that calls the - * command. This is here for some cases where it can't happen... - */ -static void i2400m_msg_ack_hook(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, - size_t size) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - unsigned int ack_type; - char strerr[32]; - - /* Chew on the message, we might need some information from - * here */ - ack_type = le16_to_cpu(l3l4_hdr->type); - switch (ack_type) { - case I2400M_MT_CMD_ENTER_POWERSAVE: - /* This is just left here for the sake of example, as - * the processing is done somewhere else. */ - if (0) { - result = i2400m_msg_check_status( - l3l4_hdr, strerr, sizeof(strerr)); - if (result >= 0) - d_printf(1, dev, "ready for power save: %zd\n", - size); - } - break; - } -} - - -/* - * i2400m_msg_size_check() - verify message size and header are congruent - * - * It is ok if the total message size is larger than the expected - * size, as there can be padding. - */ -int i2400m_msg_size_check(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, - size_t msg_size) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - size_t expected_size; - d_fnstart(4, dev, "(i2400m %p l3l4_hdr %p msg_size %zu)\n", - i2400m, l3l4_hdr, msg_size); - if (msg_size < sizeof(*l3l4_hdr)) { - dev_err(dev, "bad size for message header " - "(expected at least %zu, got %zu)\n", - (size_t) sizeof(*l3l4_hdr), msg_size); - result = -EIO; - goto error_hdr_size; - } - expected_size = le16_to_cpu(l3l4_hdr->length) + sizeof(*l3l4_hdr); - if (msg_size < expected_size) { - dev_err(dev, "bad size for message code 0x%04x (expected %zu, " - "got %zu)\n", le16_to_cpu(l3l4_hdr->type), - expected_size, msg_size); - result = -EIO; - } else - result = 0; -error_hdr_size: - d_fnend(4, dev, - "(i2400m %p l3l4_hdr %p msg_size %zu) = %d\n", - i2400m, l3l4_hdr, msg_size, result); - return result; -} - - - -/* - * Cancel a wait for a command ACK - * - * @i2400m: device descriptor - * @code: [negative] errno code to cancel with (don't use - * -EINPROGRESS) - * - * If there is an ack already filled out, free it. - */ -void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code) -{ - struct sk_buff *ack_skb; - unsigned long flags; - - spin_lock_irqsave(&i2400m->rx_lock, flags); - ack_skb = i2400m->ack_skb; - if (ack_skb && !IS_ERR(ack_skb)) - kfree_skb(ack_skb); - i2400m->ack_skb = ERR_PTR(code); - spin_unlock_irqrestore(&i2400m->rx_lock, flags); -} - - -/** - * i2400m_msg_to_dev - Send a control message to the device and get a response - * - * @i2400m: device descriptor - * - * @buf: pointer to the buffer containing the message to be sent; it - * has to start with a &struct i2400M_l3l4_hdr and then - * followed by the payload. Once this function returns, the - * buffer can be reused. - * - * @buf_len: buffer size - * - * Returns: - * - * Pointer to skb containing the ack message. You need to check the - * pointer with IS_ERR(), as it might be an error code. Error codes - * could happen because: - * - * - the message wasn't formatted correctly - * - couldn't send the message - * - failed waiting for a response - * - the ack message wasn't formatted correctly - * - * The returned skb has been allocated with wimax_msg_to_user_alloc(), - * it contains the response in a netlink attribute and is ready to be - * passed up to user space with wimax_msg_to_user_send(). To access - * the payload and its length, use wimax_msg_{data,len}() on the skb. - * - * The skb has to be freed with kfree_skb() once done. - * - * Description: - * - * This function delivers a message/command to the device and waits - * for an ack to be received. The format is described in - * linux/wimax/i2400m.h. In summary, a command/get/set is followed by an - * ack. - * - * This function will not check the ack status, that's left up to the - * caller. Once done with the ack skb, it has to be kfree_skb()ed. - * - * The i2400m handles only one message at the same time, thus we need - * the mutex to exclude other players. - * - * We write the message and then wait for an answer to come back. The - * RX path intercepts control messages and handles them in - * i2400m_rx_ctl(). Reports (notifications) are (maybe) processed - * locally and then forwarded (as needed) to user space on the WiMAX - * stack message pipe. Acks are saved and passed back to us through an - * skb in i2400m->ack_skb which is ready to be given to generic - * netlink if need be. - */ -struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m, - const void *buf, size_t buf_len) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_l3l4_hdr *msg_l3l4_hdr; - struct sk_buff *ack_skb; - const struct i2400m_l3l4_hdr *ack_l3l4_hdr; - size_t ack_len; - int ack_timeout; - unsigned msg_type; - unsigned long flags; - - d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n", - i2400m, buf, buf_len); - - rmb(); /* Make sure we see what i2400m_dev_reset_handle() */ - if (i2400m->boot_mode) - return ERR_PTR(-EL3RST); - - msg_l3l4_hdr = buf; - /* Check msg & payload consistency */ - result = i2400m_msg_size_check(i2400m, msg_l3l4_hdr, buf_len); - if (result < 0) - goto error_bad_msg; - msg_type = le16_to_cpu(msg_l3l4_hdr->type); - d_printf(1, dev, "CMD/GET/SET 0x%04x %zu bytes\n", - msg_type, buf_len); - d_dump(2, dev, buf, buf_len); - - /* Setup the completion, ack_skb ("we are waiting") and send - * the message to the device */ - mutex_lock(&i2400m->msg_mutex); - spin_lock_irqsave(&i2400m->rx_lock, flags); - i2400m->ack_skb = ERR_PTR(-EINPROGRESS); - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - init_completion(&i2400m->msg_completion); - result = i2400m_tx(i2400m, buf, buf_len, I2400M_PT_CTRL); - if (result < 0) { - dev_err(dev, "can't send message 0x%04x: %d\n", - le16_to_cpu(msg_l3l4_hdr->type), result); - goto error_tx; - } - - /* Some commands take longer to execute because of crypto ops, - * so we give them some more leeway on timeout */ - switch (msg_type) { - case I2400M_MT_GET_TLS_OPERATION_RESULT: - case I2400M_MT_CMD_SEND_EAP_RESPONSE: - ack_timeout = 5 * HZ; - break; - default: - ack_timeout = HZ; - } - - if (unlikely(i2400m->trace_msg_from_user)) - wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL); - /* The RX path in rx.c will put any response for this message - * in i2400m->ack_skb and wake us up. If we cancel the wait, - * we need to change the value of i2400m->ack_skb to something - * not -EINPROGRESS so RX knows there is no one waiting. */ - result = wait_for_completion_interruptible_timeout( - &i2400m->msg_completion, ack_timeout); - if (result == 0) { - dev_err(dev, "timeout waiting for reply to message 0x%04x\n", - msg_type); - result = -ETIMEDOUT; - i2400m_msg_to_dev_cancel_wait(i2400m, result); - goto error_wait_for_completion; - } else if (result < 0) { - dev_err(dev, "error waiting for reply to message 0x%04x: %d\n", - msg_type, result); - i2400m_msg_to_dev_cancel_wait(i2400m, result); - goto error_wait_for_completion; - } - - /* Pull out the ack data from i2400m->ack_skb -- see if it is - * an error and act accordingly */ - spin_lock_irqsave(&i2400m->rx_lock, flags); - ack_skb = i2400m->ack_skb; - if (IS_ERR(ack_skb)) - result = PTR_ERR(ack_skb); - else - result = 0; - i2400m->ack_skb = NULL; - spin_unlock_irqrestore(&i2400m->rx_lock, flags); - if (result < 0) - goto error_ack_status; - ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len); - - /* Check the ack and deliver it if it is ok */ - if (unlikely(i2400m->trace_msg_from_user)) - wimax_msg(&i2400m->wimax_dev, "echo", - ack_l3l4_hdr, ack_len, GFP_KERNEL); - result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len); - if (result < 0) { - dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n", - msg_type, result); - goto error_bad_ack_len; - } - if (msg_type != le16_to_cpu(ack_l3l4_hdr->type)) { - dev_err(dev, "HW BUG? bad reply 0x%04x to message 0x%04x\n", - le16_to_cpu(ack_l3l4_hdr->type), msg_type); - result = -EIO; - goto error_bad_ack_type; - } - i2400m_msg_ack_hook(i2400m, ack_l3l4_hdr, ack_len); - mutex_unlock(&i2400m->msg_mutex); - d_fnend(3, dev, "(i2400m %p buf %p len %zu) = %p\n", - i2400m, buf, buf_len, ack_skb); - return ack_skb; - -error_bad_ack_type: -error_bad_ack_len: - kfree_skb(ack_skb); -error_ack_status: -error_wait_for_completion: -error_tx: - mutex_unlock(&i2400m->msg_mutex); -error_bad_msg: - d_fnend(3, dev, "(i2400m %p buf %p len %zu) = %d\n", - i2400m, buf, buf_len, result); - return ERR_PTR(result); -} - - -/* - * Definitions for the Enter Power Save command - * - * The Enter Power Save command requests the device to go into power - * saving mode. The device will ack or nak the command depending on it - * being ready for it. If it acks, we tell the USB subsystem to - * - * As well, the device might request to go into power saving mode by - * sending a report (REPORT_POWERSAVE_READY), in which case, we issue - * this command. The hookups in the RX coder allow - */ -enum { - I2400M_WAKEUP_ENABLED = 0x01, - I2400M_WAKEUP_DISABLED = 0x02, - I2400M_TLV_TYPE_WAKEUP_MODE = 144, -}; - -struct i2400m_cmd_enter_power_save { - struct i2400m_l3l4_hdr hdr; - struct i2400m_tlv_hdr tlv; - __le32 val; -} __packed; - - -/* - * Request entering power save - * - * This command is (mainly) executed when the device indicates that it - * is ready to go into powersave mode via a REPORT_POWERSAVE_READY. - */ -int i2400m_cmd_enter_powersave(struct i2400m *i2400m) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - struct sk_buff *ack_skb; - struct i2400m_cmd_enter_power_save *cmd; - char strerr[32]; - - result = -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (cmd == NULL) - goto error_alloc; - cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_ENTER_POWERSAVE); - cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr)); - cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); - cmd->tlv.type = cpu_to_le16(I2400M_TLV_TYPE_WAKEUP_MODE); - cmd->tlv.length = cpu_to_le16(sizeof(cmd->val)); - cmd->val = cpu_to_le32(I2400M_WAKEUP_ENABLED); - - ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); - result = PTR_ERR(ack_skb); - if (IS_ERR(ack_skb)) { - dev_err(dev, "Failed to issue 'Enter power save' command: %d\n", - result); - goto error_msg_to_dev; - } - result = i2400m_msg_check_status(wimax_msg_data(ack_skb), - strerr, sizeof(strerr)); - if (result == -EACCES) - d_printf(1, dev, "Cannot enter power save mode\n"); - else if (result < 0) - dev_err(dev, "'Enter power save' (0x%04x) command failed: " - "%d - %s\n", I2400M_MT_CMD_ENTER_POWERSAVE, - result, strerr); - else - d_printf(1, dev, "device ready to power save\n"); - kfree_skb(ack_skb); -error_msg_to_dev: - kfree(cmd); -error_alloc: - return result; -} -EXPORT_SYMBOL_GPL(i2400m_cmd_enter_powersave); - - -/* - * Definitions for getting device information - */ -enum { - I2400M_TLV_DETAILED_DEVICE_INFO = 140 -}; - -/** - * i2400m_get_device_info - Query the device for detailed device information - * - * @i2400m: device descriptor - * - * Returns: an skb whose skb->data points to a 'struct - * i2400m_tlv_detailed_device_info'. When done, kfree_skb() it. The - * skb is *guaranteed* to contain the whole TLV data structure. - * - * On error, IS_ERR(skb) is true and ERR_PTR(skb) is the error - * code. - */ -struct sk_buff *i2400m_get_device_info(struct i2400m *i2400m) -{ - int result; - struct device *dev = i2400m_dev(i2400m); - struct sk_buff *ack_skb; - struct i2400m_l3l4_hdr *cmd; - const struct i2400m_l3l4_hdr *ack; - size_t ack_len; - const struct i2400m_tlv_hdr *tlv; - const struct i2400m_tlv_detailed_device_info *ddi; - char strerr[32]; - - ack_skb = ERR_PTR(-ENOMEM); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (cmd == NULL) - goto error_alloc; - cmd->type = cpu_to_le16(I2400M_MT_GET_DEVICE_INFO); - cmd->length = 0; - cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); - - ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); - if (IS_ERR(ack_skb)) { - dev_err(dev, "Failed to issue 'get device info' command: %ld\n", - PTR_ERR(ack_skb)); - goto error_msg_to_dev; - } - ack = wimax_msg_data_len(ack_skb, &ack_len); - result = i2400m_msg_check_status(ack, strerr, sizeof(strerr)); - if (result < 0) { - dev_err(dev, "'get device info' (0x%04x) command failed: " - "%d - %s\n", I2400M_MT_GET_DEVICE_INFO, result, - strerr); - goto error_cmd_failed; - } - tlv = i2400m_tlv_find(i2400m, ack->pl, ack_len - sizeof(*ack), - I2400M_TLV_DETAILED_DEVICE_INFO, sizeof(*ddi)); - if (tlv == NULL) { - dev_err(dev, "GET DEVICE INFO: " - "detailed device info TLV not found (0x%04x)\n", - I2400M_TLV_DETAILED_DEVICE_INFO); - result = -EIO; - goto error_no_tlv; - } - skb_pull(ack_skb, (void *) tlv - (void *) ack_skb->da