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