linux/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * This file is provided under a dual BSD/GPLv2 license.  When using or
   4 * redistributing this file, you may do so under either license.
   5 *
   6 * GPL LICENSE SUMMARY
   7 *
   8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
   9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  10 * Copyright(c) 2015        Intel Deutschland GmbH
  11 * Copyright(c) 2018 Intel Corporation
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of version 2 of the GNU General Public License as
  15 * published by the Free Software Foundation.
  16 *
  17 * This program is distributed in the hope that it will be useful, but
  18 * WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20 * General Public License for more details.
  21 *
  22 * The full GNU General Public License is included in this distribution
  23 * in the file called COPYING.
  24 *
  25 * Contact Information:
  26 *  Intel Linux Wireless <linuxwifi@intel.com>
  27 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  28 *
  29 * BSD LICENSE
  30 *
  31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  33 * Copyright(c) 2015        Intel Deutschland GmbH
  34 * Copyright(c) 2018 Intel Corporation
  35 * All rights reserved.
  36 *
  37 * Redistribution and use in source and binary forms, with or without
  38 * modification, are permitted provided that the following conditions
  39 * are met:
  40 *
  41 *  * Redistributions of source code must retain the above copyright
  42 *    notice, this list of conditions and the following disclaimer.
  43 *  * Redistributions in binary form must reproduce the above copyright
  44 *    notice, this list of conditions and the following disclaimer in
  45 *    the documentation and/or other materials provided with the
  46 *    distribution.
  47 *  * Neither the name Intel Corporation nor the names of its
  48 *    contributors may be used to endorse or promote products derived
  49 *    from this software without specific prior written permission.
  50 *
  51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  52 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  53 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  54 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  55 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  57 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  61 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  62 *
  63 *****************************************************************************/
  64#ifndef __iwl_op_mode_h__
  65#define __iwl_op_mode_h__
  66
  67#include <linux/netdevice.h>
  68#include <linux/debugfs.h>
  69
  70struct iwl_op_mode;
  71struct iwl_trans;
  72struct sk_buff;
  73struct iwl_device_cmd;
  74struct iwl_rx_cmd_buffer;
  75struct iwl_fw;
  76struct iwl_cfg;
  77
  78/**
  79 * DOC: Operational mode - what is it ?
  80 *
  81 * The operational mode (a.k.a. op_mode) is the layer that implements
  82 * mac80211's handlers. It knows two APIs: mac80211's and the fw's. It uses
  83 * the transport API to access the HW. The op_mode doesn't need to know how the
  84 * underlying HW works, since the transport layer takes care of that.
  85 *
  86 * There can be several op_mode: i.e. different fw APIs will require two
  87 * different op_modes. This is why the op_mode is virtualized.
  88 */
  89
  90/**
  91 * DOC: Life cycle of the Operational mode
  92 *
  93 * The operational mode has a very simple life cycle.
  94 *
  95 *      1) The driver layer (iwl-drv.c) chooses the op_mode based on the
  96 *         capabilities advertised by the fw file (in TLV format).
  97 *      2) The driver layer starts the op_mode (ops->start)
  98 *      3) The op_mode registers mac80211
  99 *      4) The op_mode is governed by mac80211
 100 *      5) The driver layer stops the op_mode
 101 */
 102
 103/**
 104 * struct iwl_op_mode_ops - op_mode specific operations
 105 *
 106 * The op_mode exports its ops so that external components can start it and
 107 * interact with it. The driver layer typically calls the start and stop
 108 * handlers, the transport layer calls the others.
 109 *
 110 * All the handlers MUST be implemented, except @rx_rss which can be left
 111 * out *iff* the opmode will never run on hardware with multi-queue capability.
 112 *
 113 * @start: start the op_mode. The transport layer is already allocated.
 114 *      May sleep
 115 * @stop: stop the op_mode. Must free all the memory allocated.
 116 *      May sleep
 117 * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
 118 *      HCMD this Rx responds to. Can't sleep.
 119 * @rx_rss: data queue RX notification to the op_mode, for (data) notifications
 120 *      received on the RSS queue(s). The queue parameter indicates which of the
 121 *      RSS queues received this frame; it will always be non-zero.
 122 *      This method must not sleep.
 123 * @async_cb: called when an ASYNC command with CMD_WANT_ASYNC_CALLBACK set
 124 *      completes. Must be atomic.
 125 * @queue_full: notifies that a HW queue is full.
 126 *      Must be atomic and called with BH disabled.
 127 * @queue_not_full: notifies that a HW queue is not full any more.
 128 *      Must be atomic and called with BH disabled.
 129 * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
 130 *      the radio is killed. Return %true if the device should be stopped by
 131 *      the transport immediately after the call. May sleep.
 132 * @free_skb: allows the transport layer to free skbs that haven't been
 133 *      reclaimed by the op_mode. This can happen when the driver is freed and
 134 *      there are Tx packets pending in the transport layer.
 135 *      Must be atomic
 136 * @nic_error: error notification. Must be atomic and must be called with BH
 137 *      disabled.
 138 * @cmd_queue_full: Called when the command queue gets full. Must be atomic and
 139 *      called with BH disabled.
 140 * @nic_config: configure NIC, called before firmware is started.
 141 *      May sleep
 142 * @wimax_active: invoked when WiMax becomes active. May sleep
 143 * @enter_d0i3: configure the fw to enter d0i3. return 1 to indicate d0i3
 144 *      entrance is aborted (e.g. due to held reference). May sleep.
 145 * @exit_d0i3: configure the fw to exit d0i3. May sleep.
 146 */
 147struct iwl_op_mode_ops {
 148        struct iwl_op_mode *(*start)(struct iwl_trans *trans,
 149                                     const struct iwl_cfg *cfg,
 150                                     const struct iwl_fw *fw,
 151                                     struct dentry *dbgfs_dir);
 152        void (*stop)(struct iwl_op_mode *op_mode);
 153        void (*rx)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
 154                   struct iwl_rx_cmd_buffer *rxb);
 155        void (*rx_rss)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
 156                       struct iwl_rx_cmd_buffer *rxb, unsigned int queue);
 157        void (*async_cb)(struct iwl_op_mode *op_mode,
 158                         const struct iwl_device_cmd *cmd);
 159        void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
 160        void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
 161        bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
 162        void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
 163        void (*nic_error)(struct iwl_op_mode *op_mode);
 164        void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
 165        void (*nic_config)(struct iwl_op_mode *op_mode);
 166        void (*wimax_active)(struct iwl_op_mode *op_mode);
 167        int (*enter_d0i3)(struct iwl_op_mode *op_mode);
 168        int (*exit_d0i3)(struct iwl_op_mode *op_mode);
 169};
 170
 171int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops);
 172void iwl_opmode_deregister(const char *name);
 173
 174/**
 175 * struct iwl_op_mode - operational mode
 176 * @ops: pointer to its own ops
 177 *
 178 * This holds an implementation of the mac80211 / fw API.
 179 */
 180struct iwl_op_mode {
 181        const struct iwl_op_mode_ops *ops;
 182
 183        char op_mode_specific[0] __aligned(sizeof(void *));
 184};
 185
 186static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
 187{
 188        might_sleep();
 189        op_mode->ops->stop(op_mode);
 190}
 191
 192static inline void iwl_op_mode_rx(struct iwl_op_mode *op_mode,
 193                                  struct napi_struct *napi,
 194                                  struct iwl_rx_cmd_buffer *rxb)
 195{
 196        return op_mode->ops->rx(op_mode, napi, rxb);
 197}
 198
 199static inline void iwl_op_mode_rx_rss(struct iwl_op_mode *op_mode,
 200                                      struct napi_struct *napi,
 201                                      struct iwl_rx_cmd_buffer *rxb,
 202                                      unsigned int queue)
 203{
 204        op_mode->ops->rx_rss(op_mode, napi, rxb, queue);
 205}
 206
 207static inline void iwl_op_mode_async_cb(struct iwl_op_mode *op_mode,
 208                                        const struct iwl_device_cmd *cmd)
 209{
 210        if (op_mode->ops->async_cb)
 211                op_mode->ops->async_cb(op_mode, cmd);
 212}
 213
 214static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode,
 215                                          int queue)
 216{
 217        op_mode->ops->queue_full(op_mode, queue);
 218}
 219
 220static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
 221                                              int queue)
 222{
 223        op_mode->ops->queue_not_full(op_mode, queue);
 224}
 225
 226static inline bool __must_check
 227iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode, bool state)
 228{
 229        might_sleep();
 230        return op_mode->ops->hw_rf_kill(op_mode, state);
 231}
 232
 233static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode,
 234                                        struct sk_buff *skb)
 235{
 236        op_mode->ops->free_skb(op_mode, skb);
 237}
 238
 239static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode)
 240{
 241        op_mode->ops->nic_error(op_mode);
 242}
 243
 244static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode)
 245{
 246        op_mode->ops->cmd_queue_full(op_mode);
 247}
 248
 249static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode)
 250{
 251        might_sleep();
 252        op_mode->ops->nic_config(op_mode);
 253}
 254
 255static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)
 256{
 257        might_sleep();
 258        op_mode->ops->wimax_active(op_mode);
 259}
 260
 261static inline int iwl_op_mode_enter_d0i3(struct iwl_op_mode *op_mode)
 262{
 263        might_sleep();
 264
 265        if (!op_mode->ops->enter_d0i3)
 266                return 0;
 267        return op_mode->ops->enter_d0i3(op_mode);
 268}
 269
 270static inline int iwl_op_mode_exit_d0i3(struct iwl_op_mode *op_mode)
 271{
 272        might_sleep();
 273
 274        if (!op_mode->ops->exit_d0i3)
 275                return 0;
 276        return op_mode->ops->exit_d0i3(op_mode);
 277}
 278
 279#endif /* __iwl_op_mode_h__ */
 280