aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/caif/caif_dev.h24
-rw-r--r--include/net/caif/cfcnfg.h71
-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
8 files changed, 176 insertions, 261 deletions
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
index 6638435525fc..c011281d92c0 100644
--- a/include/net/caif/caif_dev.h
+++ b/include/net/caif/caif_dev.h
@@ -11,6 +11,7 @@
11#include <net/caif/cfcnfg.h> 11#include <net/caif/cfcnfg.h>
12#include <linux/caif/caif_socket.h> 12#include <linux/caif/caif_socket.h>
13#include <linux/if.h> 13#include <linux/if.h>
14#include <linux/net.h>
14 15
15/** 16/**
16 * struct caif_param - CAIF parameters. 17 * struct caif_param - CAIF parameters.
@@ -62,16 +63,18 @@ struct caif_connect_request {
62 * E.g. CAIF Socket will call this function for each socket it connects 63 * E.g. CAIF Socket will call this function for each socket it connects
63 * and have one client_layer instance for each socket. 64 * and have one client_layer instance for each socket.
64 */ 65 */
65int caif_connect_client(struct caif_connect_request *conn_req, 66int caif_connect_client(struct net *net,
67 struct caif_connect_request *conn_req,
66 struct cflayer *client_layer, int *ifindex, 68 struct cflayer *client_layer, int *ifindex,
67 int *headroom, int *tailroom); 69 int *headroom, int *tailroom);
68 70
69/** 71/**
70 * caif_disconnect_client - Disconnects a client from the CAIF stack. 72 * caif_disconnect_client - Disconnects a client from the CAIF stack.
71 * 73 *
72 * @client_layer: Client layer to be removed. 74 * @client_layer: Client layer to be disconnected.
73 */ 75 */
74int caif_disconnect_client(struct cflayer *client_layer); 76int caif_disconnect_client(struct net *net, struct cflayer *client_layer);
77
75 78
76/** 79/**
77 * caif_client_register_refcnt - register ref-count functions provided by client. 80 * caif_client_register_refcnt - register ref-count functions provided by client.
@@ -91,21 +94,6 @@ void caif_client_register_refcnt(struct cflayer *adapt_layer,
91 void (*hold)(struct cflayer *lyr), 94 void (*hold)(struct cflayer *lyr),
92 void (*put)(struct cflayer *lyr)); 95 void (*put)(struct cflayer *lyr));
93/** 96/**
94 * caif_connect_req_to_link_param - Translate configuration parameters
95 * from socket format to internal format.
96 * @cnfg: Pointer to configuration handler
97 * @con_req: Configuration parameters supplied in function
98 * caif_connect_client
99 * @channel_setup_param: Parameters supplied to the CAIF Core stack for
100 * setting up channels.
101 *
102 */
103
104int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
105 struct caif_connect_request *con_req,
106 struct cfctrl_link_param *setup_param);
107
108/**
109 * caif_free_client - Free memory used to manage the client in the CAIF Stack. 97 * caif_free_client - Free memory used to manage the client in the CAIF Stack.
110 * 98 *
111 * @client_layer: Client layer to be removed. 99 * @client_layer: Client layer to be removed.
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h
index e0a1eb5d7eaf..3e93a4a4b677 100644
--- a/include/net/caif/cfcnfg.h
+++ b/include/net/caif/cfcnfg.h
@@ -46,6 +46,12 @@ enum cfcnfg_phy_preference {
46}; 46};
47 47
48/** 48/**
49 * cfcnfg_create() - Get the CAIF configuration object given network.
50 * @net: Network for the CAIF configuration object.
51 */
52struct cfcnfg *get_cfcnfg(struct net *net);
53
54/**
49 * cfcnfg_create() - Create the CAIF configuration object. 55 * cfcnfg_create() - Create the CAIF configuration object.
50 */ 56 */
51struct cfcnfg *cfcnfg_create(void); 57struct cfcnfg *cfcnfg_create(void);
@@ -65,17 +71,15 @@ void cfcnfg_remove(struct cfcnfg *cfg);
65 * @dev: Pointer to link layer device 71 * @dev: Pointer to link layer device
66 * @phy_layer: Specify the physical layer. The transmit function 72 * @phy_layer: Specify the physical layer. The transmit function
67 * MUST be set in the structure. 73 * MUST be set in the structure.
68 * @phyid: The assigned physical ID for this layer, used in
69 * cfcnfg_add_adapt_layer to specify PHY for the link.
70 * @pref: The phy (link layer) preference. 74 * @pref: The phy (link layer) preference.
71 * @fcs: Specify if checksum is used in CAIF Framing Layer. 75 * @fcs: Specify if checksum is used in CAIF Framing Layer.
72 * @stx: Specify if Start Of Frame extension is used. 76 * @stx: Specify if Start Of Frame eXtention is used.
73 */ 77 */
74 78
75void 79void
76cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, 80cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
77 struct net_device *dev, struct cflayer *phy_layer, 81 struct net_device *dev, struct cflayer *phy_layer,
78 u16 *phyid, enum cfcnfg_phy_preference pref, 82 enum cfcnfg_phy_preference pref,
79 bool fcs, bool stx); 83 bool fcs, bool stx);
80 84
81/** 85/**
@@ -88,65 +92,6 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
88int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer); 92int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer);
89 93
90/** 94/**
91 * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer.
92 *
93 * @cnfg: Pointer to a CAIF configuration object, created by
94 * cfcnfg_create().
95 * @adap_layer: Adaptation layer to be removed.
96 */
97int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg,
98 struct cflayer *adap_layer);
99
100/**
101 * cfcnfg_release_adap_layer - Used by client to release the adaptation layer.
102 *
103 * @adap_layer: Adaptation layer.
104 */
105void cfcnfg_release_adap_layer(struct cflayer *adap_layer);
106
107/**
108 * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack.
109 *
110 * The adaptation Layer is where the interface to application or higher-level
111 * driver functionality is implemented.
112 *
113 * @cnfg: Pointer to a CAIF configuration object, created by
114 * cfcnfg_create().
115 * @param: Link setup parameters.
116 * @adap_layer: Specify the adaptation layer; the receive and
117 * flow-control functions MUST be set in the structure.
118 * @ifindex: Link layer interface index used for this connection.
119 * @proto_head: Protocol head-space needed by CAIF protocol,
120 * excluding link layer.
121 * @proto_tail: Protocol tail-space needed by CAIF protocol,
122 * excluding link layer.
123 */
124int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
125 struct cfctrl_link_param *param,
126 struct cflayer *adap_layer,
127 int *ifindex,
128 int *proto_head,
129 int *proto_tail);
130
131/**
132 * cfcnfg_get_phyid() - Get physical ID, given type.
133 * Returns one of the physical interfaces matching the given type.
134 * Zero if no match is found.
135 * @cnfg: Configuration object
136 * @phy_pref: Caif Link Layer preference
137 */
138struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
139 enum cfcnfg_phy_preference phy_pref);
140
141/**
142 * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
143 * it matches caif physical id with the kernel interface id.
144 * @cnfg: Configuration object
145 * @ifi: ifindex obtained from socket.c bindtodevice.
146 */
147int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);
148
149/**
150 * cfcnfg_set_phy_state() - Set the state of the physical interface device. 95 * cfcnfg_set_phy_state() - Set the state of the physical interface device.
151 * @cnfg: Configuration object 96 * @cnfg: Configuration object
152 * @phy_layer: Physical Layer representation 97 * @phy_layer: Physical Layer representation
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