2012-05-16 00:50:19 +04:00
/*
* IEEE802 .15 .4 - 2003 specification
*
* Copyright ( C ) 2007 - 2012 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 .
*
*/
# ifndef NET_MAC802154_H
# define NET_MAC802154_H
# include <net/af_ieee802154.h>
2014-11-05 22:51:23 +03:00
# include <linux/ieee802154.h>
2014-03-15 00:24:00 +04:00
# include <linux/skbuff.h>
2015-02-11 16:39:16 +03:00
# include <linux/unaligned/memmove.h>
2012-05-16 00:50:19 +04:00
2014-12-10 17:33:12 +03:00
# include <net/cfg802154.h>
2012-06-26 03:24:48 +04:00
/* General MAC frame format:
* 2 bytes : Frame Control
* 1 byte : Sequence Number
* 20 bytes : Addressing fields
* 14 bytes : Auxiliary Security Header
*/
# define MAC802154_FRAME_HARD_HEADER_LEN (2 + 1 + 20 + 14)
2015-06-06 18:30:47 +03:00
/**
* enum ieee802154_hw_addr_filt_flags - hardware address filtering flags
*
* The following flags are used to indicate changed address settings from
2012-05-16 00:50:19 +04:00
* the stack to the hardware .
2015-06-06 18:30:47 +03:00
*
* @ IEEE802154_AFILT_SADDR_CHANGED : Indicates that the short address will be
* change .
*
* @ IEEE802154_AFILT_IEEEADDR_CHANGED : Indicates that the extended address
* will be change .
*
* @ IEEE802154_AFILT_PANID_CHANGED : Indicates that the pan id will be change .
*
* @ IEEE802154_AFILT_PANC_CHANGED : Indicates that the address filter will
* do frame address filtering as a pan coordinator .
2012-05-16 00:50:19 +04:00
*/
2015-06-06 18:30:47 +03:00
enum ieee802154_hw_addr_filt_flags {
IEEE802154_AFILT_SADDR_CHANGED = BIT ( 1 ) ,
IEEE802154_AFILT_IEEEADDR_CHANGED = BIT ( 2 ) ,
IEEE802154_AFILT_PANID_CHANGED = BIT ( 3 ) ,
IEEE802154_AFILT_PANC_CHANGED = BIT ( 4 ) ,
} ;
2012-05-16 00:50:19 +04:00
struct ieee802154_hw_addr_filt {
__le16 pan_id ; /* Each independent PAN selects a unique
* identifier . This PAN id allows communication
* between devices within a network using short
* addresses and enables transmissions between
* devices across independent networks .
*/
__le16 short_addr ;
2014-03-15 00:23:59 +04:00
__le64 ieee_addr ;
2012-05-16 00:50:19 +04:00
u8 pan_coord ;
} ;
2014-10-25 19:16:34 +04:00
struct ieee802154_hw {
2012-05-16 00:50:19 +04:00
/* filled by the driver */
int extra_tx_headroom ;
u32 flags ;
struct device * parent ;
/* filled by mac802154 core */
void * priv ;
struct wpan_phy * phy ;
} ;
2015-06-06 18:30:49 +03:00
/**
* enum ieee802154_hw_flags - hardware flags
2012-05-16 00:50:19 +04:00
*
2015-06-06 18:30:49 +03:00
* These flags are used to indicate hardware capabilities to
2012-05-16 00:50:19 +04:00
* the stack . Generally , flags here should have their meaning
* done in a way that the simplest hardware doesn ' t need setting
* any particular flags . There are some exceptions to this rule ,
* however , so you are advised to review these flags carefully .
2015-06-06 18:30:49 +03:00
*
* @ IEEE802154_HW_TX_OMIT_CKSUM : Indicates that xmitter will add FCS on it ' s
* own .
*
* @ IEEE802154_HW_LBT : Indicates that transceiver will support listen before
* transmit .
*
* @ IEEE802154_HW_CSMA_PARAMS : Indicates that transceiver will support csma
* parameters ( max_be , min_be , backoff exponents ) .
*
* @ IEEE802154_HW_FRAME_RETRIES : Indicates that transceiver will support ARET
* frame retries setting .
*
* @ IEEE802154_HW_AFILT : Indicates that transceiver will support hardware
* address filter setting .
*
* @ IEEE802154_HW_PROMISCUOUS : Indicates that transceiver will support
* promiscuous mode setting .
*
* @ IEEE802154_HW_RX_OMIT_CKSUM : Indicates that receiver omits FCS .
*
* @ IEEE802154_HW_RX_DROP_BAD_CKSUM : Indicates that receiver will not filter
* frames with bad checksum .
2012-05-16 00:50:19 +04:00
*/
2015-06-06 18:30:49 +03:00
enum ieee802154_hw_flags {
IEEE802154_HW_TX_OMIT_CKSUM = BIT ( 1 ) ,
IEEE802154_HW_LBT = BIT ( 2 ) ,
IEEE802154_HW_CSMA_PARAMS = BIT ( 3 ) ,
IEEE802154_HW_FRAME_RETRIES = BIT ( 4 ) ,
IEEE802154_HW_AFILT = BIT ( 5 ) ,
IEEE802154_HW_PROMISCUOUS = BIT ( 6 ) ,
IEEE802154_HW_RX_OMIT_CKSUM = BIT ( 7 ) ,
IEEE802154_HW_RX_DROP_BAD_CKSUM = BIT ( 8 ) ,
} ;
2014-10-29 23:34:34 +03:00
/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */
# define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \
IEEE802154_HW_RX_OMIT_CKSUM )
2014-07-03 02:20:43 +04:00
2012-05-16 00:50:19 +04:00
/* struct ieee802154_ops - callbacks from mac802154 to the driver
*
* This structure contains various callbacks that the driver may
* handle or , in some cases , must handle , for example to transmit
* a frame .
*
* start : Handler that 802.15 .4 module calls for device initialization .
* This function is called before the first interface is attached .
*
* stop : Handler that 802.15 .4 module calls for device cleanup .
* This function is called after the last interface is removed .
*
2014-10-26 11:37:08 +03:00
* xmit_sync :
* Handler that 802.15 .4 module calls for each transmitted frame .
* skb cntains the buffer starting from the IEEE 802.15 .4 header .
* The low - level driver should send the frame based on available
* configuration . This is called by a workqueue and useful for
* synchronous 802.15 .4 drivers .
* This function should return zero or negative errno .
*
2014-10-26 11:37:14 +03:00
* WARNING :
* This will be deprecated soon . We don ' t accept synced xmit callbacks
* drivers anymore .
*
2014-10-26 11:37:08 +03:00
* xmit_async :
* Handler that 802.15 .4 module calls for each transmitted frame .
2012-05-16 00:50:19 +04:00
* skb cntains the buffer starting from the IEEE 802.15 .4 header .
* The low - level driver should send the frame based on available
* configuration .
2014-10-26 11:37:04 +03:00
* This function should return zero or negative errno .
2012-05-16 00:50:19 +04:00
*
* ed : Handler that 802.15 .4 module calls for Energy Detection .
* This function should place the value for detected energy
* ( usually device - dependant ) in the level pointer and return
* either zero or negative errno . Called with pib_lock held .
*
* set_channel :
* Set radio for listening on specific channel .
* Set the device for listening on specified channel .
* Returns either zero , or negative errno . Called with pib_lock held .
*
* set_hw_addr_filt :
* Set radio for listening on specific address .
* Set the device for listening on specified address .
* Returns either zero , or negative errno .
2014-02-17 14:34:08 +04:00
*
* set_txpower :
2015-05-17 22:44:40 +03:00
* Set radio transmit power in mBm . Called with pib_lock held .
2014-02-17 14:34:08 +04:00
* Returns either zero , or negative errno .
2014-02-17 14:34:10 +04:00
*
* set_lbt
* Enables or disables listen before talk on the device . Called with
* pib_lock held .
* Returns either zero , or negative errno .
2014-02-17 14:34:11 +04:00
*
* set_cca_mode
* Sets the CCA mode used by the device . Called with pib_lock held .
* Returns either zero , or negative errno .
2014-02-17 14:34:12 +04:00
*
* set_cca_ed_level
2015-05-17 22:44:41 +03:00
* Sets the CCA energy detection threshold in mBm . Called with pib_lock
2014-02-17 14:34:12 +04:00
* held .
* Returns either zero , or negative errno .
2014-02-17 14:34:14 +04:00
*
* set_csma_params
* Sets the CSMA parameter set for the PHY . Called with pib_lock held .
* Returns either zero , or negative errno .
*
* set_frame_retries
* Sets the retransmission attempt limit . Called with pib_lock held .
* Returns either zero , or negative errno .
2014-10-29 23:34:32 +03:00
*
* set_promiscuous_mode
* Enables or disable promiscuous mode .
2012-05-16 00:50:19 +04:00
*/
struct ieee802154_ops {
struct module * owner ;
2014-10-25 19:16:34 +04:00
int ( * start ) ( struct ieee802154_hw * hw ) ;
void ( * stop ) ( struct ieee802154_hw * hw ) ;
2014-10-26 11:37:08 +03:00
int ( * xmit_sync ) ( struct ieee802154_hw * hw ,
struct sk_buff * skb ) ;
int ( * xmit_async ) ( struct ieee802154_hw * hw ,
struct sk_buff * skb ) ;
2014-10-25 19:16:34 +04:00
int ( * ed ) ( struct ieee802154_hw * hw , u8 * level ) ;
2014-10-28 20:21:19 +03:00
int ( * set_channel ) ( struct ieee802154_hw * hw , u8 page ,
u8 channel ) ;
2014-10-25 19:16:34 +04:00
int ( * set_hw_addr_filt ) ( struct ieee802154_hw * hw ,
struct ieee802154_hw_addr_filt * filt ,
2012-05-16 00:50:19 +04:00
unsigned long changed ) ;
2015-05-17 22:44:40 +03:00
int ( * set_txpower ) ( struct ieee802154_hw * hw , s32 mbm ) ;
2014-10-25 19:16:34 +04:00
int ( * set_lbt ) ( struct ieee802154_hw * hw , bool on ) ;
2014-12-10 17:33:12 +03:00
int ( * set_cca_mode ) ( struct ieee802154_hw * hw ,
const struct wpan_phy_cca * cca ) ;
2015-05-17 22:44:41 +03:00
int ( * set_cca_ed_level ) ( struct ieee802154_hw * hw , s32 mbm ) ;
2014-10-25 19:16:34 +04:00
int ( * set_csma_params ) ( struct ieee802154_hw * hw ,
2014-02-17 14:34:14 +04:00
u8 min_be , u8 max_be , u8 retries ) ;
2014-10-25 19:16:34 +04:00
int ( * set_frame_retries ) ( struct ieee802154_hw * hw ,
2014-02-17 14:34:14 +04:00
s8 retries ) ;
2014-10-29 23:34:32 +03:00
int ( * set_promiscuous_mode ) ( struct ieee802154_hw * hw ,
const bool on ) ;
2012-05-16 00:50:19 +04:00
} ;
2014-11-02 06:18:40 +03:00
/**
2014-11-05 22:51:24 +03:00
* ieee802154_be64_to_le64 - copies and convert be64 to le64
* @ le64_dst : le64 destination pointer
* @ be64_src : be64 source pointer
2014-11-02 06:18:40 +03:00
*/
2014-11-05 22:51:24 +03:00
static inline void ieee802154_be64_to_le64 ( void * le64_dst , const void * be64_src )
2014-11-02 06:18:40 +03:00
{
2015-02-11 16:39:16 +03:00
__put_unaligned_memmove64 ( swab64p ( be64_src ) , le64_dst ) ;
2014-11-02 06:18:40 +03:00
}
2014-11-05 22:51:23 +03:00
/**
* ieee802154_le64_to_be64 - copies and convert le64 to be64
* @ be64_dst : be64 destination pointer
* @ le64_src : le64 source pointer
*/
static inline void ieee802154_le64_to_be64 ( void * be64_dst , const void * le64_src )
{
2015-02-11 16:39:17 +03:00
__put_unaligned_memmove64 ( swab64p ( le64_src ) , be64_dst ) ;
2014-11-05 22:51:23 +03:00
}
2015-04-30 18:44:52 +03:00
/**
* ieee802154_alloc_hw - Allocate a new hardware device
*
* This must be called once for each hardware device . The returned pointer
* must be used to refer to this device when calling other functions .
* mac802154 allocates a private data area for the driver pointed to by
* @ priv in & struct ieee802154_hw , the size of this area is given as
* @ priv_data_len .
*
* @ priv_data_len : length of private data
* @ ops : callbacks for this device
*
* Return : A pointer to the new hardware device , or % NULL on error .
*/
2014-10-25 19:16:34 +04:00
struct ieee802154_hw *
2014-10-28 20:21:18 +03:00
ieee802154_alloc_hw ( size_t priv_data_len , const struct ieee802154_ops * ops ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_free_hw - free hardware descriptor
*
* This function frees everything that was allocated , including the
* private data for the driver . You must call ieee802154_unregister_hw ( )
* before calling this function .
*
* @ hw : the hardware to free
*/
2014-10-25 19:16:34 +04:00
void ieee802154_free_hw ( struct ieee802154_hw * hw ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_register_hw - Register hardware device
*
* You must call this function before any other functions in
* mac802154 . Note that before a hardware can be registered , you
* need to fill the contained wpan_phy ' s information .
*
* @ hw : the device to register as returned by ieee802154_alloc_hw ( )
*
* Return : 0 on success . An error code otherwise .
*/
2014-10-25 19:16:34 +04:00
int ieee802154_register_hw ( struct ieee802154_hw * hw ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_unregister_hw - Unregister a hardware device
*
* This function instructs mac802154 to free allocated resources
* and unregister netdevices from the networking subsystem .
*
* @ hw : the hardware to unregister
*/
2014-10-25 19:16:34 +04:00
void ieee802154_unregister_hw ( struct ieee802154_hw * hw ) ;
2012-05-16 00:50:20 +04:00
2015-04-30 18:44:52 +03:00
/**
* ieee802154_rx - receive frame
*
* Use this function to hand received frames to mac802154 . The receive
* buffer in @ skb must start with an IEEE 802.15 .4 header . In case of a
* paged @ skb is used , the driver is recommended to put the ieee802154
* header of the frame on the linear part of the @ skb to avoid memory
* allocation and / or memcpy by the stack .
*
* This function may not be called in IRQ context . Calls to this function
* for a single hardware must be synchronized against each other .
*
* @ hw : the hardware this frame came in on
* @ skb : the buffer to receive , owned by mac802154 after this call
*/
2014-10-27 19:13:30 +03:00
void ieee802154_rx ( struct ieee802154_hw * hw , struct sk_buff * skb ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_rx_irqsafe - receive frame
*
* Like ieee802154_rx ( ) but can be called in IRQ context
* ( internally defers to a tasklet . )
*
* @ hw : the hardware this frame came in on
* @ skb : the buffer to receive , owned by mac802154 after this call
* @ lqi : link quality indicator
*/
2014-10-25 19:16:34 +04:00
void ieee802154_rx_irqsafe ( struct ieee802154_hw * hw , struct sk_buff * skb ,
2012-05-16 00:50:21 +04:00
u8 lqi ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_wake_queue - wake ieee802154 queue
* @ hw : pointer as obtained from ieee802154_alloc_hw ( ) .
*
* Drivers should use this function instead of netif_wake_queue .
*/
2014-10-26 11:37:05 +03:00
void ieee802154_wake_queue ( struct ieee802154_hw * hw ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_stop_queue - stop ieee802154 queue
* @ hw : pointer as obtained from ieee802154_alloc_hw ( ) .
*
* Drivers should use this function instead of netif_stop_queue .
*/
2014-10-26 11:37:05 +03:00
void ieee802154_stop_queue ( struct ieee802154_hw * hw ) ;
2015-04-30 18:44:52 +03:00
/**
* ieee802154_xmit_complete - frame transmission complete
*
* @ hw : pointer as obtained from ieee802154_alloc_hw ( ) .
* @ skb : buffer for transmission
* @ ifs_handling : indicate interframe space handling
*/
2014-11-12 21:51:56 +03:00
void ieee802154_xmit_complete ( struct ieee802154_hw * hw , struct sk_buff * skb ,
bool ifs_handling ) ;
2014-10-26 11:37:05 +03:00
2012-05-16 00:50:19 +04:00
# endif /* NET_MAC802154_H */