Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

sjur.brandeland@stericsson.com and committed by
David S. Miller
bee925db b3ccfbe4

+176 -261
+6 -18
include/net/caif/caif_dev.h
··· 11 11 #include <net/caif/cfcnfg.h> 12 12 #include <linux/caif/caif_socket.h> 13 13 #include <linux/if.h> 14 + #include <linux/net.h> 14 15 15 16 /** 16 17 * struct caif_param - CAIF parameters. ··· 63 62 * E.g. CAIF Socket will call this function for each socket it connects 64 63 * and have one client_layer instance for each socket. 65 64 */ 66 - int caif_connect_client(struct caif_connect_request *conn_req, 65 + int caif_connect_client(struct net *net, 66 + struct caif_connect_request *conn_req, 67 67 struct cflayer *client_layer, int *ifindex, 68 68 int *headroom, int *tailroom); 69 69 70 70 /** 71 71 * caif_disconnect_client - Disconnects a client from the CAIF stack. 72 72 * 73 - * @client_layer: Client layer to be removed. 73 + * @client_layer: Client layer to be disconnected. 74 74 */ 75 - int caif_disconnect_client(struct cflayer *client_layer); 75 + int caif_disconnect_client(struct net *net, struct cflayer *client_layer); 76 + 76 77 77 78 /** 78 79 * caif_client_register_refcnt - register ref-count functions provided by client. ··· 93 90 void caif_client_register_refcnt(struct cflayer *adapt_layer, 94 91 void (*hold)(struct cflayer *lyr), 95 92 void (*put)(struct cflayer *lyr)); 96 - /** 97 - * caif_connect_req_to_link_param - Translate configuration parameters 98 - * from socket format to internal format. 99 - * @cnfg: Pointer to configuration handler 100 - * @con_req: Configuration parameters supplied in function 101 - * caif_connect_client 102 - * @channel_setup_param: Parameters supplied to the CAIF Core stack for 103 - * setting up channels. 104 - * 105 - */ 106 - 107 - int caif_connect_req_to_link_param(struct cfcnfg *cnfg, 108 - struct caif_connect_request *con_req, 109 - struct cfctrl_link_param *setup_param); 110 - 111 93 /** 112 94 * caif_free_client - Free memory used to manage the client in the CAIF Stack. 113 95 *
+8 -63
include/net/caif/cfcnfg.h
··· 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 + */ 52 + struct cfcnfg *get_cfcnfg(struct net *net); 53 + 54 + /** 49 55 * cfcnfg_create() - Create the CAIF configuration object. 50 56 */ 51 57 struct cfcnfg *cfcnfg_create(void); ··· 71 65 * @dev: Pointer to link layer device 72 66 * @phy_layer: Specify the physical layer. The transmit function 73 67 * MUST be set in the structure. 74 - * @phyid: The assigned physical ID for this layer, used in 75 - * cfcnfg_add_adapt_layer to specify PHY for the link. 76 68 * @pref: The phy (link layer) preference. 77 69 * @fcs: Specify if checksum is used in CAIF Framing Layer. 78 - * @stx: Specify if Start Of Frame extension is used. 70 + * @stx: Specify if Start Of Frame eXtention is used. 79 71 */ 80 72 81 73 void 82 74 cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, 83 75 struct net_device *dev, struct cflayer *phy_layer, 84 - u16 *phyid, enum cfcnfg_phy_preference pref, 76 + enum cfcnfg_phy_preference pref, 85 77 bool fcs, bool stx); 86 78 87 79 /** ··· 90 86 * @phy_layer: Adaptation layer to be removed. 91 87 */ 92 88 int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer); 93 - 94 - /** 95 - * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer. 96 - * 97 - * @cnfg: Pointer to a CAIF configuration object, created by 98 - * cfcnfg_create(). 99 - * @adap_layer: Adaptation layer to be removed. 100 - */ 101 - int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, 102 - struct cflayer *adap_layer); 103 - 104 - /** 105 - * cfcnfg_release_adap_layer - Used by client to release the adaptation layer. 106 - * 107 - * @adap_layer: Adaptation layer. 108 - */ 109 - void cfcnfg_release_adap_layer(struct cflayer *adap_layer); 110 - 111 - /** 112 - * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack. 113 - * 114 - * The adaptation Layer is where the interface to application or higher-level 115 - * driver functionality is implemented. 116 - * 117 - * @cnfg: Pointer to a CAIF configuration object, created by 118 - * cfcnfg_create(). 119 - * @param: Link setup parameters. 120 - * @adap_layer: Specify the adaptation layer; the receive and 121 - * flow-control functions MUST be set in the structure. 122 - * @ifindex: Link layer interface index used for this connection. 123 - * @proto_head: Protocol head-space needed by CAIF protocol, 124 - * excluding link layer. 125 - * @proto_tail: Protocol tail-space needed by CAIF protocol, 126 - * excluding link layer. 127 - */ 128 - int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, 129 - struct cfctrl_link_param *param, 130 - struct cflayer *adap_layer, 131 - int *ifindex, 132 - int *proto_head, 133 - int *proto_tail); 134 - 135 - /** 136 - * cfcnfg_get_phyid() - Get physical ID, given type. 137 - * Returns one of the physical interfaces matching the given type. 138 - * Zero if no match is found. 139 - * @cnfg: Configuration object 140 - * @phy_pref: Caif Link Layer preference 141 - */ 142 - struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, 143 - enum cfcnfg_phy_preference phy_pref); 144 - 145 - /** 146 - * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex, 147 - * it matches caif physical id with the kernel interface id. 148 - * @cnfg: Configuration object 149 - * @ifi: ifindex obtained from socket.c bindtodevice. 150 - */ 151 - int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi); 152 89 153 90 /** 154 91 * cfcnfg_set_phy_state() - Set the state of the physical interface device.
+1 -1
net/caif/Makefile
··· 5 5 cffrml.o cfveil.o cfdbgl.o\ 6 6 cfserl.o cfdgml.o \ 7 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 10 obj-$(CONFIG_CAIF) += caif.o 11 11 obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
-99
net/caif/caif_config_util.c
··· 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 - }
+36 -41
net/caif/caif_dev.c
··· 21 21 #include <net/net_namespace.h> 22 22 #include <net/pkt_sched.h> 23 23 #include <net/caif/caif_device.h> 24 - #include <net/caif/caif_dev.h> 25 24 #include <net/caif/caif_layer.h> 26 25 #include <net/caif/cfpkt.h> 27 26 #include <net/caif/cfcnfg.h> ··· 42 43 }; 43 44 44 45 struct caif_net { 46 + struct cfcnfg *cfg; 45 47 struct caif_device_entry_list caifdevs; 46 48 }; 47 49 48 50 static int caif_net_id; 49 - static struct cfcnfg *cfg; 51 + 52 + struct cfcnfg *get_cfcnfg(struct net *net) 53 + { 54 + struct caif_net *caifn; 55 + BUG_ON(!net); 56 + caifn = net_generic(net, caif_net_id); 57 + BUG_ON(!caifn); 58 + return caifn->cfg; 59 + } 60 + EXPORT_SYMBOL(get_cfcnfg); 50 61 51 62 static struct caif_device_entry_list *caif_device_list(struct net *net) 52 63 { ··· 200 191 struct caif_dev_common *caifdev; 201 192 enum cfcnfg_phy_preference pref; 202 193 enum cfcnfg_phy_type phy_type; 194 + struct cfcnfg *cfg; 203 195 struct caif_device_entry_list *caifdevs = 204 196 caif_device_list(dev_net(dev)); 205 197 206 198 if (dev->type != ARPHRD_CAIF) 199 + return 0; 200 + 201 + cfg = get_cfcnfg(dev_net(dev)); 202 + if (cfg == NULL) 207 203 return 0; 208 204 209 205 switch (what) { ··· 249 235 phy_type, 250 236 dev, 251 237 &caifd->layer, 252 - 0, 253 238 pref, 254 239 caifdev->use_fcs, 255 240 caifdev->use_stx); ··· 336 323 .priority = 0, 337 324 }; 338 325 339 - int caif_connect_client(struct caif_connect_request *conn_req, 340 - struct cflayer *client_layer, int *ifindex, 341 - int *headroom, int *tailroom) 342 - { 343 - struct cfctrl_link_param param; 344 - int ret; 345 - 346 - ret = caif_connect_req_to_link_param(cfg, conn_req, &param); 347 - if (ret) 348 - return ret; 349 - /* Hook up the adaptation layer. */ 350 - return cfcnfg_add_adaptation_layer(cfg, &param, 351 - client_layer, ifindex, 352 - headroom, tailroom); 353 - } 354 - EXPORT_SYMBOL(caif_connect_client); 355 - 356 - int caif_disconnect_client(struct cflayer *adap_layer) 357 - { 358 - return cfcnfg_disconn_adapt_layer(cfg, adap_layer); 359 - } 360 - EXPORT_SYMBOL(caif_disconnect_client); 361 - 362 326 /* Per-namespace Caif devices handling */ 363 327 static int caif_init_net(struct net *net) 364 328 { 365 329 struct caif_net *caifn = net_generic(net, caif_net_id); 330 + BUG_ON(!caifn); 366 331 INIT_LIST_HEAD(&caifn->caifdevs.list); 367 332 mutex_init(&caifn->caifdevs.lock); 333 + 334 + caifn->cfg = cfcnfg_create(); 335 + if (!caifn->cfg) { 336 + pr_warn("can't create cfcnfg\n"); 337 + return -ENOMEM; 338 + } 339 + 368 340 return 0; 369 341 } 370 342 ··· 358 360 struct caif_device_entry *caifd, *tmp; 359 361 struct caif_device_entry_list *caifdevs = 360 362 caif_device_list(net); 363 + struct cfcnfg *cfg; 361 364 362 365 rtnl_lock(); 363 366 mutex_lock(&caifdevs->lock); 367 + 368 + cfg = get_cfcnfg(net); 369 + if (cfg == NULL) { 370 + mutex_unlock(&caifdevs->lock); 371 + return; 372 + } 364 373 365 374 list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) { 366 375 int i = 0; ··· 387 382 free_percpu(caifd->pcpu_refcnt); 388 383 kfree(caifd); 389 384 } 390 - 385 + cfcnfg_remove(cfg); 391 386 392 387 mutex_unlock(&caifdevs->lock); 393 388 rtnl_unlock(); ··· 405 400 { 406 401 int result; 407 402 408 - cfg = cfcnfg_create(); 409 - if (!cfg) { 410 - pr_warn("can't create cfcnfg\n"); 411 - goto err_cfcnfg_create_failed; 412 - } 413 403 result = register_pernet_device(&caif_net_ops); 414 404 415 - if (result) { 416 - kfree(cfg); 417 - cfg = NULL; 405 + if (result) 418 406 return result; 419 - } 420 - dev_add_pack(&caif_packet_type); 407 + 421 408 register_netdevice_notifier(&caif_device_notifier); 409 + dev_add_pack(&caif_packet_type); 422 410 423 411 return result; 424 - err_cfcnfg_create_failed: 425 - return -ENODEV; 426 412 } 427 413 428 414 static void __exit caif_device_exit(void) 429 415 { 430 - dev_remove_pack(&caif_packet_type); 431 416 unregister_pernet_device(&caif_net_ops); 432 417 unregister_netdevice_notifier(&caif_device_notifier); 433 - cfcnfg_remove(cfg); 418 + dev_remove_pack(&caif_packet_type); 434 419 } 435 420 436 421 module_init(caif_device_init);
+3 -3
net/caif/caif_socket.c
··· 810 810 sk->sk_state == CAIF_DISCONNECTED); 811 811 if (sk->sk_shutdown & SHUTDOWN_MASK) { 812 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 814 break; 815 815 } 816 816 /* No reconnect on a seqpacket socket */ ··· 851 851 dbfs_atomic_inc(&cnt.num_connect_req); 852 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 855 &cf_sk->layer, &ifindex, &headroom, &tailroom); 856 856 857 857 if (err < 0) { ··· 949 949 950 950 if (cf_sk->sk.sk_socket->state == SS_CONNECTED || 951 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 954 cf_sk->sk.sk_socket->state = SS_DISCONNECTING; 955 955 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
+116 -30
net/caif/cfcnfg.c
··· 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 154 enum cfcnfg_phy_preference phy_pref) 155 155 { 156 156 /* Try to match with specified preference */ ··· 171 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 176 struct cfcnfg_phyinfo *phy; 177 177 ··· 181 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 186 u8 channel_id = 0; 187 187 int ret = 0; 188 188 struct cflayer *servl = NULL; 189 + struct cfcnfg *cfg = get_cfcnfg(net); 189 190 190 191 caif_assert(adap_layer != NULL); 191 192 ··· 218 217 return ret; 219 218 220 219 } 221 - EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer); 222 - 223 - void cfcnfg_release_adap_layer(struct cflayer *adap_layer) 224 - { 225 - if (adap_layer->dn) 226 - cfsrvl_put(adap_layer->dn); 227 - } 228 - EXPORT_SYMBOL(cfcnfg_release_adap_layer); 220 + EXPORT_SYMBOL(caif_disconnect_client); 229 221 230 222 static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) 231 223 { ··· 232 238 [CFCTRL_SRV_DBG] = 3, 233 239 }; 234 240 235 - int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, 236 - struct cfctrl_link_param *param, 237 - struct cflayer *adap_layer, 238 - int *ifindex, 241 + 242 + static int caif_connect_req_to_link_param(struct cfcnfg *cnfg, 243 + struct caif_connect_request *s, 244 + struct cfctrl_link_param *l) 245 + { 246 + struct dev_info *dev_info; 247 + enum cfcnfg_phy_preference pref; 248 + int res; 249 + 250 + memset(l, 0, sizeof(*l)); 251 + /* In caif protocol low value is high priority */ 252 + l->priority = CAIF_PRIO_MAX - s->priority + 1; 253 + 254 + if (s->ifindex != 0) { 255 + res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); 256 + if (res < 0) 257 + return res; 258 + l->phyid = res; 259 + } else { 260 + switch (s->link_selector) { 261 + case CAIF_LINK_HIGH_BANDW: 262 + pref = CFPHYPREF_HIGH_BW; 263 + break; 264 + case CAIF_LINK_LOW_LATENCY: 265 + pref = CFPHYPREF_LOW_LAT; 266 + break; 267 + default: 268 + return -EINVAL; 269 + } 270 + dev_info = cfcnfg_get_phyid(cnfg, pref); 271 + if (dev_info == NULL) 272 + return -ENODEV; 273 + l->phyid = dev_info->id; 274 + } 275 + switch (s->protocol) { 276 + case CAIFPROTO_AT: 277 + l->linktype = CFCTRL_SRV_VEI; 278 + l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3; 279 + l->chtype = s->sockaddr.u.at.type & 0x3; 280 + break; 281 + case CAIFPROTO_DATAGRAM: 282 + l->linktype = CFCTRL_SRV_DATAGRAM; 283 + l->chtype = 0x00; 284 + l->u.datagram.connid = s->sockaddr.u.dgm.connection_id; 285 + break; 286 + case CAIFPROTO_DATAGRAM_LOOP: 287 + l->linktype = CFCTRL_SRV_DATAGRAM; 288 + l->chtype = 0x03; 289 + l->endpoint = 0x00; 290 + l->u.datagram.connid = s->sockaddr.u.dgm.connection_id; 291 + break; 292 + case CAIFPROTO_RFM: 293 + l->linktype = CFCTRL_SRV_RFM; 294 + l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; 295 + strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, 296 + sizeof(l->u.rfm.volume)-1); 297 + l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0; 298 + break; 299 + case CAIFPROTO_UTIL: 300 + l->linktype = CFCTRL_SRV_UTIL; 301 + l->endpoint = 0x00; 302 + l->chtype = 0x00; 303 + strncpy(l->u.utility.name, s->sockaddr.u.util.service, 304 + sizeof(l->u.utility.name)-1); 305 + l->u.utility.name[sizeof(l->u.utility.name)-1] = 0; 306 + caif_assert(sizeof(l->u.utility.name) > 10); 307 + l->u.utility.paramlen = s->param.size; 308 + if (l->u.utility.paramlen > sizeof(l->u.utility.params)) 309 + l->u.utility.paramlen = sizeof(l->u.utility.params); 310 + 311 + memcpy(l->u.utility.params, s->param.data, 312 + l->u.utility.paramlen); 313 + 314 + break; 315 + case CAIFPROTO_DEBUG: 316 + l->linktype = CFCTRL_SRV_DBG; 317 + l->endpoint = s->sockaddr.u.dbg.service; 318 + l->chtype = s->sockaddr.u.dbg.type; 319 + break; 320 + default: 321 + return -EINVAL; 322 + } 323 + return 0; 324 + } 325 + 326 + int caif_connect_client(struct net *net, struct caif_connect_request *conn_req, 327 + struct cflayer *adap_layer, int *ifindex, 239 328 int *proto_head, 240 329 int *proto_tail) 241 330 { 242 331 struct cflayer *frml; 243 332 struct cfcnfg_phyinfo *phy; 244 333 int err; 334 + struct cfctrl_link_param param; 335 + struct cfcnfg *cfg = get_cfcnfg(net); 336 + caif_assert(cfg != NULL); 245 337 246 338 rcu_read_lock(); 247 - phy = cfcnfg_get_phyinfo_rcu(cnfg, param->phyid); 339 + err = caif_connect_req_to_link_param(cfg, conn_req, &param); 340 + if (err) 341 + goto unlock; 342 + 343 + phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid); 248 344 if (!phy) { 249 345 err = -ENODEV; 250 346 goto unlock; ··· 360 276 pr_err("Specified PHY type does not exist!\n"); 361 277 goto unlock; 362 278 } 363 - caif_assert(param->phyid == phy->id); 279 + caif_assert(param.phyid == phy->id); 364 280 caif_assert(phy->frm_layer->id == 365 - param->phyid); 281 + param.phyid); 366 282 caif_assert(phy->phy_layer->id == 367 - param->phyid); 283 + param.phyid); 368 284 369 285 *ifindex = phy->ifindex; 370 286 *proto_tail = 2; 371 287 *proto_head = 372 - protohead[param->linktype] + (phy->use_stx ? 1 : 0); 288 + 289 + protohead[param.linktype] + (phy->use_stx ? 1 : 0); 373 290 374 291 rcu_read_unlock(); 375 292 376 293 /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ 377 - cfctrl_enum_req(cnfg->ctrl, param->phyid); 378 - return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); 294 + cfctrl_enum_req(cfg->ctrl, param.phyid); 295 + return cfctrl_linkup_request(cfg->ctrl, &param, adap_layer); 379 296 380 297 unlock: 381 298 rcu_read_unlock(); 382 299 return err; 383 300 } 384 - EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); 301 + EXPORT_SYMBOL(caif_connect_client); 385 302 386 303 static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, 387 304 struct cflayer *adapt_layer) ··· 474 389 void 475 390 cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, 476 391 struct net_device *dev, struct cflayer *phy_layer, 477 - u16 *phy_id, enum cfcnfg_phy_preference pref, 392 + enum cfcnfg_phy_preference pref, 478 393 bool fcs, bool stx) 479 394 { 480 395 struct cflayer *frml; ··· 597 512 phyid = phy_layer->id; 598 513 phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid); 599 514 600 - if (phyinfo == NULL) 515 + if (phyinfo == NULL) { 516 + mutex_unlock(&cnfg->lock); 601 517 return 0; 518 + } 602 519 caif_assert(phyid == phyinfo->id); 603 520 caif_assert(phy_layer == phyinfo->phy_layer); 604 521 caif_assert(phy_layer->id == phyid); 605 522 caif_assert(phyinfo->frm_layer->id == phyid); 606 523 524 + list_del_rcu(&phyinfo->node); 525 + synchronize_rcu(); 526 + 607 527 /* Fail if reference count is not zero */ 608 528 if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) { 609 529 pr_info("Wait for device inuse\n"); 530 + list_add_rcu(&phyinfo->node, &cnfg->phys); 610 531 mutex_unlock(&cnfg->lock); 611 532 return -EAGAIN; 612 533 } 613 - 614 - list_del_rcu(&phyinfo->node); 615 - synchronize_rcu(); 616 534 617 535 frml = phyinfo->frm_layer; 618 536 frml_dn = frml->dn; ··· 626 538 layer_set_dn(frml_dn, NULL); 627 539 } 628 540 layer_set_up(phy_layer, NULL); 629 - 630 - 631 541 632 542 if (phyinfo->phy_layer != frml_dn) 633 543 kfree(frml_dn);
+6 -6
net/caif/chnl_net.c
··· 20 20 #include <linux/caif/if_caif.h> 21 21 #include <net/rtnetlink.h> 22 22 #include <net/caif/caif_layer.h> 23 - #include <net/caif/cfcnfg.h> 24 23 #include <net/caif/cfpkt.h> 25 24 #include <net/caif/caif_dev.h> 26 25 ··· 269 270 270 271 if (priv->state != CAIF_CONNECTING) { 271 272 priv->state = CAIF_CONNECTING; 272 - result = caif_connect_client(&priv->conn_req, &priv->chnl, 273 - &llifindex, &headroom, &tailroom); 273 + result = caif_connect_client(dev_net(dev), &priv->conn_req, 274 + &priv->chnl, &llifindex, 275 + &headroom, &tailroom); 274 276 if (result != 0) { 275 277 pr_debug("err: " 276 278 "Unable to register and open device," ··· 327 327 328 328 if (result == 0) { 329 329 pr_debug("connect timeout\n"); 330 - caif_disconnect_client(&priv->chnl); 330 + caif_disconnect_client(dev_net(dev), &priv->chnl); 331 331 priv->state = CAIF_DISCONNECTED; 332 332 pr_debug("state disconnected\n"); 333 333 result = -ETIMEDOUT; ··· 343 343 return 0; 344 344 345 345 error: 346 - caif_disconnect_client(&priv->chnl); 346 + caif_disconnect_client(dev_net(dev), &priv->chnl); 347 347 priv->state = CAIF_DISCONNECTED; 348 348 pr_debug("state disconnected\n"); 349 349 return result; ··· 357 357 ASSERT_RTNL(); 358 358 priv = netdev_priv(dev); 359 359 priv->state = CAIF_DISCONNECTED; 360 - caif_disconnect_client(&priv->chnl); 360 + caif_disconnect_client(dev_net(dev), &priv->chnl); 361 361 return 0; 362 362 } 363 363