2012-02-09 18:08:15 +04:00
/******************************************************************************
*
* This file is provided under a dual BSD / GPLv2 license . When using or
* redistributing this file , you may do so under either license .
*
* GPL LICENSE SUMMARY
*
* Copyright ( c ) 2007 - 2012 Intel Corporation . All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 ,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE . GPL .
*
* Contact Information :
* Intel Linux Wireless < ilw @ linux . intel . com >
* Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
*
* BSD LICENSE
*
* Copyright ( c ) 2005 - 2012 Intel Corporation . All rights reserved .
* 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 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 .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef __iwl_op_mode_h__
# define __iwl_op_mode_h__
struct iwl_op_mode ;
struct iwl_trans ;
2012-02-09 18:08:15 +04:00
struct sk_buff ;
2012-02-09 18:08:15 +04:00
struct iwl_device_cmd ;
2012-03-05 23:24:39 +04:00
struct iwl_rx_cmd_buffer ;
2012-03-07 01:30:37 +04:00
struct iwl_fw ;
2012-03-25 18:20:12 +04:00
struct iwl_cfg ;
2012-02-09 18:08:15 +04:00
2012-02-16 11:35:19 +04:00
/**
* DOC : Operational mode - what is it ?
*
* The operational mode ( a . k . a . op_mode ) is the layer that implements
* mac80211 ' s handlers . It knows two APIs : mac80211 ' s and the fw ' s . It uses
* the transport API to access the HW . The op_mode doesn ' t need to know how the
* underlying HW works , since the transport layer takes care of that .
*
* There can be several op_mode : i . e . different fw APIs will require two
* different op_modes . This is why the op_mode is virtualized .
*/
/**
* DOC : Life cycle of the Operational mode
*
* The operational mode has a very simple life cycle .
*
* 1 ) The driver layer ( iwl - drv . c ) chooses the op_mode based on the
* capabilities advertized by the fw file ( in TLV format ) .
* 2 ) The driver layer starts the op_mode ( ops - > start )
* 3 ) The op_mode registers registers mac80211
* 4 ) The op_mode is governed by mac80211
* 5 ) The driver layer stops the op_mode
*/
2012-02-09 18:08:15 +04:00
/**
* struct iwl_op_mode_ops - op_mode specific operations
*
2012-02-16 11:35:19 +04:00
* The op_mode exports its ops so that external components can start it and
* interact with it . The driver layer typically calls the start and stop
* handlers , the transport layer calls the others .
*
2012-02-09 18:08:15 +04:00
* All the handlers MUST be implemented
*
2012-02-16 11:35:19 +04:00
* @ start : start the op_mode . The transport layer is already allocated .
2012-02-09 18:08:15 +04:00
* May sleep
2012-02-16 11:35:19 +04:00
* @ stop : stop the op_mode . Must free all the memory allocated .
2012-02-09 18:08:15 +04:00
* May sleep
2012-02-09 18:08:15 +04:00
* @ rx : Rx notification to the op_mode . rxb is the Rx buffer itself . Cmd is the
* HCMD the this Rx responds to .
2012-06-17 17:00:22 +04:00
* Must be atomic and called with BH disabled .
2012-03-16 00:26:52 +04:00
* @ queue_full : notifies that a HW queue is full .
2012-06-17 17:00:22 +04:00
* Must be atomic and called with BH disabled .
2012-02-09 18:08:15 +04:00
* @ queue_not_full : notifies that a HW queue is not full any more .
2012-06-17 17:00:22 +04:00
* Must be atomic and called with BH disabled .
2012-02-09 18:08:15 +04:00
* @ hw_rf_kill : notifies of a change in the HW rf kill switch . True means that
* the radio is killed . Must be atomic .
2012-02-09 18:08:15 +04:00
* @ free_skb : allows the transport layer to free skbs that haven ' t been
* reclaimed by the op_mode . This can happen when the driver is freed and
* there are Tx packets pending in the transport layer .
* Must be atomic
2012-06-17 17:00:22 +04:00
* @ nic_error : error notification . Must be atomic and must be called with BH
* disabled .
* @ cmd_queue_full : Called when the command queue gets full . Must be atomic and
* called with BH disabled .
2012-03-07 01:31:03 +04:00
* @ nic_config : configure NIC , called before firmware is started .
* May sleep
2012-06-17 17:00:22 +04:00
* @ wimax_active : invoked when WiMax becomes active . Must be atomic and called
* with BH disabled .
2012-02-09 18:08:15 +04:00
*/
struct iwl_op_mode_ops {
2012-03-07 01:30:37 +04:00
struct iwl_op_mode * ( * start ) ( struct iwl_trans * trans ,
2012-03-22 19:51:44 +04:00
const struct iwl_cfg * cfg ,
2012-07-17 05:43:56 +04:00
const struct iwl_fw * fw ,
struct dentry * dbgfs_dir ) ;
2012-02-09 18:08:15 +04:00
void ( * stop ) ( struct iwl_op_mode * op_mode ) ;
2012-03-05 23:24:39 +04:00
int ( * rx ) ( struct iwl_op_mode * op_mode , struct iwl_rx_cmd_buffer * rxb ,
2012-02-09 18:08:15 +04:00
struct iwl_device_cmd * cmd ) ;
2012-03-16 00:26:52 +04:00
void ( * queue_full ) ( struct iwl_op_mode * op_mode , int queue ) ;
void ( * queue_not_full ) ( struct iwl_op_mode * op_mode , int queue ) ;
2012-02-09 18:08:15 +04:00
void ( * hw_rf_kill ) ( struct iwl_op_mode * op_mode , bool state ) ;
2012-02-09 18:08:15 +04:00
void ( * free_skb ) ( struct iwl_op_mode * op_mode , struct sk_buff * skb ) ;
2012-02-09 18:08:15 +04:00
void ( * nic_error ) ( struct iwl_op_mode * op_mode ) ;
2012-03-07 01:30:49 +04:00
void ( * cmd_queue_full ) ( struct iwl_op_mode * op_mode ) ;
2012-03-07 01:31:03 +04:00
void ( * nic_config ) ( struct iwl_op_mode * op_mode ) ;
2012-03-20 21:33:34 +04:00
void ( * wimax_active ) ( struct iwl_op_mode * op_mode ) ;
2012-02-09 18:08:15 +04:00
} ;
2012-05-17 00:54:27 +04:00
int iwl_opmode_register ( const char * name , const struct iwl_op_mode_ops * ops ) ;
void iwl_opmode_deregister ( const char * name ) ;
2012-02-09 18:08:15 +04:00
/**
* struct iwl_op_mode - operational mode
*
* This holds an implementation of the mac80211 / fw API .
*
* @ ops - pointer to its own ops
*/
struct iwl_op_mode {
const struct iwl_op_mode_ops * ops ;
const struct iwl_trans * trans ;
char op_mode_specific [ 0 ] __aligned ( sizeof ( void * ) ) ;
} ;
static inline void iwl_op_mode_stop ( struct iwl_op_mode * op_mode )
{
2012-02-16 11:35:19 +04:00
might_sleep ( ) ;
2012-02-09 18:08:15 +04:00
op_mode - > ops - > stop ( op_mode ) ;
}
2012-02-09 18:08:15 +04:00
static inline int iwl_op_mode_rx ( struct iwl_op_mode * op_mode ,
2012-03-05 23:24:39 +04:00
struct iwl_rx_cmd_buffer * rxb ,
2012-02-09 18:08:15 +04:00
struct iwl_device_cmd * cmd )
{
return op_mode - > ops - > rx ( op_mode , rxb , cmd ) ;
}
2012-03-16 00:26:52 +04:00
static inline void iwl_op_mode_queue_full ( struct iwl_op_mode * op_mode ,
int queue )
2012-02-09 18:08:15 +04:00
{
2012-03-16 00:26:52 +04:00
op_mode - > ops - > queue_full ( op_mode , queue ) ;
2012-02-09 18:08:15 +04:00
}
static inline void iwl_op_mode_queue_not_full ( struct iwl_op_mode * op_mode ,
2012-03-16 00:26:52 +04:00
int queue )
2012-02-09 18:08:15 +04:00
{
2012-03-16 00:26:52 +04:00
op_mode - > ops - > queue_not_full ( op_mode , queue ) ;
2012-02-09 18:08:15 +04:00
}
2012-02-09 18:08:15 +04:00
static inline void iwl_op_mode_hw_rf_kill ( struct iwl_op_mode * op_mode ,
bool state )
{
op_mode - > ops - > hw_rf_kill ( op_mode , state ) ;
}
2012-02-09 18:08:15 +04:00
static inline void iwl_op_mode_free_skb ( struct iwl_op_mode * op_mode ,
struct sk_buff * skb )
{
op_mode - > ops - > free_skb ( op_mode , skb ) ;
}
2012-02-09 18:08:15 +04:00
static inline void iwl_op_mode_nic_error ( struct iwl_op_mode * op_mode )
{
op_mode - > ops - > nic_error ( op_mode ) ;
}
2012-03-07 01:30:49 +04:00
static inline void iwl_op_mode_cmd_queue_full ( struct iwl_op_mode * op_mode )
{
op_mode - > ops - > cmd_queue_full ( op_mode ) ;
}
2012-03-07 01:31:03 +04:00
static inline void iwl_op_mode_nic_config ( struct iwl_op_mode * op_mode )
{
might_sleep ( ) ;
op_mode - > ops - > nic_config ( op_mode ) ;
}
2012-03-20 21:33:34 +04:00
static inline void iwl_op_mode_wimax_active ( struct iwl_op_mode * op_mode )
{
op_mode - > ops - > wimax_active ( op_mode ) ;
}
2012-02-09 18:08:15 +04:00
# endif /* __iwl_op_mode_h__ */