18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Linux WiMAX
48c2ecf20Sopenharmony_ci * Kernel space API for accessing WiMAX devices
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2007-2008 Intel Corporation <linux-wimax@intel.com>
78c2ecf20Sopenharmony_ci * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * The WiMAX stack provides an API for controlling and managing the
108c2ecf20Sopenharmony_ci * system's WiMAX devices. This API affects the control plane; the
118c2ecf20Sopenharmony_ci * data plane is accessed via the network stack (netdev).
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Parts of the WiMAX stack API and notifications are exported to
148c2ecf20Sopenharmony_ci * user space via Generic Netlink. In user space, libwimax (part of
158c2ecf20Sopenharmony_ci * the wimax-tools package) provides a shim layer for accessing those
168c2ecf20Sopenharmony_ci * calls.
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * The API is standarized for all WiMAX devices and different drivers
198c2ecf20Sopenharmony_ci * implement the backend support for it. However, device-specific
208c2ecf20Sopenharmony_ci * messaging pipes are provided that can be used to issue commands and
218c2ecf20Sopenharmony_ci * receive notifications in free form.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * Currently the messaging pipes are the only means of control as it
248c2ecf20Sopenharmony_ci * is not known (due to the lack of more devices in the market) what
258c2ecf20Sopenharmony_ci * will be a good abstraction layer. Expect this to change as more
268c2ecf20Sopenharmony_ci * devices show in the market. This API is designed to be growable in
278c2ecf20Sopenharmony_ci * order to address this problem.
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci * USAGE
308c2ecf20Sopenharmony_ci *
318c2ecf20Sopenharmony_ci * Embed a `struct wimax_dev` at the beginning of the device's
328c2ecf20Sopenharmony_ci * private structure, initialize and register it. For details, see
338c2ecf20Sopenharmony_ci * `struct wimax_dev`s documentation.
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * Once this is done, wimax-tools's libwimaxll can be used to
368c2ecf20Sopenharmony_ci * communicate with the driver from user space. You user space
378c2ecf20Sopenharmony_ci * application does not have to forcibily use libwimaxll and can talk
388c2ecf20Sopenharmony_ci * the generic netlink protocol directly if desired.
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci * Remember this is a very low level API that will to provide all of
418c2ecf20Sopenharmony_ci * WiMAX features. Other daemons and services running in user space
428c2ecf20Sopenharmony_ci * are the expected clients of it. They offer a higher level API that
438c2ecf20Sopenharmony_ci * applications should use (an example of this is the Intel's WiMAX
448c2ecf20Sopenharmony_ci * Network Service for the i2400m).
458c2ecf20Sopenharmony_ci *
468c2ecf20Sopenharmony_ci * DESIGN
478c2ecf20Sopenharmony_ci *
488c2ecf20Sopenharmony_ci * Although not set on final stone, this very basic interface is
498c2ecf20Sopenharmony_ci * mostly completed. Remember this is meant to grow as new common
508c2ecf20Sopenharmony_ci * operations are decided upon. New operations will be added to the
518c2ecf20Sopenharmony_ci * interface, intent being on keeping backwards compatibility as much
528c2ecf20Sopenharmony_ci * as possible.
538c2ecf20Sopenharmony_ci *
548c2ecf20Sopenharmony_ci * This layer implements a set of calls to control a WiMAX device,
558c2ecf20Sopenharmony_ci * exposing a frontend to the rest of the kernel and user space (via
568c2ecf20Sopenharmony_ci * generic netlink) and a backend implementation in the driver through
578c2ecf20Sopenharmony_ci * function pointers.
588c2ecf20Sopenharmony_ci *
598c2ecf20Sopenharmony_ci * WiMAX devices have a state, and a kernel-only API allows the
608c2ecf20Sopenharmony_ci * drivers to manipulate that state. State transitions are atomic, and
618c2ecf20Sopenharmony_ci * only some of them are allowed (see `enum wimax_st`).
628c2ecf20Sopenharmony_ci *
638c2ecf20Sopenharmony_ci * Most API calls will set the state automatically; in most cases
648c2ecf20Sopenharmony_ci * drivers have to only report state changes due to external
658c2ecf20Sopenharmony_ci * conditions.
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * All API operations are 'atomic', serialized through a mutex in the
688c2ecf20Sopenharmony_ci * `struct wimax_dev`.
698c2ecf20Sopenharmony_ci *
708c2ecf20Sopenharmony_ci * EXPORTING TO USER SPACE THROUGH GENERIC NETLINK
718c2ecf20Sopenharmony_ci *
728c2ecf20Sopenharmony_ci * The API is exported to user space using generic netlink (other
738c2ecf20Sopenharmony_ci * methods can be added as needed).
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * There is a Generic Netlink Family named "WiMAX", where interfaces
768c2ecf20Sopenharmony_ci * supporting the WiMAX interface receive commands and broadcast their
778c2ecf20Sopenharmony_ci * signals over a multicast group named "msg".
788c2ecf20Sopenharmony_ci *
798c2ecf20Sopenharmony_ci * Mapping to the source/destination interface is done by an interface
808c2ecf20Sopenharmony_ci * index attribute.
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci * For user-to-kernel traffic (commands) we use a function call
838c2ecf20Sopenharmony_ci * marshalling mechanism, where a message X with attributes A, B, C
848c2ecf20Sopenharmony_ci * sent from user space to kernel space means executing the WiMAX API
858c2ecf20Sopenharmony_ci * call wimax_X(A, B, C), sending the results back as a message.
868c2ecf20Sopenharmony_ci *
878c2ecf20Sopenharmony_ci * Kernel-to-user (notifications or signals) communication is sent
888c2ecf20Sopenharmony_ci * over multicast groups. This allows to have multiple applications
898c2ecf20Sopenharmony_ci * monitoring them.
908c2ecf20Sopenharmony_ci *
918c2ecf20Sopenharmony_ci * Each command/signal gets assigned it's own attribute policy. This
928c2ecf20Sopenharmony_ci * way the validator will verify that all the attributes in there are
938c2ecf20Sopenharmony_ci * only the ones that should be for each command/signal. Thing of an
948c2ecf20Sopenharmony_ci * attribute mapping to a type+argumentname for each command/signal.
958c2ecf20Sopenharmony_ci *
968c2ecf20Sopenharmony_ci * If we had a single policy for *all* commands/signals, after running
978c2ecf20Sopenharmony_ci * the validator we'd have to check "does this attribute belong in
988c2ecf20Sopenharmony_ci * here"?  for each one. It can be done manually, but it's just easier
998c2ecf20Sopenharmony_ci * to have the validator do that job with multiple policies. As well,
1008c2ecf20Sopenharmony_ci * it makes it easier to later expand each command/signal signature
1018c2ecf20Sopenharmony_ci * without affecting others and keeping the namespace more or less
1028c2ecf20Sopenharmony_ci * sane. Not that it is too complicated, but it makes it even easier.
1038c2ecf20Sopenharmony_ci *
1048c2ecf20Sopenharmony_ci * No state information is maintained in the kernel for each user
1058c2ecf20Sopenharmony_ci * space connection (the connection is stateless).
1068c2ecf20Sopenharmony_ci *
1078c2ecf20Sopenharmony_ci * TESTING FOR THE INTERFACE AND VERSIONING
1088c2ecf20Sopenharmony_ci *
1098c2ecf20Sopenharmony_ci * If network interface X is a WiMAX device, there will be a Generic
1108c2ecf20Sopenharmony_ci * Netlink family named "WiMAX X" and the device will present a
1118c2ecf20Sopenharmony_ci * "wimax" directory in it's network sysfs directory
1128c2ecf20Sopenharmony_ci * (/sys/class/net/DEVICE/wimax) [used by HAL].
1138c2ecf20Sopenharmony_ci *
1148c2ecf20Sopenharmony_ci * The inexistence of any of these means the device does not support
1158c2ecf20Sopenharmony_ci * this WiMAX API.
1168c2ecf20Sopenharmony_ci *
1178c2ecf20Sopenharmony_ci * By querying the generic netlink controller, versioning information
1188c2ecf20Sopenharmony_ci * and the multicast groups available can be found. Applications using
1198c2ecf20Sopenharmony_ci * the interface can either rely on that or use the generic netlink
1208c2ecf20Sopenharmony_ci * controller to figure out which generic netlink commands/signals are
1218c2ecf20Sopenharmony_ci * supported.
1228c2ecf20Sopenharmony_ci *
1238c2ecf20Sopenharmony_ci * NOTE: this versioning is a last resort to avoid hard
1248c2ecf20Sopenharmony_ci *    incompatibilities. It is the intention of the design of this
1258c2ecf20Sopenharmony_ci *    stack not to introduce backward incompatible changes.
1268c2ecf20Sopenharmony_ci *
1278c2ecf20Sopenharmony_ci * The version code has to fit in one byte (restrictions imposed by
1288c2ecf20Sopenharmony_ci * generic netlink); we use `version / 10` for the major version and
1298c2ecf20Sopenharmony_ci * `version % 10` for the minor. This gives 9 minors for each major
1308c2ecf20Sopenharmony_ci * and 25 majors.
1318c2ecf20Sopenharmony_ci *
1328c2ecf20Sopenharmony_ci * The version change protocol is as follow:
1338c2ecf20Sopenharmony_ci *
1348c2ecf20Sopenharmony_ci * - Major versions: needs to be increased if an existing message/API
1358c2ecf20Sopenharmony_ci *   call is changed or removed. Doesn't need to be changed if a new
1368c2ecf20Sopenharmony_ci *   message is added.
1378c2ecf20Sopenharmony_ci *
1388c2ecf20Sopenharmony_ci * - Minor version: needs to be increased if new messages/API calls are
1398c2ecf20Sopenharmony_ci *   being added or some other consideration that doesn't impact the
1408c2ecf20Sopenharmony_ci *   user-kernel interface too much (like some kind of bug fix) and
1418c2ecf20Sopenharmony_ci *   that is kind of left up in the air to common sense.
1428c2ecf20Sopenharmony_ci *
1438c2ecf20Sopenharmony_ci * User space code should not try to work if the major version it was
1448c2ecf20Sopenharmony_ci * compiled for differs from what the kernel offers. As well, if the
1458c2ecf20Sopenharmony_ci * minor version of the kernel interface is lower than the one user
1468c2ecf20Sopenharmony_ci * space is expecting (the one it was compiled for), the kernel
1478c2ecf20Sopenharmony_ci * might be missing API calls; user space shall be ready to handle
1488c2ecf20Sopenharmony_ci * said condition. Use the generic netlink controller operations to
1498c2ecf20Sopenharmony_ci * find which ones are supported and which not.
1508c2ecf20Sopenharmony_ci *
1518c2ecf20Sopenharmony_ci * libwimaxll:wimaxll_open() takes care of checking versions.
1528c2ecf20Sopenharmony_ci *
1538c2ecf20Sopenharmony_ci * THE OPERATIONS:
1548c2ecf20Sopenharmony_ci *
1558c2ecf20Sopenharmony_ci * Each operation is defined in its on file (drivers/net/wimax/op-*.c)
1568c2ecf20Sopenharmony_ci * for clarity. The parts needed for an operation are:
1578c2ecf20Sopenharmony_ci *
1588c2ecf20Sopenharmony_ci *  - a function pointer in `struct wimax_dev`: optional, as the
1598c2ecf20Sopenharmony_ci *    operation might be implemented by the stack and not by the
1608c2ecf20Sopenharmony_ci *    driver.
1618c2ecf20Sopenharmony_ci *
1628c2ecf20Sopenharmony_ci *    All function pointers are named wimax_dev->op_*(), and drivers
1638c2ecf20Sopenharmony_ci *    must implement them except where noted otherwise.
1648c2ecf20Sopenharmony_ci *
1658c2ecf20Sopenharmony_ci *  - When exported to user space, a `struct nla_policy` to define the
1668c2ecf20Sopenharmony_ci *    attributes of the generic netlink command and a `struct genl_ops`
1678c2ecf20Sopenharmony_ci *    to define the operation.
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci * All the declarations for the operation codes (WIMAX_GNL_OP_<NAME>)
1708c2ecf20Sopenharmony_ci * and generic netlink attributes (WIMAX_GNL_<NAME>_*) are declared in
1718c2ecf20Sopenharmony_ci * include/linux/wimax.h; this file is intended to be cloned by user
1728c2ecf20Sopenharmony_ci * space to gain access to those declarations.
1738c2ecf20Sopenharmony_ci *
1748c2ecf20Sopenharmony_ci * A few caveats to remember:
1758c2ecf20Sopenharmony_ci *
1768c2ecf20Sopenharmony_ci *  - Need to define attribute numbers starting in 1; otherwise it
1778c2ecf20Sopenharmony_ci *    fails.
1788c2ecf20Sopenharmony_ci *
1798c2ecf20Sopenharmony_ci *  - the `struct genl_family` requires a maximum attribute id; when
1808c2ecf20Sopenharmony_ci *    defining the `struct nla_policy` for each message, it has to have
1818c2ecf20Sopenharmony_ci *    an array size of WIMAX_GNL_ATTR_MAX+1.
1828c2ecf20Sopenharmony_ci *
1838c2ecf20Sopenharmony_ci * The op_*() function pointers will not be called if the wimax_dev is
1848c2ecf20Sopenharmony_ci * in a state <= %WIMAX_ST_UNINITIALIZED. The exception is:
1858c2ecf20Sopenharmony_ci *
1868c2ecf20Sopenharmony_ci * - op_reset: can be called at any time after wimax_dev_add() has
1878c2ecf20Sopenharmony_ci *   been called.
1888c2ecf20Sopenharmony_ci *
1898c2ecf20Sopenharmony_ci * THE PIPE INTERFACE:
1908c2ecf20Sopenharmony_ci *
1918c2ecf20Sopenharmony_ci * This interface is kept intentionally simple. The driver can send
1928c2ecf20Sopenharmony_ci * and receive free-form messages to/from user space through a
1938c2ecf20Sopenharmony_ci * pipe. See drivers/net/wimax/op-msg.c for details.
1948c2ecf20Sopenharmony_ci *
1958c2ecf20Sopenharmony_ci * The kernel-to-user messages are sent with
1968c2ecf20Sopenharmony_ci * wimax_msg(). user-to-kernel messages are delivered via
1978c2ecf20Sopenharmony_ci * wimax_dev->op_msg_from_user().
1988c2ecf20Sopenharmony_ci *
1998c2ecf20Sopenharmony_ci * RFKILL:
2008c2ecf20Sopenharmony_ci *
2018c2ecf20Sopenharmony_ci * RFKILL support is built into the wimax_dev layer; the driver just
2028c2ecf20Sopenharmony_ci * needs to call wimax_report_rfkill_{hw,sw}() to inform of changes in
2038c2ecf20Sopenharmony_ci * the hardware or software RF kill switches. When the stack wants to
2048c2ecf20Sopenharmony_ci * turn the radio off, it will call wimax_dev->op_rfkill_sw_toggle(),
2058c2ecf20Sopenharmony_ci * which the driver implements.
2068c2ecf20Sopenharmony_ci *
2078c2ecf20Sopenharmony_ci * User space can set the software RF Kill switch by calling
2088c2ecf20Sopenharmony_ci * wimax_rfkill().
2098c2ecf20Sopenharmony_ci *
2108c2ecf20Sopenharmony_ci * The code for now only supports devices that don't require polling;
2118c2ecf20Sopenharmony_ci * If the device needs to be polled, create a self-rearming delayed
2128c2ecf20Sopenharmony_ci * work struct for polling or look into adding polled support to the
2138c2ecf20Sopenharmony_ci * WiMAX stack.
2148c2ecf20Sopenharmony_ci *
2158c2ecf20Sopenharmony_ci * When initializing the hardware (_probe), after calling
2168c2ecf20Sopenharmony_ci * wimax_dev_add(), query the device for it's RF Kill switches status
2178c2ecf20Sopenharmony_ci * and feed it back to the WiMAX stack using
2188c2ecf20Sopenharmony_ci * wimax_report_rfkill_{hw,sw}(). If any switch is missing, always
2198c2ecf20Sopenharmony_ci * report it as ON.
2208c2ecf20Sopenharmony_ci *
2218c2ecf20Sopenharmony_ci * NOTE: the wimax stack uses an inverted terminology to that of the
2228c2ecf20Sopenharmony_ci * RFKILL subsystem:
2238c2ecf20Sopenharmony_ci *
2248c2ecf20Sopenharmony_ci *  - ON: radio is ON, RFKILL is DISABLED or OFF.
2258c2ecf20Sopenharmony_ci *  - OFF: radio is OFF, RFKILL is ENABLED or ON.
2268c2ecf20Sopenharmony_ci *
2278c2ecf20Sopenharmony_ci * MISCELLANEOUS OPS:
2288c2ecf20Sopenharmony_ci *
2298c2ecf20Sopenharmony_ci * wimax_reset() can be used to reset the device to power on state; by
2308c2ecf20Sopenharmony_ci * default it issues a warm reset that maintains the same device
2318c2ecf20Sopenharmony_ci * node. If that is not possible, it falls back to a cold reset
2328c2ecf20Sopenharmony_ci * (device reconnect). The driver implements the backend to this
2338c2ecf20Sopenharmony_ci * through wimax_dev->op_reset().
2348c2ecf20Sopenharmony_ci */
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci#ifndef __NET__WIMAX_H__
2378c2ecf20Sopenharmony_ci#define __NET__WIMAX_H__
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci#include <linux/wimax.h>
2408c2ecf20Sopenharmony_ci#include <net/genetlink.h>
2418c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_cistruct net_device;
2448c2ecf20Sopenharmony_cistruct genl_info;
2458c2ecf20Sopenharmony_cistruct wimax_dev;
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci/**
2488c2ecf20Sopenharmony_ci * struct wimax_dev - Generic WiMAX device
2498c2ecf20Sopenharmony_ci *
2508c2ecf20Sopenharmony_ci * @net_dev: [fill] Pointer to the &struct net_device this WiMAX
2518c2ecf20Sopenharmony_ci *     device implements.
2528c2ecf20Sopenharmony_ci *
2538c2ecf20Sopenharmony_ci * @op_msg_from_user: [fill] Driver-specific operation to
2548c2ecf20Sopenharmony_ci *     handle a raw message from user space to the driver. The
2558c2ecf20Sopenharmony_ci *     driver can send messages to user space using with
2568c2ecf20Sopenharmony_ci *     wimax_msg_to_user().
2578c2ecf20Sopenharmony_ci *
2588c2ecf20Sopenharmony_ci * @op_rfkill_sw_toggle: [fill] Driver-specific operation to act on
2598c2ecf20Sopenharmony_ci *     userspace (or any other agent) requesting the WiMAX device to
2608c2ecf20Sopenharmony_ci *     change the RF Kill software switch (WIMAX_RF_ON or
2618c2ecf20Sopenharmony_ci *     WIMAX_RF_OFF).
2628c2ecf20Sopenharmony_ci *     If such hardware support is not present, it is assumed the
2638c2ecf20Sopenharmony_ci *     radio cannot be switched off and it is always on (and the stack
2648c2ecf20Sopenharmony_ci *     will error out when trying to switch it off). In such case,
2658c2ecf20Sopenharmony_ci *     this function pointer can be left as NULL.
2668c2ecf20Sopenharmony_ci *
2678c2ecf20Sopenharmony_ci * @op_reset: [fill] Driver specific operation to reset the
2688c2ecf20Sopenharmony_ci *     device.
2698c2ecf20Sopenharmony_ci *     This operation should always attempt first a warm reset that
2708c2ecf20Sopenharmony_ci *     does not disconnect the device from the bus and return 0.
2718c2ecf20Sopenharmony_ci *     If that fails, it should resort to some sort of cold or bus
2728c2ecf20Sopenharmony_ci *     reset (even if it implies a bus disconnection and device
2738c2ecf20Sopenharmony_ci *     disappearance). In that case, -ENODEV should be returned to
2748c2ecf20Sopenharmony_ci *     indicate the device is gone.
2758c2ecf20Sopenharmony_ci *     This operation has to be synchronous, and return only when the
2768c2ecf20Sopenharmony_ci *     reset is complete. In case of having had to resort to bus/cold
2778c2ecf20Sopenharmony_ci *     reset implying a device disconnection, the call is allowed to
2788c2ecf20Sopenharmony_ci *     return immediately.
2798c2ecf20Sopenharmony_ci *     NOTE: wimax_dev->mutex is NOT locked when this op is being
2808c2ecf20Sopenharmony_ci *     called; however, wimax_dev->mutex_reset IS locked to ensure
2818c2ecf20Sopenharmony_ci *     serialization of calls to wimax_reset().
2828c2ecf20Sopenharmony_ci *     See wimax_reset()'s documentation.
2838c2ecf20Sopenharmony_ci *
2848c2ecf20Sopenharmony_ci * @name: [fill] A way to identify this device. We need to register a
2858c2ecf20Sopenharmony_ci *     name with many subsystems (rfkill, workqueue creation, etc).
2868c2ecf20Sopenharmony_ci *     We can't use the network device name as that
2878c2ecf20Sopenharmony_ci *     might change and in some instances we don't know it yet (until
2888c2ecf20Sopenharmony_ci *     we don't call register_netdev()). So we generate an unique one
2898c2ecf20Sopenharmony_ci *     using the driver name and device bus id, place it here and use
2908c2ecf20Sopenharmony_ci *     it across the board. Recommended naming:
2918c2ecf20Sopenharmony_ci *     DRIVERNAME-BUSNAME:BUSID (dev->bus->name, dev->bus_id).
2928c2ecf20Sopenharmony_ci *
2938c2ecf20Sopenharmony_ci * @id_table_node: [private] link to the list of wimax devices kept by
2948c2ecf20Sopenharmony_ci *     id-table.c. Protected by it's own spinlock.
2958c2ecf20Sopenharmony_ci *
2968c2ecf20Sopenharmony_ci * @mutex: [private] Serializes all concurrent access and execution of
2978c2ecf20Sopenharmony_ci *     operations.
2988c2ecf20Sopenharmony_ci *
2998c2ecf20Sopenharmony_ci * @mutex_reset: [private] Serializes reset operations. Needs to be a
3008c2ecf20Sopenharmony_ci *     different mutex because as part of the reset operation, the
3018c2ecf20Sopenharmony_ci *     driver has to call back into the stack to do things such as
3028c2ecf20Sopenharmony_ci *     state change, that require wimax_dev->mutex.
3038c2ecf20Sopenharmony_ci *
3048c2ecf20Sopenharmony_ci * @state: [private] Current state of the WiMAX device.
3058c2ecf20Sopenharmony_ci *
3068c2ecf20Sopenharmony_ci * @rfkill: [private] integration into the RF-Kill infrastructure.
3078c2ecf20Sopenharmony_ci *
3088c2ecf20Sopenharmony_ci * @rf_sw: [private] State of the software radio switch (OFF/ON)
3098c2ecf20Sopenharmony_ci *
3108c2ecf20Sopenharmony_ci * @rf_hw: [private] State of the hardware radio switch (OFF/ON)
3118c2ecf20Sopenharmony_ci *
3128c2ecf20Sopenharmony_ci * @debugfs_dentry: [private] Used to hook up a debugfs entry. This
3138c2ecf20Sopenharmony_ci *     shows up in the debugfs root as wimax\:DEVICENAME.
3148c2ecf20Sopenharmony_ci *
3158c2ecf20Sopenharmony_ci * Description:
3168c2ecf20Sopenharmony_ci * This structure defines a common interface to access all WiMAX
3178c2ecf20Sopenharmony_ci * devices from different vendors and provides a common API as well as
3188c2ecf20Sopenharmony_ci * a free-form device-specific messaging channel.
3198c2ecf20Sopenharmony_ci *
3208c2ecf20Sopenharmony_ci * Usage:
3218c2ecf20Sopenharmony_ci *  1. Embed a &struct wimax_dev at *the beginning* the network
3228c2ecf20Sopenharmony_ci *     device structure so that netdev_priv() points to it.
3238c2ecf20Sopenharmony_ci *
3248c2ecf20Sopenharmony_ci *  2. memset() it to zero
3258c2ecf20Sopenharmony_ci *
3268c2ecf20Sopenharmony_ci *  3. Initialize with wimax_dev_init(). This will leave the WiMAX
3278c2ecf20Sopenharmony_ci *     device in the %__WIMAX_ST_NULL state.
3288c2ecf20Sopenharmony_ci *
3298c2ecf20Sopenharmony_ci *  4. Fill all the fields marked with [fill]; once called
3308c2ecf20Sopenharmony_ci *     wimax_dev_add(), those fields CANNOT be modified.
3318c2ecf20Sopenharmony_ci *
3328c2ecf20Sopenharmony_ci *  5. Call wimax_dev_add() *after* registering the network
3338c2ecf20Sopenharmony_ci *     device. This will leave the WiMAX device in the %WIMAX_ST_DOWN
3348c2ecf20Sopenharmony_ci *     state.
3358c2ecf20Sopenharmony_ci *     Protect the driver's net_device->open() against succeeding if
3368c2ecf20Sopenharmony_ci *     the wimax device state is lower than %WIMAX_ST_DOWN.
3378c2ecf20Sopenharmony_ci *
3388c2ecf20Sopenharmony_ci *  6. Select when the device is going to be turned on/initialized;
3398c2ecf20Sopenharmony_ci *     for example, it could be initialized on 'ifconfig up' (when the
3408c2ecf20Sopenharmony_ci *     netdev op 'open()' is called on the driver).
3418c2ecf20Sopenharmony_ci *
3428c2ecf20Sopenharmony_ci * When the device is initialized (at `ifconfig up` time, or right
3438c2ecf20Sopenharmony_ci * after calling wimax_dev_add() from _probe(), make sure the
3448c2ecf20Sopenharmony_ci * following steps are taken
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci *  a. Move the device to %WIMAX_ST_UNINITIALIZED. This is needed so
3478c2ecf20Sopenharmony_ci *     some API calls that shouldn't work until the device is ready
3488c2ecf20Sopenharmony_ci *     can be blocked.
3498c2ecf20Sopenharmony_ci *
3508c2ecf20Sopenharmony_ci *  b. Initialize the device. Make sure to turn the SW radio switch
3518c2ecf20Sopenharmony_ci *     off and move the device to state %WIMAX_ST_RADIO_OFF when
3528c2ecf20Sopenharmony_ci *     done. When just initialized, a device should be left in RADIO
3538c2ecf20Sopenharmony_ci *     OFF state until user space devices to turn it on.
3548c2ecf20Sopenharmony_ci *
3558c2ecf20Sopenharmony_ci *  c. Query the device for the state of the hardware rfkill switch
3568c2ecf20Sopenharmony_ci *     and call wimax_rfkill_report_hw() and wimax_rfkill_report_sw()
3578c2ecf20Sopenharmony_ci *     as needed. See below.
3588c2ecf20Sopenharmony_ci *
3598c2ecf20Sopenharmony_ci * wimax_dev_rm() undoes before unregistering the network device. Once
3608c2ecf20Sopenharmony_ci * wimax_dev_add() is called, the driver can get called on the
3618c2ecf20Sopenharmony_ci * wimax_dev->op_* function pointers
3628c2ecf20Sopenharmony_ci *
3638c2ecf20Sopenharmony_ci * CONCURRENCY:
3648c2ecf20Sopenharmony_ci *
3658c2ecf20Sopenharmony_ci * The stack provides a mutex for each device that will disallow API
3668c2ecf20Sopenharmony_ci * calls happening concurrently; thus, op calls into the driver
3678c2ecf20Sopenharmony_ci * through the wimax_dev->op*() function pointers will always be
3688c2ecf20Sopenharmony_ci * serialized and *never* concurrent.
3698c2ecf20Sopenharmony_ci *
3708c2ecf20Sopenharmony_ci * For locking, take wimax_dev->mutex is taken; (most) operations in
3718c2ecf20Sopenharmony_ci * the API have to check for wimax_dev_is_ready() to return 0 before
3728c2ecf20Sopenharmony_ci * continuing (this is done internally).
3738c2ecf20Sopenharmony_ci *
3748c2ecf20Sopenharmony_ci * REFERENCE COUNTING:
3758c2ecf20Sopenharmony_ci *
3768c2ecf20Sopenharmony_ci * The WiMAX device is reference counted by the associated network
3778c2ecf20Sopenharmony_ci * device. The only operation that can be used to reference the device
3788c2ecf20Sopenharmony_ci * is wimax_dev_get_by_genl_info(), and the reference it acquires has
3798c2ecf20Sopenharmony_ci * to be released with dev_put(wimax_dev->net_dev).
3808c2ecf20Sopenharmony_ci *
3818c2ecf20Sopenharmony_ci * RFKILL:
3828c2ecf20Sopenharmony_ci *
3838c2ecf20Sopenharmony_ci * At startup, both HW and SW radio switchess are assumed to be off.
3848c2ecf20Sopenharmony_ci *
3858c2ecf20Sopenharmony_ci * At initialization time [after calling wimax_dev_add()], have the
3868c2ecf20Sopenharmony_ci * driver query the device for the status of the software and hardware
3878c2ecf20Sopenharmony_ci * RF kill switches and call wimax_report_rfkill_hw() and
3888c2ecf20Sopenharmony_ci * wimax_rfkill_report_sw() to indicate their state. If any is
3898c2ecf20Sopenharmony_ci * missing, just call it to indicate it is ON (radio always on).
3908c2ecf20Sopenharmony_ci *
3918c2ecf20Sopenharmony_ci * Whenever the driver detects a change in the state of the RF kill
3928c2ecf20Sopenharmony_ci * switches, it should call wimax_report_rfkill_hw() or
3938c2ecf20Sopenharmony_ci * wimax_report_rfkill_sw() to report it to the stack.
3948c2ecf20Sopenharmony_ci */
3958c2ecf20Sopenharmony_cistruct wimax_dev {
3968c2ecf20Sopenharmony_ci	struct net_device *net_dev;
3978c2ecf20Sopenharmony_ci	struct list_head id_table_node;
3988c2ecf20Sopenharmony_ci	struct mutex mutex;		/* Protects all members and API calls */
3998c2ecf20Sopenharmony_ci	struct mutex mutex_reset;
4008c2ecf20Sopenharmony_ci	enum wimax_st state;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	int (*op_msg_from_user)(struct wimax_dev *wimax_dev,
4038c2ecf20Sopenharmony_ci				const char *,
4048c2ecf20Sopenharmony_ci				const void *, size_t,
4058c2ecf20Sopenharmony_ci				const struct genl_info *info);
4068c2ecf20Sopenharmony_ci	int (*op_rfkill_sw_toggle)(struct wimax_dev *wimax_dev,
4078c2ecf20Sopenharmony_ci				   enum wimax_rf_state);
4088c2ecf20Sopenharmony_ci	int (*op_reset)(struct wimax_dev *wimax_dev);
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	struct rfkill *rfkill;
4118c2ecf20Sopenharmony_ci	unsigned int rf_hw;
4128c2ecf20Sopenharmony_ci	unsigned int rf_sw;
4138c2ecf20Sopenharmony_ci	char name[32];
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	struct dentry *debugfs_dentry;
4168c2ecf20Sopenharmony_ci};
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci/*
4218c2ecf20Sopenharmony_ci * WiMAX stack public API for device drivers
4228c2ecf20Sopenharmony_ci * -----------------------------------------
4238c2ecf20Sopenharmony_ci *
4248c2ecf20Sopenharmony_ci * These functions are not exported to user space.
4258c2ecf20Sopenharmony_ci */
4268c2ecf20Sopenharmony_civoid wimax_dev_init(struct wimax_dev *);
4278c2ecf20Sopenharmony_ciint wimax_dev_add(struct wimax_dev *, struct net_device *);
4288c2ecf20Sopenharmony_civoid wimax_dev_rm(struct wimax_dev *);
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_cistatic inline
4318c2ecf20Sopenharmony_cistruct wimax_dev *net_dev_to_wimax(struct net_device *net_dev)
4328c2ecf20Sopenharmony_ci{
4338c2ecf20Sopenharmony_ci	return netdev_priv(net_dev);
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_cistatic inline
4378c2ecf20Sopenharmony_cistruct device *wimax_dev_to_dev(struct wimax_dev *wimax_dev)
4388c2ecf20Sopenharmony_ci{
4398c2ecf20Sopenharmony_ci	return wimax_dev->net_dev->dev.parent;
4408c2ecf20Sopenharmony_ci}
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_civoid wimax_state_change(struct wimax_dev *, enum wimax_st);
4438c2ecf20Sopenharmony_cienum wimax_st wimax_state_get(struct wimax_dev *);
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci/*
4468c2ecf20Sopenharmony_ci * Radio Switch state reporting.
4478c2ecf20Sopenharmony_ci *
4488c2ecf20Sopenharmony_ci * enum wimax_rf_state is declared in linux/wimax.h so the exports
4498c2ecf20Sopenharmony_ci * to user space can use it.
4508c2ecf20Sopenharmony_ci */
4518c2ecf20Sopenharmony_civoid wimax_report_rfkill_hw(struct wimax_dev *, enum wimax_rf_state);
4528c2ecf20Sopenharmony_civoid wimax_report_rfkill_sw(struct wimax_dev *, enum wimax_rf_state);
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci/*
4568c2ecf20Sopenharmony_ci * Free-form messaging to/from user space
4578c2ecf20Sopenharmony_ci *
4588c2ecf20Sopenharmony_ci * Sending a message:
4598c2ecf20Sopenharmony_ci *
4608c2ecf20Sopenharmony_ci *   wimax_msg(wimax_dev, pipe_name, buf, buf_size, GFP_KERNEL);
4618c2ecf20Sopenharmony_ci *
4628c2ecf20Sopenharmony_ci * Broken up:
4638c2ecf20Sopenharmony_ci *
4648c2ecf20Sopenharmony_ci *   skb = wimax_msg_alloc(wimax_dev, pipe_name, buf_size, GFP_KERNEL);
4658c2ecf20Sopenharmony_ci *   ...fill up skb...
4668c2ecf20Sopenharmony_ci *   wimax_msg_send(wimax_dev, pipe_name, skb);
4678c2ecf20Sopenharmony_ci *
4688c2ecf20Sopenharmony_ci * Be sure not to modify skb->data in the middle (ie: don't use
4698c2ecf20Sopenharmony_ci * skb_push()/skb_pull()/skb_reserve() on the skb).
4708c2ecf20Sopenharmony_ci *
4718c2ecf20Sopenharmony_ci * "pipe_name" is any string, that can be interpreted as the name of
4728c2ecf20Sopenharmony_ci * the pipe or recipient; the interpretation of it is driver
4738c2ecf20Sopenharmony_ci * specific, so the recipient can multiplex it as wished. It can be
4748c2ecf20Sopenharmony_ci * NULL, it won't be used - an example is using a "diagnostics" tag to
4758c2ecf20Sopenharmony_ci * send diagnostics information that a device-specific diagnostics
4768c2ecf20Sopenharmony_ci * tool would be interested in.
4778c2ecf20Sopenharmony_ci */
4788c2ecf20Sopenharmony_cistruct sk_buff *wimax_msg_alloc(struct wimax_dev *, const char *, const void *,
4798c2ecf20Sopenharmony_ci				size_t, gfp_t);
4808c2ecf20Sopenharmony_ciint wimax_msg_send(struct wimax_dev *, struct sk_buff *);
4818c2ecf20Sopenharmony_ciint wimax_msg(struct wimax_dev *, const char *, const void *, size_t, gfp_t);
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ciconst void *wimax_msg_data_len(struct sk_buff *, size_t *);
4848c2ecf20Sopenharmony_ciconst void *wimax_msg_data(struct sk_buff *);
4858c2ecf20Sopenharmony_cissize_t wimax_msg_len(struct sk_buff *);
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci/*
4898c2ecf20Sopenharmony_ci * WiMAX stack user space API
4908c2ecf20Sopenharmony_ci * --------------------------
4918c2ecf20Sopenharmony_ci *
4928c2ecf20Sopenharmony_ci * This API is what gets exported to user space for general
4938c2ecf20Sopenharmony_ci * operations. As well, they can be called from within the kernel,
4948c2ecf20Sopenharmony_ci * (with a properly referenced `struct wimax_dev`).
4958c2ecf20Sopenharmony_ci *
4968c2ecf20Sopenharmony_ci * Properly referenced means: the 'struct net_device' that embeds the
4978c2ecf20Sopenharmony_ci * device's control structure and (as such) the 'struct wimax_dev' is
4988c2ecf20Sopenharmony_ci * referenced by the caller.
4998c2ecf20Sopenharmony_ci */
5008c2ecf20Sopenharmony_ciint wimax_rfkill(struct wimax_dev *, enum wimax_rf_state);
5018c2ecf20Sopenharmony_ciint wimax_reset(struct wimax_dev *);
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci#endif /* #ifndef __NET__WIMAX_H__ */
504