diff options
author | sjur.brandeland@stericsson.com <sjur.brandeland@stericsson.com> | 2011-05-12 22:44:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-15 17:45:55 -0400 |
commit | bee925db9a77a5736596dcf6f91d0879f5ee915b (patch) | |
tree | 57a3b499d5b8ec3cb9d36be674e165fa1e7eed42 /net | |
parent | b3ccfbe4098a5542177d0f34e8979f32e7d606e1 (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/Makefile | 2 | ||||
-rw-r--r-- | net/caif/caif_config_util.c | 99 | ||||
-rw-r--r-- | net/caif/caif_dev.c | 77 | ||||
-rw-r--r-- | net/caif/caif_socket.c | 6 | ||||
-rw-r--r-- | net/caif/cfcnfg.c | 146 | ||||
-rw-r--r-- | net/caif/chnl_net.c | 12 |
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 | ||
10 | obj-$(CONFIG_CAIF) += caif.o | 10 | obj-$(CONFIG_CAIF) += caif.o |
11 | obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o | 11 | obj-$(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 | |||
13 | int 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 | ||
45 | struct caif_net { | 44 | struct caif_net { |
45 | struct cfcnfg *cfg; | ||
46 | struct caif_device_entry_list caifdevs; | 46 | struct caif_device_entry_list caifdevs; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int caif_net_id; | 49 | static int caif_net_id; |
50 | static struct cfcnfg *cfg; | 50 | |
51 | struct 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 | } | ||
59 | EXPORT_SYMBOL(get_cfcnfg); | ||
51 | 60 | ||
52 | static struct caif_device_entry_list *caif_device_list(struct net *net) | 61 | static 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 | ||
326 | int 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, ¶m); | ||
334 | if (ret) | ||
335 | return ret; | ||
336 | /* Hook up the adaptation layer. */ | ||
337 | return cfcnfg_add_adaptation_layer(cfg, ¶m, | ||
338 | client_layer, ifindex, | ||
339 | headroom, tailroom); | ||
340 | } | ||
341 | EXPORT_SYMBOL(caif_connect_client); | ||
342 | |||
343 | int caif_disconnect_client(struct cflayer *adap_layer) | ||
344 | { | ||
345 | return cfcnfg_disconn_adapt_layer(cfg, adap_layer); | ||
346 | } | ||
347 | EXPORT_SYMBOL(caif_disconnect_client); | ||
348 | |||
349 | /* Per-namespace Caif devices handling */ | 339 | /* Per-namespace Caif devices handling */ |
350 | static int caif_init_net(struct net *net) | 340 | static 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; |
419 | err_cfcnfg_create_failed: | ||
420 | return -ENODEV; | ||
421 | } | 417 | } |
422 | 418 | ||
423 | static void __exit caif_device_exit(void) | 419 | static 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 | ||
431 | module_init(caif_device_init); | 426 | module_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 | ||
153 | struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, | 153 | static 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 | ||
174 | int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) | 174 | static 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 | ||
184 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cfg, struct cflayer *adap_layer) | 184 | int 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 | } |
220 | EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer); | 221 | EXPORT_SYMBOL(caif_disconnect_client); |
221 | |||
222 | void cfcnfg_release_adap_layer(struct cflayer *adap_layer) | ||
223 | { | ||
224 | if (adap_layer->dn) | ||
225 | cfsrvl_put(adap_layer->dn); | ||
226 | } | ||
227 | EXPORT_SYMBOL(cfcnfg_release_adap_layer); | ||
228 | 222 | ||
229 | static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) | 223 | static 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 | ||
241 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | 235 | |
242 | struct cfctrl_link_param *param, | 236 | static 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 | |||
320 | int 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, ¶m); |
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, ¶m, adap_layer); |
295 | 380 | ||
296 | unlock: | 381 | unlock: |
297 | rcu_read_unlock(); | 382 | rcu_read_unlock(); |
298 | return err; | 383 | return err; |
299 | } | 384 | } |
300 | EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); | 385 | EXPORT_SYMBOL(caif_connect_client); |
301 | 386 | ||
302 | static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, | 387 | static 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: | |||
389 | void | 474 | void |
390 | cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | 475 | cfcnfg_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 | ||
345 | error: | 345 | error: |
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 | ||