2014-11-02 06:18:36 +03:00
/* 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 .
*
* Authors :
* Alexander Aring < aar @ pengutronix . de >
*
* Based on : net / mac80211 / cfg . c
*/
2014-11-05 22:51:17 +03:00
# include <net/rtnetlink.h>
2014-11-02 06:18:36 +03:00
# include <net/cfg802154.h>
2014-11-02 06:18:38 +03:00
# include "ieee802154_i.h"
2014-11-12 05:36:55 +03:00
# include "driver-ops.h"
2014-11-02 23:43:05 +03:00
# include "cfg.h"
2014-11-02 06:18:38 +03:00
static struct net_device *
ieee802154_add_iface_deprecated ( struct wpan_phy * wpan_phy ,
const char * name , int type )
{
2014-11-05 22:51:15 +03:00
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
2014-11-05 22:51:17 +03:00
struct net_device * dev ;
2014-11-05 22:51:15 +03:00
2014-11-05 22:51:17 +03:00
rtnl_lock ( ) ;
2014-11-17 10:20:50 +03:00
dev = ieee802154_if_add ( local , name , type ) ;
2014-11-05 22:51:17 +03:00
rtnl_unlock ( ) ;
return dev ;
2014-11-02 06:18:38 +03:00
}
static void ieee802154_del_iface_deprecated ( struct wpan_phy * wpan_phy ,
struct net_device * dev )
{
2014-11-05 22:51:14 +03:00
struct ieee802154_sub_if_data * sdata = IEEE802154_DEV_TO_SUB_IF ( dev ) ;
ieee802154_if_remove ( sdata ) ;
2014-11-02 06:18:38 +03:00
}
2014-11-17 10:20:51 +03:00
static int
ieee802154_add_iface ( struct wpan_phy * phy , const char * name ,
enum nl802154_iftype type )
{
struct ieee802154_local * local = wpan_phy_priv ( phy ) ;
struct net_device * err ;
err = ieee802154_if_add ( local , name , type ) ;
if ( IS_ERR ( err ) )
return PTR_ERR ( err ) ;
return 0 ;
}
2014-11-12 05:36:55 +03:00
static int
2014-11-17 10:20:46 +03:00
ieee802154_set_channel ( struct wpan_phy * wpan_phy , u8 page , u8 channel )
2014-11-12 05:36:55 +03:00
{
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
int ret ;
ASSERT_RTNL ( ) ;
/* check if phy support this setting */
if ( ! ( wpan_phy - > channels_supported [ page ] & BIT ( channel ) ) )
return - EINVAL ;
ret = drv_set_channel ( local , page , channel ) ;
if ( ! ret ) {
wpan_phy - > current_page = page ;
wpan_phy - > current_channel = channel ;
}
return ret ;
}
2014-11-17 10:20:46 +03:00
static int
ieee802154_set_pan_id ( struct wpan_phy * wpan_phy , struct wpan_dev * wpan_dev ,
u16 pan_id )
2014-11-12 05:36:57 +03:00
{
ASSERT_RTNL ( ) ;
/* TODO
* I am not sure about to check here on broadcast pan_id .
* Broadcast is a valid setting , comment from 802.15 .4 :
* If this value is 0xffff , the device is not associated .
*
* This could useful to simple deassociate an device .
*/
if ( pan_id = = IEEE802154_PAN_ID_BROADCAST )
return - EINVAL ;
wpan_dev - > pan_id = cpu_to_le16 ( pan_id ) ;
return 0 ;
}
2014-11-12 05:36:59 +03:00
static int
ieee802154_set_backoff_exponent ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
2014-11-17 10:20:46 +03:00
u8 min_be , u8 max_be )
2014-11-12 05:36:59 +03:00
{
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
ASSERT_RTNL ( ) ;
if ( ! ( local - > hw . flags & IEEE802154_HW_CSMA_PARAMS ) )
return - EOPNOTSUPP ;
wpan_dev - > min_be = min_be ;
wpan_dev - > max_be = max_be ;
return 0 ;
}
2014-11-12 05:36:58 +03:00
static int
ieee802154_set_short_addr ( struct wpan_phy * wpan_phy , struct wpan_dev * wpan_dev ,
2014-11-17 10:20:46 +03:00
u16 short_addr )
2014-11-12 05:36:58 +03:00
{
ASSERT_RTNL ( ) ;
/* TODO
* I am not sure about to check here on broadcast short_addr .
* Broadcast is a valid setting , comment from 802.15 .4 :
* A value of 0xfffe indicates that the device has
* associated but has not been allocated an address . A
* value of 0xffff indicates that the device does not
* have a short address .
*
* I think we should allow to set these settings but
* don ' t allow to allow socket communication with it .
*/
if ( short_addr = = IEEE802154_ADDR_SHORT_UNSPEC | |
short_addr = = IEEE802154_ADDR_SHORT_BROADCAST )
return - EINVAL ;
wpan_dev - > short_addr = cpu_to_le16 ( short_addr ) ;
return 0 ;
}
2014-11-17 10:20:46 +03:00
static int
ieee802154_set_max_csma_backoffs ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
u8 max_csma_backoffs )
2014-11-12 05:37:01 +03:00
{
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
ASSERT_RTNL ( ) ;
if ( ! ( local - > hw . flags & IEEE802154_HW_CSMA_PARAMS ) )
return - EOPNOTSUPP ;
wpan_dev - > csma_retries = max_csma_backoffs ;
return 0 ;
}
2014-11-17 10:20:46 +03:00
static int
ieee802154_set_max_frame_retries ( struct wpan_phy * wpan_phy ,
struct wpan_dev * wpan_dev ,
s8 max_frame_retries )
2014-11-12 05:37:03 +03:00
{
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
ASSERT_RTNL ( ) ;
if ( ! ( local - > hw . flags & IEEE802154_HW_FRAME_RETRIES ) )
return - EOPNOTSUPP ;
wpan_dev - > frame_retries = max_frame_retries ;
return 0 ;
}
2014-11-17 10:20:46 +03:00
static int
ieee802154_set_lbt_mode ( struct wpan_phy * wpan_phy , struct wpan_dev * wpan_dev ,
bool mode )
2014-11-12 05:37:05 +03:00
{
struct ieee802154_local * local = wpan_phy_priv ( wpan_phy ) ;
ASSERT_RTNL ( ) ;
if ( ! ( local - > hw . flags & IEEE802154_HW_LBT ) )
return - EOPNOTSUPP ;
wpan_dev - > lbt = mode ;
return 0 ;
}
2014-11-02 06:18:36 +03:00
const struct cfg802154_ops mac802154_config_ops = {
2014-11-02 06:18:38 +03:00
. add_virtual_intf_deprecated = ieee802154_add_iface_deprecated ,
. del_virtual_intf_deprecated = ieee802154_del_iface_deprecated ,
2014-11-17 10:20:51 +03:00
. add_virtual_intf = ieee802154_add_iface ,
2014-11-12 05:36:55 +03:00
. set_channel = ieee802154_set_channel ,
2014-11-12 05:36:57 +03:00
. set_pan_id = ieee802154_set_pan_id ,
2014-11-12 05:36:58 +03:00
. set_short_addr = ieee802154_set_short_addr ,
2014-11-12 05:36:59 +03:00
. set_backoff_exponent = ieee802154_set_backoff_exponent ,
2014-11-12 05:37:01 +03:00
. set_max_csma_backoffs = ieee802154_set_max_csma_backoffs ,
2014-11-12 05:37:03 +03:00
. set_max_frame_retries = ieee802154_set_max_frame_retries ,
2014-11-12 05:37:05 +03:00
. set_lbt_mode = ieee802154_set_lbt_mode ,
2014-11-02 06:18:36 +03:00
} ;