2009-08-14 16:13:12 +04:00
/*
* Copyright ( C ) 2007 , 2008 , 2009 Siemens AG
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2
* 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 .
*
* Written by :
* Dmitry Eremin - Solenikov < dbaryshkov @ gmail . com >
*/
2014-10-25 11:41:02 +04:00
# ifndef __NET_CFG802154_H
# define __NET_CFG802154_H
2009-08-14 16:13:12 +04:00
2014-11-17 10:20:54 +03:00
# include <linux/ieee802154.h>
2009-08-14 16:13:12 +04:00
# include <linux/netdevice.h>
# include <linux/mutex.h>
2011-11-24 05:12:59 +04:00
# include <linux/bug.h>
2009-08-14 16:13:12 +04:00
2014-11-17 10:20:51 +03:00
# include <net/nl802154.h>
2014-11-02 06:18:35 +03:00
struct wpan_phy ;
2014-12-10 17:33:13 +03:00
struct wpan_phy_cca ;
2014-11-02 06:18:35 +03:00
2015-09-28 10:00:25 +03:00
# ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
struct ieee802154_llsec_device_key ;
struct ieee802154_llsec_seclevel ;
struct ieee802154_llsec_params ;
struct ieee802154_llsec_device ;
struct ieee802154_llsec_table ;
struct ieee802154_llsec_key_id ;
struct ieee802154_llsec_key ;
# endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2014-11-02 06:18:35 +03:00
struct cfg802154_ops {
2014-11-02 06:18:38 +03:00
struct net_device * ( * add_virtual_intf_deprecated ) ( struct wpan_phy * wpan_phy ,
const char * name ,
2015-04-30 18:44:57 +03:00
unsigned char name_assign_type ,
2014-11-02 06:18:38 +03:00
int type ) ;
2014-11-12 05:36:54 +03:00
void ( * del_virtual_intf_deprecated ) ( struct wpan_phy * wpan_phy ,
struct net_device * dev ) ;
2015-06-24 12:36:35 +03:00
int ( * suspend ) ( struct wpan_phy * wpan_phy ) ;
int ( * resume ) ( struct wpan_phy * wpan_phy ) ;
2014-11-17 10:20:51 +03:00
int ( * add_virtual_intf ) ( struct wpan_phy * wpan_phy ,
const char * name ,
2015-04-30 18:44:57 +03:00
unsigned char name_assign_type ,
2014-11-17 10:20:52 +03:00
enum nl802154_iftype type ,
__le64 extended_addr ) ;
2014-11-17 10:20:53 +03:00
int ( * del_virtual_intf ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ) ;
2014-11-12 05:36:55 +03:00
int ( * set_channel ) ( struct wpan_phy * wpan_phy , u8 page , u8 channel ) ;
2014-12-10 17:33:13 +03:00
int ( * set_cca_mode ) ( struct wpan_phy * wpan_phy ,
const struct wpan_phy_cca * cca ) ;
2015-05-27 14:42:10 +03:00
int ( * set_cca_ed_level ) ( struct wpan_phy * wpan_phy , s32 ed_level ) ;
2015-05-27 06:40:54 +03:00
int ( * set_tx_power ) ( struct wpan_phy * wpan_phy , s32 power ) ;
2014-11-12 05:36:57 +03:00
int ( * set_pan_id ) ( struct wpan_phy * wpan_phy ,
2014-11-17 10:20:55 +03:00
struct wpan_dev * wpan_dev , __le16 pan_id ) ;
2014-11-12 05:36:58 +03:00
int ( * set_short_addr ) ( struct wpan_phy * wpan_phy ,
2014-11-17 10:20:55 +03:00
struct wpan_dev * wpan_dev , __le16 short_addr ) ;
2014-11-12 05:36:59 +03:00
int ( * set_backoff_exponent ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev , u8 min_be ,
u8 max_be ) ;
2014-11-12 05:37:01 +03:00
int ( * set_max_csma_backoffs ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
u8 max_csma_backoffs ) ;
2014-11-12 05:37:03 +03:00
int ( * set_max_frame_retries ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
s8 max_frame_retries ) ;
2014-11-12 05:37:05 +03:00
int ( * set_lbt_mode ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev , bool mode ) ;
2015-08-10 22:15:58 +03:00
int ( * set_ackreq_default ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev , bool ackreq ) ;
2015-09-28 10:00:25 +03:00
# ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
void ( * get_llsec_table ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
struct ieee802154_llsec_table * * table ) ;
void ( * lock_llsec_table ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ) ;
void ( * unlock_llsec_table ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ) ;
/* TODO remove locking/get table callbacks, this is part of the
* nl802154 interface and should be accessible from ieee802154 layer .
*/
int ( * get_llsec_params ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
struct ieee802154_llsec_params * params ) ;
int ( * set_llsec_params ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_params * params ,
int changed ) ;
int ( * add_llsec_key ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_key_id * id ,
const struct ieee802154_llsec_key * key ) ;
int ( * del_llsec_key ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_key_id * id ) ;
int ( * add_seclevel ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_seclevel * sl ) ;
int ( * del_seclevel ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_seclevel * sl ) ;
int ( * add_device ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
const struct ieee802154_llsec_device * dev ) ;
int ( * del_device ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev , __le64 extended_addr ) ;
int ( * add_devkey ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
__le64 extended_addr ,
const struct ieee802154_llsec_device_key * key ) ;
int ( * del_devkey ) ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
__le64 extended_addr ,
const struct ieee802154_llsec_device_key * key ) ;
# endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2014-11-02 06:18:35 +03:00
} ;
2015-05-17 22:44:43 +03:00
static inline bool
wpan_phy_supported_bool ( bool b , enum nl802154_supported_bool_states st )
{
switch ( st ) {
case NL802154_SUPPORTED_BOOL_TRUE :
return b ;
case NL802154_SUPPORTED_BOOL_FALSE :
return ! b ;
case NL802154_SUPPORTED_BOOL_BOTH :
return true ;
default :
WARN_ON ( 1 ) ;
}
return false ;
}
2015-05-17 22:44:42 +03:00
struct wpan_phy_supported {
2015-05-17 22:44:43 +03:00
u32 channels [ IEEE802154_MAX_PAGE + 1 ] ,
2015-05-17 22:44:47 +03:00
cca_modes , cca_opts , iftypes ;
2015-05-17 22:44:43 +03:00
enum nl802154_supported_bool_states lbt ;
u8 min_minbe , max_minbe , min_maxbe , max_maxbe ,
min_csma_backoffs , max_csma_backoffs ;
s8 min_frame_retries , max_frame_retries ;
size_t tx_powers_size , cca_ed_levels_size ;
const s32 * tx_powers , * cca_ed_levels ;
2015-05-17 22:44:42 +03:00
} ;
2014-12-10 17:33:12 +03:00
struct wpan_phy_cca {
enum nl802154_cca_modes mode ;
enum nl802154_cca_opts opt ;
} ;
2015-05-17 22:44:44 +03:00
static inline bool
wpan_phy_cca_cmp ( const struct wpan_phy_cca * a , const struct wpan_phy_cca * b )
{
if ( a - > mode ! = b - > mode )
return false ;
if ( a - > mode = = NL802154_CCA_ENERGY_CARRIER )
return a - > opt = = b - > opt ;
return true ;
}
2015-05-17 22:44:46 +03:00
/**
* @ WPAN_PHY_FLAG_TRANSMIT_POWER : Indicates that transceiver will support
* transmit power setting .
* @ WPAN_PHY_FLAG_CCA_ED_LEVEL : Indicates that transceiver will support cca ed
* level setting .
* @ WPAN_PHY_FLAG_CCA_MODE : Indicates that transceiver will support cca mode
* setting .
*/
enum wpan_phy_flags {
WPAN_PHY_FLAG_TXPOWER = BIT ( 1 ) ,
WPAN_PHY_FLAG_CCA_ED_LEVEL = BIT ( 2 ) ,
WPAN_PHY_FLAG_CCA_MODE = BIT ( 3 ) ,
} ;
2009-08-14 16:13:12 +04:00
struct wpan_phy {
2014-11-12 05:36:51 +03:00
/* If multiple wpan_phys are registered and you're handed e.g.
* a regular netdev with assigned ieee802154_ptr , you won ' t
* know whether it points to a wpan_phy your driver has registered
* or not . Assign this to something global to your driver to
* help determine whether you own this wpan_phy or not .
*/
const void * privid ;
2015-05-17 22:44:46 +03:00
u32 flags ;
2009-08-14 16:13:12 +04:00
/*
2014-02-17 14:34:08 +04:00
* This is a PIB according to 802.15 .4 - 2011.
2009-08-14 16:13:12 +04:00
* We do not provide timing - related variables , as they
* aren ' t used outside of driver
*/
u8 current_channel ;
u8 current_page ;
2015-05-17 22:44:42 +03:00
struct wpan_phy_supported supported ;
2015-05-17 22:44:40 +03:00
/* current transmit_power in mBm */
2015-05-17 22:44:39 +03:00
s32 transmit_power ;
2014-12-10 17:33:12 +03:00
struct wpan_phy_cca cca ;
2014-11-05 22:51:25 +03:00
__le64 perm_extended_addr ;
2009-08-14 16:13:12 +04:00
2015-05-17 22:44:41 +03:00
/* current cca ed threshold in mBm */
2014-02-17 14:34:12 +04:00
s32 cca_ed_level ;
2014-02-17 14:34:10 +04:00
2014-11-12 21:51:56 +03:00
/* PHY depended MAC PIB values */
/* 802.15.4 acronym: Tdsym in usec */
u8 symbol_duration ;
/* lifs and sifs periods timing */
u16 lifs_period ;
u16 sifs_period ;
2009-08-14 16:13:12 +04:00
struct device dev ;
2016-06-18 11:45:34 +03:00
/* the network namespace this phy lives in currently */
possible_net_t _net ;
2014-10-25 07:25:10 +04:00
char priv [ 0 ] __aligned ( NETDEV_ALIGN ) ;
2009-08-14 16:13:12 +04:00
} ;
2016-06-18 11:45:34 +03:00
static inline struct net * wpan_phy_net ( struct wpan_phy * wpan_phy )
{
return read_pnet ( & wpan_phy - > _net ) ;
}
static inline void wpan_phy_net_set ( struct wpan_phy * wpan_phy , struct net * net )
{
write_pnet ( & wpan_phy - > _net , net ) ;
}
2015-09-18 12:30:42 +03:00
struct ieee802154_addr {
u8 mode ;
__le16 pan_id ;
union {
__le16 short_addr ;
__le64 extended_addr ;
} ;
} ;
2015-09-28 10:00:25 +03:00
struct ieee802154_llsec_key_id {
u8 mode ;
u8 id ;
union {
struct ieee802154_addr device_addr ;
__le32 short_source ;
__le64 extended_source ;
} ;
} ;
# define IEEE802154_LLSEC_KEY_SIZE 16
struct ieee802154_llsec_key {
u8 frame_types ;
u32 cmd_frame_ids ;
/* TODO replace with NL802154_KEY_SIZE */
u8 key [ IEEE802154_LLSEC_KEY_SIZE ] ;
} ;
struct ieee802154_llsec_key_entry {
struct list_head list ;
struct ieee802154_llsec_key_id id ;
struct ieee802154_llsec_key * key ;
} ;
struct ieee802154_llsec_params {
bool enabled ;
__be32 frame_counter ;
u8 out_level ;
struct ieee802154_llsec_key_id out_key ;
__le64 default_key_source ;
__le16 pan_id ;
__le64 hwaddr ;
__le64 coord_hwaddr ;
__le16 coord_shortaddr ;
} ;
struct ieee802154_llsec_table {
struct list_head keys ;
struct list_head devices ;
struct list_head security_levels ;
} ;
struct ieee802154_llsec_seclevel {
struct list_head list ;
u8 frame_type ;
u8 cmd_frame_id ;
bool device_override ;
u32 sec_levels ;
} ;
struct ieee802154_llsec_device {
struct list_head list ;
__le16 pan_id ;
__le16 short_addr ;
__le64 hwaddr ;
u32 frame_counter ;
bool seclevel_exempt ;
u8 key_mode ;
struct list_head keys ;
} ;
struct ieee802154_llsec_device_key {
struct list_head list ;
struct ieee802154_llsec_key_id key_id ;
u32 frame_counter ;
} ;
2015-09-18 12:30:42 +03:00
struct wpan_dev_header_ops {
/* TODO create callback currently assumes ieee802154_mac_cb inside
* skb - > cb . This should be changed to give these information as
* parameter .
*/
int ( * create ) ( struct sk_buff * skb , struct net_device * dev ,
const struct ieee802154_addr * daddr ,
const struct ieee802154_addr * saddr ,
unsigned int len ) ;
} ;
2014-11-05 22:51:17 +03:00
struct wpan_dev {
struct wpan_phy * wpan_phy ;
2014-11-09 10:36:49 +03:00
int iftype ;
2014-11-09 10:36:45 +03:00
2014-11-09 10:36:50 +03:00
/* the remainder of this struct should be private to cfg802154 */
struct list_head list ;
struct net_device * netdev ;
2015-09-18 12:30:42 +03:00
const struct wpan_dev_header_ops * header_ops ;
2015-08-10 22:15:53 +03:00
/* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
struct net_device * lowpan_dev ;
2014-11-09 10:36:50 +03:00
u32 identifier ;
2014-11-09 10:36:45 +03:00
/* MAC PIB */
__le16 pan_id ;
__le16 short_addr ;
__le64 extended_addr ;
/* MAC BSN field */
2015-05-22 18:43:53 +03:00
atomic_t bsn ;
2014-11-09 10:36:45 +03:00
/* MAC DSN field */
2015-05-22 18:43:53 +03:00
atomic_t dsn ;
2014-11-09 10:36:45 +03:00
u8 min_be ;
u8 max_be ;
u8 csma_retries ;
s8 frame_retries ;
bool lbt ;
bool promiscuous_mode ;
2015-08-10 22:15:58 +03:00
/* fallback for acknowledgment bit setting */
bool ackreq ;
2014-11-05 22:51:17 +03:00
} ;
2009-11-04 17:53:23 +03:00
# define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
2015-09-18 12:30:42 +03:00
static inline int
wpan_dev_hard_header ( struct sk_buff * skb , struct net_device * dev ,
const struct ieee802154_addr * daddr ,
const struct ieee802154_addr * saddr ,
unsigned int len )
{
struct wpan_dev * wpan_dev = dev - > ieee802154_ptr ;
return wpan_dev - > header_ops - > create ( skb , dev , daddr , saddr , len ) ;
}
2014-11-02 06:18:35 +03:00
struct wpan_phy *
2014-11-09 10:36:47 +03:00
wpan_phy_new ( const struct cfg802154_ops * ops , size_t priv_size ) ;
2009-09-28 19:01:20 +04:00
static inline void wpan_phy_set_dev ( struct wpan_phy * phy , struct device * dev )
{
phy - > dev . parent = dev ;
}
2014-10-25 07:25:11 +04:00
2009-09-28 19:01:20 +04:00
int wpan_phy_register ( struct wpan_phy * phy ) ;
2009-08-14 16:13:12 +04:00
void wpan_phy_unregister ( struct wpan_phy * phy ) ;
void wpan_phy_free ( struct wpan_phy * phy ) ;
2009-09-15 16:57:04 +04:00
/* Same semantics as for class_for_each_device */
int wpan_phy_for_each ( int ( * fn ) ( struct wpan_phy * phy , void * data ) , void * data ) ;
2009-08-14 16:13:12 +04:00
static inline void * wpan_phy_priv ( struct wpan_phy * phy )
{
BUG_ON ( ! phy ) ;
return & phy - > priv ;
}
struct wpan_phy * wpan_phy_find ( const char * str ) ;
2009-09-14 18:11:03 +04:00
static inline void wpan_phy_put ( struct wpan_phy * phy )
{
put_device ( & phy - > dev ) ;
}
2009-08-14 16:13:12 +04:00
static inline const char * wpan_phy_name ( struct wpan_phy * phy )
{
return dev_name ( & phy - > dev ) ;
}
2014-10-25 11:41:02 +04:00
# endif /* __NET_CFG802154_H */