2009-06-08 12:18:49 +00:00
/*
* Netlink inteface for IEEE 802.15 .4 stack
*
* Copyright 2007 , 2008 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 .
*
* 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 - 1301 USA .
*
* Written by :
* Sergey Lapin < slapin @ ossfans . org >
* Dmitry Eremin - Solenikov < dbaryshkov @ gmail . com >
2009-08-07 02:58:40 +00:00
* Maxim Osipov < maxim . osipov @ siemens . com >
2009-06-08 12:18:49 +00:00
*/
# include <linux/kernel.h>
# include <net/genetlink.h>
# include <linux/nl802154.h>
2009-09-14 18:17:36 +04:00
# include "ieee802154.h"
2009-06-08 12:18:49 +00:00
static unsigned int ieee802154_seq_num ;
2009-09-10 18:02:30 +04:00
static DEFINE_SPINLOCK ( ieee802154_seq_lock ) ;
2009-06-08 12:18:49 +00:00
2009-09-14 18:17:36 +04:00
struct genl_family nl802154_family = {
2009-06-08 12:18:49 +00:00
. id = GENL_ID_GENERATE ,
. hdrsize = 0 ,
. name = IEEE802154_NL_NAME ,
. version = 1 ,
. maxattr = IEEE802154_ATTR_MAX ,
} ;
/* Requests to userspace */
2009-09-14 18:17:36 +04:00
struct sk_buff * ieee802154_nl_create ( int flags , u8 req )
2009-06-08 12:18:49 +00:00
{
void * hdr ;
struct sk_buff * msg = nlmsg_new ( NLMSG_GOODSIZE , GFP_ATOMIC ) ;
2009-09-10 18:02:30 +04:00
unsigned long f ;
2009-06-08 12:18:49 +00:00
if ( ! msg )
return NULL ;
2009-09-10 18:02:30 +04:00
spin_lock_irqsave ( & ieee802154_seq_lock , f ) ;
2009-06-08 12:18:49 +00:00
hdr = genlmsg_put ( msg , 0 , ieee802154_seq_num + + ,
2009-09-14 18:17:36 +04:00
& nl802154_family , flags , req ) ;
2009-09-10 18:02:30 +04:00
spin_unlock_irqrestore ( & ieee802154_seq_lock , f ) ;
2009-06-08 12:18:49 +00:00
if ( ! hdr ) {
nlmsg_free ( msg ) ;
return NULL ;
}
return msg ;
}
2009-09-14 18:17:36 +04:00
int ieee802154_nl_mcast ( struct sk_buff * msg , unsigned int group )
2009-06-08 12:18:49 +00:00
{
/* XXX: nlh is right at the start of msg */
void * hdr = genlmsg_data ( NLMSG_DATA ( msg - > data ) ) ;
2009-08-07 02:58:40 +00:00
if ( genlmsg_end ( msg , hdr ) < 0 )
2009-06-08 12:18:49 +00:00
goto out ;
2009-09-14 18:17:36 +04:00
return genlmsg_multicast ( msg , 0 , group , GFP_ATOMIC ) ;
2009-06-08 12:18:49 +00:00
out :
nlmsg_free ( msg ) ;
return - ENOBUFS ;
}
2009-11-04 18:05:38 +03:00
struct sk_buff * ieee802154_nl_new_reply ( struct genl_info * info ,
int flags , u8 req )
{
void * hdr ;
struct sk_buff * msg = nlmsg_new ( NLMSG_GOODSIZE , GFP_ATOMIC ) ;
if ( ! msg )
return NULL ;
hdr = genlmsg_put_reply ( msg , info ,
& nl802154_family , flags , req ) ;
if ( ! hdr ) {
nlmsg_free ( msg ) ;
return NULL ;
}
return msg ;
}
int ieee802154_nl_reply ( struct sk_buff * msg , struct genl_info * info )
{
/* XXX: nlh is right at the start of msg */
void * hdr = genlmsg_data ( NLMSG_DATA ( msg - > data ) ) ;
if ( genlmsg_end ( msg , hdr ) < 0 )
goto out ;
return genlmsg_reply ( msg , info ) ;
out :
nlmsg_free ( msg ) ;
return - ENOBUFS ;
}
2009-09-10 17:50:12 +04:00
int __init ieee802154_nl_init ( void )
2009-06-08 12:18:49 +00:00
{
int rc ;
2009-09-14 18:17:36 +04:00
rc = genl_register_family ( & nl802154_family ) ;
2009-06-08 12:18:49 +00:00
if ( rc )
goto fail ;
2009-09-14 18:17:36 +04:00
rc = nl802154_mac_register ( ) ;
2009-06-08 12:18:49 +00:00
if ( rc )
goto fail ;
2009-09-15 17:04:44 +04:00
rc = nl802154_phy_register ( ) ;
if ( rc )
goto fail ;
2009-06-08 12:18:49 +00:00
return 0 ;
fail :
2009-09-14 18:17:36 +04:00
genl_unregister_family ( & nl802154_family ) ;
2009-06-08 12:18:49 +00:00
return rc ;
}
2009-09-10 17:50:12 +04:00
void __exit ieee802154_nl_exit ( void )
2009-06-08 12:18:49 +00:00
{
2009-09-14 18:17:36 +04:00
genl_unregister_family ( & nl802154_family ) ;
2009-06-08 12:18:49 +00:00
}
2009-06-19 17:02:09 +04:00