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