mac802154: introduce hw_to_local function
[deliverable/linux.git] / net / mac802154 / mib.c
CommitLineData
ef2486f5 1/*
2 * Copyright 2007-2012 Siemens AG
3 *
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.
7 *
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.
12 *
ef2486f5 13 * Written by:
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>
18 */
19
20#include <linux/if_arp.h>
21
22#include <net/mac802154.h>
b70ab2e8 23#include <net/ieee802154_netdev.h>
5ad60d36 24#include <net/cfg802154.h>
ef2486f5 25
0f1556bc 26#include "ieee802154_i.h"
ef2486f5 27
66b69d4d 28struct phy_chan_notify_work {
29 struct work_struct work;
30 struct net_device *dev;
31};
32
ef2486f5 33struct hw_addr_filt_notify_work {
34 struct work_struct work;
35 struct net_device *dev;
36 unsigned long changed;
37};
38
a5e1ec53 39static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev)
ef2486f5 40{
036562f9 41 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
ef2486f5 42
43 BUG_ON(dev->type != ARPHRD_IEEE802154);
44
04e850fe 45 return sdata->local;
ef2486f5 46}
47
48static void hw_addr_notify(struct work_struct *work)
49{
50 struct hw_addr_filt_notify_work *nw = container_of(work,
51 struct hw_addr_filt_notify_work, work);
a5e1ec53 52 struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev);
ef2486f5 53 int res;
54
a5e1ec53
AA
55 res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt,
56 nw->changed);
ef2486f5 57 if (res)
58 pr_debug("failed changed mask %lx\n", nw->changed);
59
60 kfree(nw);
ef2486f5 61}
62
63static void set_hw_addr_filt(struct net_device *dev, unsigned long changed)
64{
036562f9 65 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
ef2486f5 66 struct hw_addr_filt_notify_work *work;
67
68 work = kzalloc(sizeof(*work), GFP_ATOMIC);
69 if (!work)
70 return;
71
72 INIT_WORK(&work->work, hw_addr_notify);
73 work->dev = dev;
74 work->changed = changed;
04e850fe 75 queue_work(sdata->local->dev_workqueue, &work->work);
ef2486f5 76}
77
b70ab2e8 78void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val)
48e44d50 79{
036562f9 80 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
48e44d50 81
82 BUG_ON(dev->type != ARPHRD_IEEE802154);
83
036562f9
AA
84 spin_lock_bh(&sdata->mib_lock);
85 sdata->short_addr = val;
86 spin_unlock_bh(&sdata->mib_lock);
48e44d50 87
04e850fe
AA
88 if ((sdata->local->ops->set_hw_addr_filt) &&
89 (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) {
90 sdata->local->hw.hw_filt.short_addr = sdata->short_addr;
57205c14 91 set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED);
48e44d50 92 }
93}
94
b70ab2e8 95__le16 mac802154_dev_get_short_addr(const struct net_device *dev)
e885a47a 96{
036562f9 97 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
b70ab2e8 98 __le16 ret;
e885a47a 99
100 BUG_ON(dev->type != ARPHRD_IEEE802154);
101
036562f9
AA
102 spin_lock_bh(&sdata->mib_lock);
103 ret = sdata->short_addr;
104 spin_unlock_bh(&sdata->mib_lock);
e885a47a 105
106 return ret;
107}
108
ef2486f5 109void mac802154_dev_set_ieee_addr(struct net_device *dev)
110{
036562f9 111 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
04e850fe 112 struct ieee802154_local *local = sdata->local;
ef2486f5 113
036562f9 114 sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr);
b70ab2e8 115
a5e1ec53 116 if (local->ops->set_hw_addr_filt &&
036562f9
AA
117 local->hw.hw_filt.ieee_addr != sdata->extended_addr) {
118 local->hw.hw_filt.ieee_addr = sdata->extended_addr;
57205c14 119 set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED);
ef2486f5 120 }
121}
dcbe4f93 122
b70ab2e8 123__le16 mac802154_dev_get_pan_id(const struct net_device *dev)
dcbe4f93 124{
036562f9 125 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
b70ab2e8 126 __le16 ret;
dcbe4f93 127
128 BUG_ON(dev->type != ARPHRD_IEEE802154);
129
036562f9
AA
130 spin_lock_bh(&sdata->mib_lock);
131 ret = sdata->pan_id;
132 spin_unlock_bh(&sdata->mib_lock);
dcbe4f93 133
134 return ret;
135}
136
b70ab2e8 137void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val)
dcbe4f93 138{
036562f9 139 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
dcbe4f93 140
141 BUG_ON(dev->type != ARPHRD_IEEE802154);
142
036562f9
AA
143 spin_lock_bh(&sdata->mib_lock);
144 sdata->pan_id = val;
145 spin_unlock_bh(&sdata->mib_lock);
dcbe4f93 146
04e850fe
AA
147 if ((sdata->local->ops->set_hw_addr_filt) &&
148 (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) {
149 sdata->local->hw.hw_filt.pan_id = sdata->pan_id;
57205c14 150 set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED);
dcbe4f93 151 }
152}
66b69d4d 153
0483546a
TC
154u8 mac802154_dev_get_dsn(const struct net_device *dev)
155{
036562f9 156 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
0483546a
TC
157
158 BUG_ON(dev->type != ARPHRD_IEEE802154);
159
036562f9 160 return sdata->dsn++;
0483546a
TC
161}
162
66b69d4d 163static void phy_chan_notify(struct work_struct *work)
164{
165 struct phy_chan_notify_work *nw = container_of(work,
166 struct phy_chan_notify_work, work);
a5e1ec53 167 struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev);
036562f9 168 struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev);
66b69d4d 169 int res;
170
04e850fe 171 mutex_lock(&sdata->local->phy->pib_lock);
036562f9 172 res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan);
4710d806 173 if (res) {
66b69d4d 174 pr_debug("set_channel failed\n");
4710d806 175 } else {
04e850fe
AA
176 sdata->local->phy->current_channel = sdata->chan;
177 sdata->local->phy->current_page = sdata->page;
9f7f78b4 178 }
04e850fe 179 mutex_unlock(&sdata->local->phy->pib_lock);
66b69d4d 180
181 kfree(nw);
182}
183
184void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan)
185{
036562f9 186 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
66b69d4d 187 struct phy_chan_notify_work *work;
188
189 BUG_ON(dev->type != ARPHRD_IEEE802154);
190
036562f9
AA
191 spin_lock_bh(&sdata->mib_lock);
192 sdata->page = page;
193 sdata->chan = chan;
194 spin_unlock_bh(&sdata->mib_lock);
66b69d4d 195
04e850fe
AA
196 mutex_lock(&sdata->local->phy->pib_lock);
197 if (sdata->local->phy->current_channel != sdata->chan ||
198 sdata->local->phy->current_page != sdata->page) {
199 mutex_unlock(&sdata->local->phy->pib_lock);
9f7f78b4 200
66b69d4d 201 work = kzalloc(sizeof(*work), GFP_ATOMIC);
202 if (!work)
203 return;
204
205 INIT_WORK(&work->work, phy_chan_notify);
206 work->dev = dev;
04e850fe 207 queue_work(sdata->local->dev_workqueue, &work->work);
4710d806 208 } else {
04e850fe 209 mutex_unlock(&sdata->local->phy->pib_lock);
4710d806 210 }
66b69d4d 211}
29e02374
PB
212
213
214int mac802154_get_params(struct net_device *dev,
215 struct ieee802154_llsec_params *params)
216{
036562f9 217 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
218 int res;
219
220 BUG_ON(dev->type != ARPHRD_IEEE802154);
221
036562f9
AA
222 mutex_lock(&sdata->sec_mtx);
223 res = mac802154_llsec_get_params(&sdata->sec, params);
224 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
225
226 return res;
227}
228
229int mac802154_set_params(struct net_device *dev,
230 const struct ieee802154_llsec_params *params,
231 int changed)
232{
036562f9 233 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
234 int res;
235
236 BUG_ON(dev->type != ARPHRD_IEEE802154);
237
036562f9
AA
238 mutex_lock(&sdata->sec_mtx);
239 res = mac802154_llsec_set_params(&sdata->sec, params, changed);
240 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
241
242 return res;
243}
244
245
246int mac802154_add_key(struct net_device *dev,
247 const struct ieee802154_llsec_key_id *id,
248 const struct ieee802154_llsec_key *key)
249{
036562f9 250 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
251 int res;
252
253 BUG_ON(dev->type != ARPHRD_IEEE802154);
254
036562f9
AA
255 mutex_lock(&sdata->sec_mtx);
256 res = mac802154_llsec_key_add(&sdata->sec, id, key);
257 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
258
259 return res;
260}
261
262int mac802154_del_key(struct net_device *dev,
263 const struct ieee802154_llsec_key_id *id)
264{
036562f9 265 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
266 int res;
267
268 BUG_ON(dev->type != ARPHRD_IEEE802154);
269
036562f9
AA
270 mutex_lock(&sdata->sec_mtx);
271 res = mac802154_llsec_key_del(&sdata->sec, id);
272 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
273
274 return res;
275}
276
277
278int mac802154_add_dev(struct net_device *dev,
279 const struct ieee802154_llsec_device *llsec_dev)
280{
036562f9 281 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
282 int res;
283
284 BUG_ON(dev->type != ARPHRD_IEEE802154);
285
036562f9
AA
286 mutex_lock(&sdata->sec_mtx);
287 res = mac802154_llsec_dev_add(&sdata->sec, llsec_dev);
288 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
289
290 return res;
291}
292
293int mac802154_del_dev(struct net_device *dev, __le64 dev_addr)
294{
036562f9 295 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
296 int res;
297
298 BUG_ON(dev->type != ARPHRD_IEEE802154);
299
036562f9
AA
300 mutex_lock(&sdata->sec_mtx);
301 res = mac802154_llsec_dev_del(&sdata->sec, dev_addr);
302 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
303
304 return res;
305}
306
307
308int mac802154_add_devkey(struct net_device *dev,
309 __le64 device_addr,
310 const struct ieee802154_llsec_device_key *key)
311{
036562f9 312 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
313 int res;
314
315 BUG_ON(dev->type != ARPHRD_IEEE802154);
316
036562f9
AA
317 mutex_lock(&sdata->sec_mtx);
318 res = mac802154_llsec_devkey_add(&sdata->sec, device_addr, key);
319 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
320
321 return res;
322}
323
324int mac802154_del_devkey(struct net_device *dev,
325 __le64 device_addr,
326 const struct ieee802154_llsec_device_key *key)
327{
036562f9 328 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
329 int res;
330
331 BUG_ON(dev->type != ARPHRD_IEEE802154);
332
036562f9
AA
333 mutex_lock(&sdata->sec_mtx);
334 res = mac802154_llsec_devkey_del(&sdata->sec, device_addr, key);
335 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
336
337 return res;
338}
339
340
341int mac802154_add_seclevel(struct net_device *dev,
342 const struct ieee802154_llsec_seclevel *sl)
343{
036562f9 344 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
345 int res;
346
347 BUG_ON(dev->type != ARPHRD_IEEE802154);
348
036562f9
AA
349 mutex_lock(&sdata->sec_mtx);
350 res = mac802154_llsec_seclevel_add(&sdata->sec, sl);
351 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
352
353 return res;
354}
355
356int mac802154_del_seclevel(struct net_device *dev,
357 const struct ieee802154_llsec_seclevel *sl)
358{
036562f9 359 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
360 int res;
361
362 BUG_ON(dev->type != ARPHRD_IEEE802154);
363
036562f9
AA
364 mutex_lock(&sdata->sec_mtx);
365 res = mac802154_llsec_seclevel_del(&sdata->sec, sl);
366 mutex_unlock(&sdata->sec_mtx);
29e02374
PB
367
368 return res;
369}
370
371
372void mac802154_lock_table(struct net_device *dev)
373{
036562f9 374 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
375
376 BUG_ON(dev->type != ARPHRD_IEEE802154);
377
036562f9 378 mutex_lock(&sdata->sec_mtx);
29e02374
PB
379}
380
381void mac802154_get_table(struct net_device *dev,
382 struct ieee802154_llsec_table **t)
383{
036562f9 384 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
385
386 BUG_ON(dev->type != ARPHRD_IEEE802154);
387
036562f9 388 *t = &sdata->sec.table;
29e02374
PB
389}
390
391void mac802154_unlock_table(struct net_device *dev)
392{
036562f9 393 struct ieee802154_sub_if_data *sdata = netdev_priv(dev);
29e02374
PB
394
395 BUG_ON(dev->type != ARPHRD_IEEE802154);
396
036562f9 397 mutex_unlock(&sdata->sec_mtx);
29e02374 398}
This page took 0.262366 seconds and 5 git commands to generate.