2 * Copyright 2007-2012 Siemens AG
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
15 * Sergey Lapin <slapin@ossfans.org>
16 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
17 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
20 #include <linux/if_arp.h>
22 #include <net/mac802154.h>
23 #include <net/ieee802154_netdev.h>
24 #include <net/cfg802154.h>
26 #include "ieee802154_i.h"
27 #include "driver-ops.h"
29 struct hw_addr_filt_notify_work
{
30 struct work_struct work
;
31 struct net_device
*dev
;
32 unsigned long changed
;
35 static struct ieee802154_local
*mac802154_slave_get_priv(struct net_device
*dev
)
37 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
39 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
44 static void hw_addr_notify(struct work_struct
*work
)
46 struct hw_addr_filt_notify_work
*nw
= container_of(work
,
47 struct hw_addr_filt_notify_work
, work
);
48 struct ieee802154_local
*local
= mac802154_slave_get_priv(nw
->dev
);
51 res
= local
->ops
->set_hw_addr_filt(&local
->hw
, &local
->hw
.hw_filt
,
54 pr_debug("failed changed mask %lx\n", nw
->changed
);
59 static void set_hw_addr_filt(struct net_device
*dev
, unsigned long changed
)
61 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
62 struct hw_addr_filt_notify_work
*work
;
64 work
= kzalloc(sizeof(*work
), GFP_ATOMIC
);
68 INIT_WORK(&work
->work
, hw_addr_notify
);
70 work
->changed
= changed
;
71 queue_work(sdata
->local
->workqueue
, &work
->work
);
74 void mac802154_dev_set_short_addr(struct net_device
*dev
, __le16 val
)
76 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
78 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
80 spin_lock_bh(&sdata
->mib_lock
);
81 sdata
->short_addr
= val
;
82 spin_unlock_bh(&sdata
->mib_lock
);
84 if ((sdata
->local
->ops
->set_hw_addr_filt
) &&
85 (sdata
->local
->hw
.hw_filt
.short_addr
!= sdata
->short_addr
)) {
86 sdata
->local
->hw
.hw_filt
.short_addr
= sdata
->short_addr
;
87 set_hw_addr_filt(dev
, IEEE802154_AFILT_SADDR_CHANGED
);
91 __le16
mac802154_dev_get_short_addr(const struct net_device
*dev
)
93 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
96 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
98 spin_lock_bh(&sdata
->mib_lock
);
99 ret
= sdata
->short_addr
;
100 spin_unlock_bh(&sdata
->mib_lock
);
105 void mac802154_dev_set_ieee_addr(struct net_device
*dev
)
107 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
108 struct ieee802154_local
*local
= sdata
->local
;
110 sdata
->extended_addr
= ieee802154_devaddr_from_raw(dev
->dev_addr
);
112 if (local
->ops
->set_hw_addr_filt
&&
113 local
->hw
.hw_filt
.ieee_addr
!= sdata
->extended_addr
) {
114 local
->hw
.hw_filt
.ieee_addr
= sdata
->extended_addr
;
115 set_hw_addr_filt(dev
, IEEE802154_AFILT_IEEEADDR_CHANGED
);
119 __le16
mac802154_dev_get_pan_id(const struct net_device
*dev
)
121 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
124 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
126 spin_lock_bh(&sdata
->mib_lock
);
128 spin_unlock_bh(&sdata
->mib_lock
);
133 void mac802154_dev_set_pan_id(struct net_device
*dev
, __le16 val
)
135 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
137 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
139 spin_lock_bh(&sdata
->mib_lock
);
141 spin_unlock_bh(&sdata
->mib_lock
);
143 if ((sdata
->local
->ops
->set_hw_addr_filt
) &&
144 (sdata
->local
->hw
.hw_filt
.pan_id
!= sdata
->pan_id
)) {
145 sdata
->local
->hw
.hw_filt
.pan_id
= sdata
->pan_id
;
146 set_hw_addr_filt(dev
, IEEE802154_AFILT_PANID_CHANGED
);
150 u8
mac802154_dev_get_dsn(const struct net_device
*dev
)
152 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
154 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
159 void mac802154_dev_set_page_channel(struct net_device
*dev
, u8 page
, u8 chan
)
161 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
162 struct ieee802154_local
*local
= sdata
->local
;
165 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
167 res
= drv_set_channel(local
, page
, chan
);
169 pr_debug("set_channel failed\n");
171 mutex_lock(&local
->phy
->pib_lock
);
172 local
->phy
->current_channel
= chan
;
173 local
->phy
->current_page
= page
;
174 mutex_unlock(&local
->phy
->pib_lock
);
179 int mac802154_get_params(struct net_device
*dev
,
180 struct ieee802154_llsec_params
*params
)
182 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
185 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
187 mutex_lock(&sdata
->sec_mtx
);
188 res
= mac802154_llsec_get_params(&sdata
->sec
, params
);
189 mutex_unlock(&sdata
->sec_mtx
);
194 int mac802154_set_params(struct net_device
*dev
,
195 const struct ieee802154_llsec_params
*params
,
198 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
201 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
203 mutex_lock(&sdata
->sec_mtx
);
204 res
= mac802154_llsec_set_params(&sdata
->sec
, params
, changed
);
205 mutex_unlock(&sdata
->sec_mtx
);
211 int mac802154_add_key(struct net_device
*dev
,
212 const struct ieee802154_llsec_key_id
*id
,
213 const struct ieee802154_llsec_key
*key
)
215 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
218 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
220 mutex_lock(&sdata
->sec_mtx
);
221 res
= mac802154_llsec_key_add(&sdata
->sec
, id
, key
);
222 mutex_unlock(&sdata
->sec_mtx
);
227 int mac802154_del_key(struct net_device
*dev
,
228 const struct ieee802154_llsec_key_id
*id
)
230 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
233 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
235 mutex_lock(&sdata
->sec_mtx
);
236 res
= mac802154_llsec_key_del(&sdata
->sec
, id
);
237 mutex_unlock(&sdata
->sec_mtx
);
243 int mac802154_add_dev(struct net_device
*dev
,
244 const struct ieee802154_llsec_device
*llsec_dev
)
246 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
249 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
251 mutex_lock(&sdata
->sec_mtx
);
252 res
= mac802154_llsec_dev_add(&sdata
->sec
, llsec_dev
);
253 mutex_unlock(&sdata
->sec_mtx
);
258 int mac802154_del_dev(struct net_device
*dev
, __le64 dev_addr
)
260 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
263 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
265 mutex_lock(&sdata
->sec_mtx
);
266 res
= mac802154_llsec_dev_del(&sdata
->sec
, dev_addr
);
267 mutex_unlock(&sdata
->sec_mtx
);
273 int mac802154_add_devkey(struct net_device
*dev
,
275 const struct ieee802154_llsec_device_key
*key
)
277 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
280 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
282 mutex_lock(&sdata
->sec_mtx
);
283 res
= mac802154_llsec_devkey_add(&sdata
->sec
, device_addr
, key
);
284 mutex_unlock(&sdata
->sec_mtx
);
289 int mac802154_del_devkey(struct net_device
*dev
,
291 const struct ieee802154_llsec_device_key
*key
)
293 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
296 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
298 mutex_lock(&sdata
->sec_mtx
);
299 res
= mac802154_llsec_devkey_del(&sdata
->sec
, device_addr
, key
);
300 mutex_unlock(&sdata
->sec_mtx
);
306 int mac802154_add_seclevel(struct net_device
*dev
,
307 const struct ieee802154_llsec_seclevel
*sl
)
309 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
312 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
314 mutex_lock(&sdata
->sec_mtx
);
315 res
= mac802154_llsec_seclevel_add(&sdata
->sec
, sl
);
316 mutex_unlock(&sdata
->sec_mtx
);
321 int mac802154_del_seclevel(struct net_device
*dev
,
322 const struct ieee802154_llsec_seclevel
*sl
)
324 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
327 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
329 mutex_lock(&sdata
->sec_mtx
);
330 res
= mac802154_llsec_seclevel_del(&sdata
->sec
, sl
);
331 mutex_unlock(&sdata
->sec_mtx
);
337 void mac802154_lock_table(struct net_device
*dev
)
339 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
341 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
343 mutex_lock(&sdata
->sec_mtx
);
346 void mac802154_get_table(struct net_device
*dev
,
347 struct ieee802154_llsec_table
**t
)
349 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
351 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
353 *t
= &sdata
->sec
.table
;
356 void mac802154_unlock_table(struct net_device
*dev
)
358 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
360 BUG_ON(dev
->type
!= ARPHRD_IEEE802154
);
362 mutex_unlock(&sdata
->sec_mtx
);