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