aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorsjur.brandeland@stericsson.com <sjur.brandeland@stericsson.com>2011-05-12 22:44:05 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-15 17:45:55 -0400
commitbee925db9a77a5736596dcf6f91d0879f5ee915b (patch)
tree57a3b499d5b8ec3cb9d36be674e165fa1e7eed42 /net
parentb3ccfbe4098a5542177d0f34e8979f32e7d606e1 (diff)
caif: prepare support for namespaces
Use struct net to reference CAIF configuration object instead of static variables. Refactor functions caif_connect_client, caif_disconnect_client and squach files cfcnfg.c and caif_config_utils. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/caif/Makefile2
-rw-r--r--net/caif/caif_config_util.c99
-rw-r--r--net/caif/caif_dev.c77
-rw-r--r--net/caif/caif_socket.c6
-rw-r--r--net/caif/cfcnfg.c146
-rw-r--r--net/caif/chnl_net.c12
6 files changed, 162 insertions, 180 deletions
diff --git a/net/caif/Makefile b/net/caif/Makefile
index 9d38e406e4a4..ebcd4e7e6f47 100644
--- a/net/caif/Makefile
+++ b/net/caif/Makefile
@@ -5,7 +5,7 @@ caif-y := caif_dev.o \
5 cffrml.o cfveil.o cfdbgl.o\ 5 cffrml.o cfveil.o cfdbgl.o\
6 cfserl.o cfdgml.o \ 6 cfserl.o cfdgml.o \
7 cfrfml.o cfvidl.o cfutill.o \ 7 cfrfml.o cfvidl.o cfutill.o \
8 cfsrvl.o cfpkt_skbuff.o caif_config_util.o 8 cfsrvl.o cfpkt_skbuff.o
9 9
10obj-$(CONFIG_CAIF) += caif.o 10obj-$(CONFIG_CAIF) += caif.o
11obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o 11obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c
deleted file mode 100644
index 9b63e4e3910e..000000000000
--- a/net/caif/caif_config_util.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright (C) ST-Ericsson AB 2010
3 * Author: Sjur Brendeland sjur.brandeland@stericsson.com
4 * License terms: GNU General Public License (GPL) version 2
5 */
6
7#include <linux/module.h>
8#include <linux/spinlock.h>
9#include <net/caif/cfctrl.h>
10#include <net/caif/cfcnfg.h>
11#include <net/caif/caif_dev.h>
12
13int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
14 struct caif_connect_request *s,
15 struct cfctrl_link_param *l)
16{
17 struct dev_info *dev_info;
18 enum cfcnfg_phy_preference pref;
19 int res;
20
21 memset(l, 0, sizeof(*l));
22 /* In caif protocol low value is high priority */
23 l->priority = CAIF_PRIO_MAX - s->priority + 1;
24
25 if (s->ifindex != 0){
26 res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
27 if (res < 0)
28 return res;
29 l->phyid = res;
30 }
31 else {
32 switch (s->link_selector) {
33 case CAIF_LINK_HIGH_BANDW:
34 pref = CFPHYPREF_HIGH_BW;
35 break;
36 case CAIF_LINK_LOW_LATENCY:
37 pref = CFPHYPREF_LOW_LAT;
38 break;
39 default:
40 return -EINVAL;
41 }
42 dev_info = cfcnfg_get_phyid(cnfg, pref);
43 if (dev_info == NULL)
44 return -ENODEV;
45 l->phyid = dev_info->id;
46 }
47 switch (s->protocol) {
48 case CAIFPROTO_AT:
49 l->linktype = CFCTRL_SRV_VEI;
50 if (s->sockaddr.u.at.type == CAIF_ATTYPE_PLAIN)
51 l->chtype = 0x02;
52 else
53 l->chtype = s->sockaddr.u.at.type;
54 l->endpoint = 0x00;
55 break;
56 case CAIFPROTO_DATAGRAM:
57 l->linktype = CFCTRL_SRV_DATAGRAM;
58 l->chtype = 0x00;
59 l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
60 break;
61 case CAIFPROTO_DATAGRAM_LOOP:
62 l->linktype = CFCTRL_SRV_DATAGRAM;
63 l->chtype = 0x03;
64 l->endpoint = 0x00;
65 l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
66 break;
67 case CAIFPROTO_RFM:
68 l->linktype = CFCTRL_SRV_RFM;
69 l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
70 strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
71 sizeof(l->u.rfm.volume)-1);
72 l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
73 break;
74 case CAIFPROTO_UTIL:
75 l->linktype = CFCTRL_SRV_UTIL;
76 l->endpoint = 0x00;
77 l->chtype = 0x00;
78 strncpy(l->u.utility.name, s->sockaddr.u.util.service,
79 sizeof(l->u.utility.name)-1);
80 l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
81 caif_assert(sizeof(l->u.utility.name) > 10);
82 l->u.utility.paramlen = s->param.size;
83 if (l->u.utility.paramlen > sizeof(l->u.utility.params))
84 l->u.utility.paramlen = sizeof(l->u.utility.params);
85
86 memcpy(l->u.utility.params, s->param.data,
87 l->u.utility.paramlen);
88
89 break;
90 case CAIFPROTO_DEBUG:
91 l->linktype = CFCTRL_SRV_DBG;
92 l->endpoint = s->sockaddr.u.dbg.service;
93 l->chtype = s->sockaddr.u.dbg.type;
94 break;
95 default:
96 return -EINVAL;
97 }
98 return 0;
99}
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 6d1d86be187b..0e651cf577cf 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -21,7 +21,6 @@
21#include <net/net_namespace.h> 21#include <net/net_namespace.h>
22#include <net/pkt_sched.h> 22#include <net/pkt_sched.h>
23#include <net/caif/caif_device.h> 23#include <net/caif/caif_device.h>
24#include <net/caif/caif_dev.h>
25#include <net/caif/caif_layer.h> 24#include <net/caif/caif_layer.h>
26#include <net/caif/cfpkt.h> 25#include <net/caif/cfpkt.h>
27#include <net/caif/cfcnfg.h> 26#include <net/caif/cfcnfg.h>
@@ -43,11 +42,21 @@ struct caif_device_entry_list {
43}; 42};
44 43
45struct caif_net { 44struct caif_net {
45 struct cfcnfg *cfg;
46 struct caif_device_entry_list caifdevs; 46 struct caif_device_entry_list caifdevs;
47}; 47};
48 48
49static int caif_net_id; 49static int caif_net_id;
50static struct cfcnfg *cfg; 50
51struct cfcnfg *get_cfcnfg(struct net *net)
52{
53 struct caif_net *caifn;
54 BUG_ON(!net);
55 caifn = net_generic(net, caif_net_id);
56 BUG_ON(!caifn);
57 return caifn->cfg;
58}
59EXPORT_SYMBOL(get_cfcnfg);
51 60
52static struct caif_device_entry_list *caif_device_list(struct net *net) 61static struct caif_device_entry_list *caif_device_list(struct net *net)
53{ 62{
@@ -191,12 +200,17 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
191 struct caif_dev_common *caifdev; 200 struct caif_dev_common *caifdev;
192 enum cfcnfg_phy_preference pref; 201 enum cfcnfg_phy_preference pref;
193 enum cfcnfg_phy_type phy_type; 202 enum cfcnfg_phy_type phy_type;
203 struct cfcnfg *cfg;
194 struct caif_device_entry_list *caifdevs = 204 struct caif_device_entry_list *caifdevs =
195 caif_device_list(dev_net(dev)); 205 caif_device_list(dev_net(dev));
196 206
197 if (dev->type != ARPHRD_CAIF) 207 if (dev->type != ARPHRD_CAIF)
198 return 0; 208 return 0;
199 209
210 cfg = get_cfcnfg(dev_net(dev));
211 if (cfg == NULL)
212 return 0;
213
200 switch (what) { 214 switch (what) {
201 case NETDEV_REGISTER: 215 case NETDEV_REGISTER:
202 caifd = caif_device_alloc(dev); 216 caifd = caif_device_alloc(dev);
@@ -235,7 +249,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
235 phy_type, 249 phy_type,
236 dev, 250 dev,
237 &caifd->layer, 251 &caifd->layer,
238 0,
239 pref, 252 pref,
240 caifdev->use_fcs, 253 caifdev->use_fcs,
241 caifdev->use_stx); 254 caifdev->use_stx);
@@ -323,35 +336,20 @@ static struct notifier_block caif_device_notifier = {
323 .priority = 0, 336 .priority = 0,
324}; 337};
325 338
326int caif_connect_client(struct caif_connect_request *conn_req,
327 struct cflayer *client_layer, int *ifindex,
328 int *headroom, int *tailroom)
329{
330 struct cfctrl_link_param param;
331 int ret;
332
333 ret = caif_connect_req_to_link_param(cfg, conn_req, &param);
334 if (ret)
335 return ret;
336 /* Hook up the adaptation layer. */
337 return cfcnfg_add_adaptation_layer(cfg, &param,
338 client_layer, ifindex,
339 headroom, tailroom);
340}
341EXPORT_SYMBOL(caif_connect_client);
342
343int caif_disconnect_client(struct cflayer *adap_layer)
344{
345 return cfcnfg_disconn_adapt_layer(cfg, adap_layer);
346}
347EXPORT_SYMBOL(caif_disconnect_client);
348
349/* Per-namespace Caif devices handling */ 339/* Per-namespace Caif devices handling */
350static int caif_init_net(struct net *net) 340static int caif_init_net(struct net *net)
351{ 341{
352 struct caif_net *caifn = net_generic(net, caif_net_id); 342 struct caif_net *caifn = net_generic(net, caif_net_id);
343 BUG_ON(!caifn);
353 INIT_LIST_HEAD(&caifn->caifdevs.list); 344 INIT_LIST_HEAD(&caifn->caifdevs.list);
354 mutex_init(&caifn->caifdevs.lock); 345 mutex_init(&caifn->caifdevs.lock);
346
347 caifn->cfg = cfcnfg_create();
348 if (!caifn->cfg) {
349 pr_warn("can't create cfcnfg\n");
350 return -ENOMEM;
351 }
352
355 return 0; 353 return 0;
356} 354}
357 355
@@ -360,10 +358,17 @@ static void caif_exit_net(struct net *net)
360 struct caif_device_entry *caifd, *tmp; 358 struct caif_device_entry *caifd, *tmp;
361 struct caif_device_entry_list *caifdevs = 359 struct caif_device_entry_list *caifdevs =
362 caif_device_list(net); 360 caif_device_list(net);
361 struct cfcnfg *cfg;
363 362
364 rtnl_lock(); 363 rtnl_lock();
365 mutex_lock(&caifdevs->lock); 364 mutex_lock(&caifdevs->lock);
366 365
366 cfg = get_cfcnfg(net);
367 if (cfg == NULL) {
368 mutex_unlock(&caifdevs->lock);
369 return;
370 }
371
367 list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) { 372 list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
368 int i = 0; 373 int i = 0;
369 list_del_rcu(&caifd->list); 374 list_del_rcu(&caifd->list);
@@ -382,7 +387,7 @@ static void caif_exit_net(struct net *net)
382 free_percpu(caifd->pcpu_refcnt); 387 free_percpu(caifd->pcpu_refcnt);
383 kfree(caifd); 388 kfree(caifd);
384 } 389 }
385 390 cfcnfg_remove(cfg);
386 391
387 mutex_unlock(&caifdevs->lock); 392 mutex_unlock(&caifdevs->lock);
388 rtnl_unlock(); 393 rtnl_unlock();
@@ -400,32 +405,22 @@ static int __init caif_device_init(void)
400{ 405{
401 int result; 406 int result;
402 407
403 cfg = cfcnfg_create();
404 if (!cfg) {
405 pr_warn("can't create cfcnfg\n");
406 goto err_cfcnfg_create_failed;
407 }
408 result = register_pernet_device(&caif_net_ops); 408 result = register_pernet_device(&caif_net_ops);
409 409
410 if (result) { 410 if (result)
411 kfree(cfg);
412 cfg = NULL;
413 return result; 411 return result;
414 } 412
415 dev_add_pack(&caif_packet_type);
416 register_netdevice_notifier(&caif_device_notifier); 413 register_netdevice_notifier(&caif_device_notifier);
414 dev_add_pack(&caif_packet_type);
417 415
418 return result; 416 return result;
419err_cfcnfg_create_failed:
420 return -ENODEV;
421} 417}
422 418
423static void __exit caif_device_exit(void) 419static void __exit caif_device_exit(void)
424{ 420{
425 dev_remove_pack(&caif_packet_type);
426 unregister_pernet_device(&caif_net_ops); 421 unregister_pernet_device(&caif_net_ops);
427 unregister_netdevice_notifier(&caif_device_notifier); 422 unregister_netdevice_notifier(&caif_device_notifier);
428 cfcnfg_remove(cfg); 423 dev_remove_pack(&caif_packet_type);
429} 424}
430 425
431module_init(caif_device_init); 426module_init(caif_device_init);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 01f612df7df1..653db759eb7e 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -810,7 +810,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
810 sk->sk_state == CAIF_DISCONNECTED); 810 sk->sk_state == CAIF_DISCONNECTED);
811 if (sk->sk_shutdown & SHUTDOWN_MASK) { 811 if (sk->sk_shutdown & SHUTDOWN_MASK) {
812 /* Allow re-connect after SHUTDOWN_IND */ 812 /* Allow re-connect after SHUTDOWN_IND */
813 caif_disconnect_client(&cf_sk->layer); 813 caif_disconnect_client(sock_net(sk), &cf_sk->layer);
814 break; 814 break;
815 } 815 }
816 /* No reconnect on a seqpacket socket */ 816 /* No reconnect on a seqpacket socket */
@@ -851,7 +851,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
851 dbfs_atomic_inc(&cnt.num_connect_req); 851 dbfs_atomic_inc(&cnt.num_connect_req);
852 cf_sk->layer.receive = caif_sktrecv_cb; 852 cf_sk->layer.receive = caif_sktrecv_cb;
853 853
854 err = caif_connect_client(&cf_sk->conn_req, 854 err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
855 &cf_sk->layer, &ifindex, &headroom, &tailroom); 855 &cf_sk->layer, &ifindex, &headroom, &tailroom);
856 856
857 if (err < 0) { 857 if (err < 0) {
@@ -949,7 +949,7 @@ static int caif_release(struct socket *sock)
949 949
950 if (cf_sk->sk.sk_socket->state == SS_CONNECTED || 950 if (cf_sk->sk.sk_socket->state == SS_CONNECTED ||
951 cf_sk->sk.sk_socket->state == SS_CONNECTING) 951 cf_sk->sk.sk_socket->state == SS_CONNECTING)
952 res = caif_disconnect_client(&cf_sk->layer); 952 res = caif_disconnect_client(sock_net(sk), &cf_sk->layer);
953 953
954 cf_sk->sk.sk_socket->state = SS_DISCONNECTING; 954 cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
955 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); 955 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
index 3f4f31fca2c1..e857d8995ca3 100644
--- a/net/caif/cfcnfg.c
+++ b/net/caif/cfcnfg.c
@@ -150,7 +150,7 @@ static void cfctrl_enum_resp(void)
150{ 150{
151} 151}
152 152
153struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, 153static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
154 enum cfcnfg_phy_preference phy_pref) 154 enum cfcnfg_phy_preference phy_pref)
155{ 155{
156 /* Try to match with specified preference */ 156 /* Try to match with specified preference */
@@ -171,7 +171,7 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
171 return NULL; 171 return NULL;
172} 172}
173 173
174int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) 174static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
175{ 175{
176 struct cfcnfg_phyinfo *phy; 176 struct cfcnfg_phyinfo *phy;
177 177
@@ -181,11 +181,12 @@ int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
181 return -ENODEV; 181 return -ENODEV;
182} 182}
183 183
184int cfcnfg_disconn_adapt_layer(struct cfcnfg *cfg, struct cflayer *adap_layer) 184int caif_disconnect_client(struct net *net, struct cflayer *adap_layer)
185{ 185{
186 u8 channel_id = 0; 186 u8 channel_id = 0;
187 int ret = 0; 187 int ret = 0;
188 struct cflayer *servl = NULL; 188 struct cflayer *servl = NULL;
189 struct cfcnfg *cfg = get_cfcnfg(net);
189 190
190 caif_assert(adap_layer != NULL); 191 caif_assert(adap_layer != NULL);
191 192
@@ -217,14 +218,7 @@ end:
217 return ret; 218 return ret;
218 219
219} 220}
220EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer); 221EXPORT_SYMBOL(caif_disconnect_client);
221
222void cfcnfg_release_adap_layer(struct cflayer *adap_layer)
223{
224 if (adap_layer->dn)
225 cfsrvl_put(adap_layer->dn);
226}
227EXPORT_SYMBOL(cfcnfg_release_adap_layer);
228 222
229static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) 223static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
230{ 224{
@@ -238,19 +232,109 @@ static const int protohead[CFCTRL_SRV_MASK] = {
238 [CFCTRL_SRV_DBG] = 3, 232 [CFCTRL_SRV_DBG] = 3,
239}; 233};
240 234
241int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, 235
242 struct cfctrl_link_param *param, 236static int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
243 struct cflayer *adap_layer, 237 struct caif_connect_request *s,
244 int *ifindex, 238 struct cfctrl_link_param *l)
239{
240 struct dev_info *dev_info;
241 enum cfcnfg_phy_preference pref;
242 int res;
243
244 memset(l, 0, sizeof(*l));
245 /* In caif protocol low value is high priority */
246 l->priority = CAIF_PRIO_MAX - s->priority + 1;
247
248 if (s->ifindex != 0) {
249 res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
250 if (res < 0)
251 return res;
252 l->phyid = res;
253 } else {
254 switch (s->link_selector) {
255 case CAIF_LINK_HIGH_BANDW:
256 pref = CFPHYPREF_HIGH_BW;
257 break;
258 case CAIF_LINK_LOW_LATENCY:
259 pref = CFPHYPREF_LOW_LAT;
260 break;
261 default:
262 return -EINVAL;
263 }
264 dev_info = cfcnfg_get_phyid(cnfg, pref);
265 if (dev_info == NULL)
266 return -ENODEV;
267 l->phyid = dev_info->id;
268 }
269 switch (s->protocol) {
270 case CAIFPROTO_AT:
271 l->linktype = CFCTRL_SRV_VEI;
272 l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3;
273 l->chtype = s->sockaddr.u.at.type & 0x3;
274 break;
275 case CAIFPROTO_DATAGRAM:
276 l->linktype = CFCTRL_SRV_DATAGRAM;
277 l->chtype = 0x00;
278 l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
279 break;
280 case CAIFPROTO_DATAGRAM_LOOP:
281 l->linktype = CFCTRL_SRV_DATAGRAM;
282 l->chtype = 0x03;
283 l->endpoint = 0x00;
284 l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
285 break;
286 case CAIFPROTO_RFM:
287 l->linktype = CFCTRL_SRV_RFM;
288 l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
289 strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
290 sizeof(l->u.rfm.volume)-1);
291 l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
292 break;
293 case CAIFPROTO_UTIL:
294 l->linktype = CFCTRL_SRV_UTIL;
295 l->endpoint = 0x00;
296 l->chtype = 0x00;
297 strncpy(l->u.utility.name, s->sockaddr.u.util.service,
298 sizeof(l->u.utility.name)-1);
299 l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
300 caif_assert(sizeof(l->u.utility.name) > 10);
301 l->u.utility.paramlen = s->param.size;
302 if (l->u.utility.paramlen > sizeof(l->u.utility.params))
303 l->u.utility.paramlen = sizeof(l->u.utility.params);
304
305 memcpy(l->u.utility.params, s->param.data,
306 l->u.utility.paramlen);
307
308 break;
309 case CAIFPROTO_DEBUG:
310 l->linktype = CFCTRL_SRV_DBG;
311 l->endpoint = s->sockaddr.u.dbg.service;
312 l->chtype = s->sockaddr.u.dbg.type;
313 break;
314 default:
315 return -EINVAL;
316 }
317 return 0;
318}
319
320int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
321 struct cflayer *adap_layer, int *ifindex,
245 int *proto_head, 322 int *proto_head,
246 int *proto_tail) 323 int *proto_tail)
247{ 324{
248 struct cflayer *frml; 325 struct cflayer *frml;
249 struct cfcnfg_phyinfo *phy; 326 struct cfcnfg_phyinfo *phy;
250 int err; 327 int err;
328 struct cfctrl_link_param param;
329 struct cfcnfg *cfg = get_cfcnfg(net);
330 caif_assert(cfg != NULL);
251 331
252 rcu_read_lock(); 332 rcu_read_lock();
253 phy = cfcnfg_get_phyinfo_rcu(cnfg, param->phyid); 333 err = caif_connect_req_to_link_param(cfg, conn_req, &param);
334 if (err)
335 goto unlock;
336
337 phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid);
254 if (!phy) { 338 if (!phy) {
255 err = -ENODEV; 339 err = -ENODEV;
256 goto unlock; 340 goto unlock;
@@ -276,28 +360,29 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
276 pr_err("Specified PHY type does not exist!\n"); 360 pr_err("Specified PHY type does not exist!\n");
277 goto unlock; 361 goto unlock;
278 } 362 }
279 caif_assert(param->phyid == phy->id); 363 caif_assert(param.phyid == phy->id);
280 caif_assert(phy->frm_layer->id == 364 caif_assert(phy->frm_layer->id ==
281 param->phyid); 365 param.phyid);
282 caif_assert(phy->phy_layer->id == 366 caif_assert(phy->phy_layer->id ==
283 param->phyid); 367 param.phyid);
284 368
285 *ifindex = phy->ifindex; 369 *ifindex = phy->ifindex;
286 *proto_tail = 2; 370 *proto_tail = 2;
287 *proto_head = 371 *proto_head =
288 protohead[param->linktype] + (phy->use_stx ? 1 : 0); 372
373 protohead[param.linktype] + (phy->use_stx ? 1 : 0);
289 374
290 rcu_read_unlock(); 375 rcu_read_unlock();
291 376
292 /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ 377 /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
293 cfctrl_enum_req(cnfg->ctrl, param->phyid); 378 cfctrl_enum_req(cfg->ctrl, param.phyid);
294 return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); 379 return cfctrl_linkup_request(cfg->ctrl, &param, adap_layer);
295 380
296unlock: 381unlock:
297 rcu_read_unlock(); 382 rcu_read_unlock();
298 return err; 383 return err;
299} 384}
300EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); 385EXPORT_SYMBOL(caif_connect_client);
301 386
302static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, 387static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
303 struct cflayer *adapt_layer) 388 struct cflayer *adapt_layer)
@@ -389,7 +474,7 @@ unlock:
389void 474void
390cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, 475cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
391 struct net_device *dev, struct cflayer *phy_layer, 476 struct net_device *dev, struct cflayer *phy_layer,
392 u16 *phy_id, enum cfcnfg_phy_preference pref, 477 enum cfcnfg_phy_preference pref,
393 bool fcs, bool stx) 478 bool fcs, bool stx)
394{ 479{
395 struct cflayer *frml; 480 struct cflayer *frml;
@@ -512,23 +597,26 @@ int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
512 phyid = phy_layer->id; 597 phyid = phy_layer->id;
513 phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid); 598 phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
514 599
515 if (phyinfo == NULL) 600 if (phyinfo == NULL) {
601 mutex_unlock(&cnfg->lock);
516 return 0; 602 return 0;
603 }
517 caif_assert(phyid == phyinfo->id); 604 caif_assert(phyid == phyinfo->id);
518 caif_assert(phy_layer == phyinfo->phy_layer); 605 caif_assert(phy_layer == phyinfo->phy_layer);
519 caif_assert(phy_layer->id == phyid); 606 caif_assert(phy_layer->id == phyid);
520 caif_assert(phyinfo->frm_layer->id == phyid); 607 caif_assert(phyinfo->frm_layer->id == phyid);
521 608
609 list_del_rcu(&phyinfo->node);
610 synchronize_rcu();
611
522 /* Fail if reference count is not zero */ 612 /* Fail if reference count is not zero */
523 if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) { 613 if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) {
524 pr_info("Wait for device inuse\n"); 614 pr_info("Wait for device inuse\n");
615 list_add_rcu(&phyinfo->node, &cnfg->phys);
525 mutex_unlock(&cnfg->lock); 616 mutex_unlock(&cnfg->lock);
526 return -EAGAIN; 617 return -EAGAIN;
527 } 618 }
528 619
529 list_del_rcu(&phyinfo->node);
530 synchronize_rcu();
531
532 frml = phyinfo->frm_layer; 620 frml = phyinfo->frm_layer;
533 frml_dn = frml->dn; 621 frml_dn = frml->dn;
534 cffrml_set_uplayer(frml, NULL); 622 cffrml_set_uplayer(frml, NULL);
@@ -539,8 +627,6 @@ int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
539 } 627 }
540 layer_set_up(phy_layer, NULL); 628 layer_set_up(phy_layer, NULL);
541 629
542
543
544 if (phyinfo->phy_layer != frml_dn) 630 if (phyinfo->phy_layer != frml_dn)
545 kfree(frml_dn); 631 kfree(frml_dn);
546 632
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 9ef8f1660ee1..1a3398a89aee 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -20,7 +20,6 @@
20#include <linux/caif/if_caif.h> 20#include <linux/caif/if_caif.h>
21#include <net/rtnetlink.h> 21#include <net/rtnetlink.h>
22#include <net/caif/caif_layer.h> 22#include <net/caif/caif_layer.h>
23#include <net/caif/cfcnfg.h>
24#include <net/caif/cfpkt.h> 23#include <net/caif/cfpkt.h>
25#include <net/caif/caif_dev.h> 24#include <net/caif/caif_dev.h>
26 25
@@ -270,8 +269,9 @@ static int chnl_net_open(struct net_device *dev)
270 269
271 if (priv->state != CAIF_CONNECTING) { 270 if (priv->state != CAIF_CONNECTING) {
272 priv->state = CAIF_CONNECTING; 271 priv->state = CAIF_CONNECTING;
273 result = caif_connect_client(&priv->conn_req, &priv->chnl, 272 result = caif_connect_client(dev_net(dev), &priv->conn_req,
274 &llifindex, &headroom, &tailroom); 273 &priv->chnl, &llifindex,
274 &headroom, &tailroom);
275 if (result != 0) { 275 if (result != 0) {
276 pr_debug("err: " 276 pr_debug("err: "
277 "Unable to register and open device," 277 "Unable to register and open device,"
@@ -327,7 +327,7 @@ static int chnl_net_open(struct net_device *dev)
327 327
328 if (result == 0) { 328 if (result == 0) {
329 pr_debug("connect timeout\n"); 329 pr_debug("connect timeout\n");
330 caif_disconnect_client(&priv->chnl); 330 caif_disconnect_client(dev_net(dev), &priv->chnl);
331 priv->state = CAIF_DISCONNECTED; 331 priv->state = CAIF_DISCONNECTED;
332 pr_debug("state disconnected\n"); 332 pr_debug("state disconnected\n");
333 result = -ETIMEDOUT; 333 result = -ETIMEDOUT;
@@ -343,7 +343,7 @@ static int chnl_net_open(struct net_device *dev)
343 return 0; 343 return 0;
344 344
345error: 345error:
346 caif_disconnect_client(&priv->chnl); 346 caif_disconnect_client(dev_net(dev), &priv->chnl);
347 priv->state = CAIF_DISCONNECTED; 347 priv->state = CAIF_DISCONNECTED;
348 pr_debug("state disconnected\n"); 348 pr_debug("state disconnected\n");
349 return result; 349 return result;
@@ -357,7 +357,7 @@ static int chnl_net_stop(struct net_device *dev)
357 ASSERT_RTNL(); 357 ASSERT_RTNL();
358 priv = netdev_priv(dev); 358 priv = netdev_priv(dev);
359 priv->state = CAIF_DISCONNECTED; 359 priv->state = CAIF_DISCONNECTED;
360 caif_disconnect_client(&priv->chnl); 360 caif_disconnect_client(dev_net(dev), &priv->chnl);
361 return 0; 361 return 0;
362} 362}
363 363