1 /* 2 * CAIF Interface registration. 3 * Copyright (C) ST-Ericsson AB 2010 4 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com 5 * License terms: GNU General Public License (GPL) version 2 6 * 7 * Borrowed heavily from file: pn_dev.c. Thanks to 8 * Remi Denis-Courmont <remi.denis-courmont@nokia.com> 9 * and Sakari Ailus <sakari.ailus@nokia.com> 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 13 14 #include <linux/version.h> 15 #include <linux/module.h> 16 #include <linux/kernel.h> 17 #include <linux/if_arp.h> 18 #include <linux/net.h> 19 #include <linux/netdevice.h> 20 #include <linux/skbuff.h> 21 #include <linux/sched.h> 22 #include <linux/wait.h> 23 #include <net/netns/generic.h> 24 #include <net/net_namespace.h> 25 #include <net/pkt_sched.h> 26 #include <net/caif/caif_device.h> 27 #include <net/caif/caif_dev.h> 28 #include <net/caif/caif_layer.h> 29 #include <net/caif/cfpkt.h> 30 #include <net/caif/cfcnfg.h> 31 32 MODULE_LICENSE("GPL"); 33 #define TIMEOUT (HZ*5) 34 35 /* Used for local tracking of the CAIF net devices */ 36 struct caif_device_entry { 37 struct cflayer layer; 38 struct list_head list; 39 atomic_t in_use; 40 atomic_t state; 41 u16 phyid; 42 struct net_device *netdev; 43 wait_queue_head_t event; 44 }; 45 46 struct caif_device_entry_list { 47 struct list_head list; 48 /* Protects simulanous deletes in list */ 49 spinlock_t lock; 50 }; 51 52 struct caif_net { 53 struct caif_device_entry_list caifdevs; 54 }; 55 56 static int caif_net_id; 57 static struct cfcnfg *cfg; 58 59 static struct caif_device_entry_list *caif_device_list(struct net *net) 60 { 61 struct caif_net *caifn; 62 BUG_ON(!net); 63 caifn = net_generic(net, caif_net_id); 64 BUG_ON(!caifn); 65 return &caifn->caifdevs; 66 } 67 68 /* Allocate new CAIF device. */ 69 static struct caif_device_entry *caif_device_alloc(struct net_device *dev) 70 { 71 struct caif_device_entry_list *caifdevs; 72 struct caif_device_entry *caifd; 73 caifdevs = caif_device_list(dev_net(dev)); 74 BUG_ON(!caifdevs); 75 caifd = kzalloc(sizeof(*caifd), GFP_ATOMIC); 76 if (!caifd) 77 return NULL; 78 caifd->netdev = dev; 79 list_add(&caifd->list, &caifdevs->list); 80 init_waitqueue_head(&caifd->event); 81 return caifd; 82 } 83 84 static struct caif_device_entry *caif_get(struct net_device *dev) 85 { 86 struct caif_device_entry_list *caifdevs = 87 caif_device_list(dev_net(dev)); 88 struct caif_device_entry *caifd; 89 BUG_ON(!caifdevs); 90 list_for_each_entry(caifd, &caifdevs->list, list) { 91 if (caifd->netdev == dev) 92 return caifd; 93 } 94 return NULL; 95 } 96 97 static void caif_device_destroy(struct net_device *dev) 98 { 99 struct caif_device_entry_list *caifdevs = 100 caif_device_list(dev_net(dev)); 101 struct caif_device_entry *caifd; 102 ASSERT_RTNL(); 103 if (dev->type != ARPHRD_CAIF) 104 return; 105 106 spin_lock_bh(&caifdevs->lock); 107 caifd = caif_get(dev); 108 if (caifd == NULL) { 109 spin_unlock_bh(&caifdevs->lock); 110 return; 111 } 112 113 list_del(&caifd->list); 114 spin_unlock_bh(&caifdevs->lock); 115 116 kfree(caifd); 117 } 118 119 static int transmit(struct cflayer *layer, struct cfpkt *pkt) 120 { 121 struct caif_device_entry *caifd = 122 container_of(layer, struct caif_device_entry, layer); 123 struct sk_buff *skb, *skb2; 124 int ret = -EINVAL; 125 skb = cfpkt_tonative(pkt); 126 skb->dev = caifd->netdev; 127 /* 128 * Don't allow SKB to be destroyed upon error, but signal resend 129 * notification to clients. We can't rely on the return value as 130 * congestion (NET_XMIT_CN) sometimes drops the packet, sometimes don't. 131 */ 132 if (netif_queue_stopped(caifd->netdev)) 133 return -EAGAIN; 134 skb2 = skb_get(skb); 135 136 ret = dev_queue_xmit(skb2); 137 138 if (!ret) 139 kfree_skb(skb); 140 else 141 return -EAGAIN; 142 143 return 0; 144 } 145 146 static int modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) 147 { 148 struct caif_device_entry *caifd; 149 struct caif_dev_common *caifdev; 150 caifd = container_of(layr, struct caif_device_entry, layer); 151 caifdev = netdev_priv(caifd->netdev); 152 if (ctrl == _CAIF_MODEMCMD_PHYIF_USEFULL) { 153 atomic_set(&caifd->in_use, 1); 154 wake_up_interruptible(&caifd->event); 155 156 } else if (ctrl == _CAIF_MODEMCMD_PHYIF_USELESS) { 157 atomic_set(&caifd->in_use, 0); 158 wake_up_interruptible(&caifd->event); 159 } 160 return 0; 161 } 162 163 /* 164 * Stuff received packets to associated sockets. 165 * On error, returns non-zero and releases the skb. 166 */ 167 static int receive(struct sk_buff *skb, struct net_device *dev, 168 struct packet_type *pkttype, struct net_device *orig_dev) 169 { 170 struct net *net; 171 struct cfpkt *pkt; 172 struct caif_device_entry *caifd; 173 net = dev_net(dev); 174 pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); 175 caifd = caif_get(dev); 176 if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) 177 return NET_RX_DROP; 178 179 if (caifd->layer.up->receive(caifd->layer.up, pkt)) 180 return NET_RX_DROP; 181 182 return 0; 183 } 184 185 static struct packet_type caif_packet_type __read_mostly = { 186 .type = cpu_to_be16(ETH_P_CAIF), 187 .func = receive, 188 }; 189 190 static void dev_flowctrl(struct net_device *dev, int on) 191 { 192 struct caif_device_entry *caifd = caif_get(dev); 193 if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) 194 return; 195 196 caifd->layer.up->ctrlcmd(caifd->layer.up, 197 on ? 198 _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND : 199 _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND, 200 caifd->layer.id); 201 } 202 203 /* notify Caif of device events */ 204 static int caif_device_notify(struct notifier_block *me, unsigned long what, 205 void *arg) 206 { 207 struct net_device *dev = arg; 208 struct caif_device_entry *caifd = NULL; 209 struct caif_dev_common *caifdev; 210 enum cfcnfg_phy_preference pref; 211 int res = -EINVAL; 212 enum cfcnfg_phy_type phy_type; 213 214 if (dev->type != ARPHRD_CAIF) 215 return 0; 216 217 switch (what) { 218 case NETDEV_REGISTER: 219 pr_info("register %s\n", dev->name); 220 caifd = caif_device_alloc(dev); 221 if (caifd == NULL) 222 break; 223 caifdev = netdev_priv(dev); 224 caifdev->flowctrl = dev_flowctrl; 225 atomic_set(&caifd->state, what); 226 res = 0; 227 break; 228 229 case NETDEV_UP: 230 pr_info("up %s\n", dev->name); 231 caifd = caif_get(dev); 232 if (caifd == NULL) 233 break; 234 caifdev = netdev_priv(dev); 235 if (atomic_read(&caifd->state) == NETDEV_UP) { 236 pr_info("%s already up\n", dev->name); 237 break; 238 } 239 atomic_set(&caifd->state, what); 240 caifd->layer.transmit = transmit; 241 caifd->layer.modemcmd = modemcmd; 242 243 if (caifdev->use_frag) 244 phy_type = CFPHYTYPE_FRAG; 245 else 246 phy_type = CFPHYTYPE_CAIF; 247 248 switch (caifdev->link_select) { 249 case CAIF_LINK_HIGH_BANDW: 250 pref = CFPHYPREF_HIGH_BW; 251 break; 252 case CAIF_LINK_LOW_LATENCY: 253 pref = CFPHYPREF_LOW_LAT; 254 break; 255 default: 256 pref = CFPHYPREF_HIGH_BW; 257 break; 258 } 259 dev_hold(dev); 260 cfcnfg_add_phy_layer(get_caif_conf(), 261 phy_type, 262 dev, 263 &caifd->layer, 264 &caifd->phyid, 265 pref, 266 caifdev->use_fcs, 267 caifdev->use_stx); 268 strncpy(caifd->layer.name, dev->name, 269 sizeof(caifd->layer.name) - 1); 270 caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0; 271 break; 272 273 case NETDEV_GOING_DOWN: 274 caifd = caif_get(dev); 275 if (caifd == NULL) 276 break; 277 pr_info("going down %s\n", dev->name); 278 279 if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN || 280 atomic_read(&caifd->state) == NETDEV_DOWN) 281 break; 282 283 atomic_set(&caifd->state, what); 284 if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) 285 return -EINVAL; 286 caifd->layer.up->ctrlcmd(caifd->layer.up, 287 _CAIF_CTRLCMD_PHYIF_DOWN_IND, 288 caifd->layer.id); 289 might_sleep(); 290 res = wait_event_interruptible_timeout(caifd->event, 291 atomic_read(&caifd->in_use) == 0, 292 TIMEOUT); 293 break; 294 295 case NETDEV_DOWN: 296 caifd = caif_get(dev); 297 if (caifd == NULL) 298 break; 299 pr_info("down %s\n", dev->name); 300 if (atomic_read(&caifd->in_use)) 301 pr_warn("Unregistering an active CAIF device: %s\n", 302 dev->name); 303 cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); 304 dev_put(dev); 305 atomic_set(&caifd->state, what); 306 break; 307 308 case NETDEV_UNREGISTER: 309 caifd = caif_get(dev); 310 pr_info("unregister %s\n", dev->name); 311 atomic_set(&caifd->state, what); 312 caif_device_destroy(dev); 313 break; 314 } 315 return 0; 316 } 317 318 static struct notifier_block caif_device_notifier = { 319 .notifier_call = caif_device_notify, 320 .priority = 0, 321 }; 322 323 324 struct cfcnfg *get_caif_conf(void) 325 { 326 return cfg; 327 } 328 EXPORT_SYMBOL(get_caif_conf); 329 330 int caif_connect_client(struct caif_connect_request *conn_req, 331 struct cflayer *client_layer, int *ifindex, 332 int *headroom, int *tailroom) 333 { 334 struct cfctrl_link_param param; 335 int ret; 336 ret = connect_req_to_link_param(get_caif_conf(), conn_req, ¶m); 337 if (ret) 338 return ret; 339 /* Hook up the adaptation layer. */ 340 return cfcnfg_add_adaptation_layer(get_caif_conf(), ¶m, 341 client_layer, ifindex, 342 headroom, tailroom); 343 } 344 EXPORT_SYMBOL(caif_connect_client); 345 346 int caif_disconnect_client(struct cflayer *adap_layer) 347 { 348 return cfcnfg_disconn_adapt_layer(get_caif_conf(), adap_layer); 349 } 350 EXPORT_SYMBOL(caif_disconnect_client); 351 352 void caif_release_client(struct cflayer *adap_layer) 353 { 354 cfcnfg_release_adap_layer(adap_layer); 355 } 356 EXPORT_SYMBOL(caif_release_client); 357 358 /* Per-namespace Caif devices handling */ 359 static int caif_init_net(struct net *net) 360 { 361 struct caif_net *caifn = net_generic(net, caif_net_id); 362 INIT_LIST_HEAD(&caifn->caifdevs.list); 363 spin_lock_init(&caifn->caifdevs.lock); 364 return 0; 365 } 366 367 static void caif_exit_net(struct net *net) 368 { 369 struct net_device *dev; 370 int res; 371 rtnl_lock(); 372 for_each_netdev(net, dev) { 373 if (dev->type != ARPHRD_CAIF) 374 continue; 375 res = dev_close(dev); 376 caif_device_destroy(dev); 377 } 378 rtnl_unlock(); 379 } 380 381 static struct pernet_operations caif_net_ops = { 382 .init = caif_init_net, 383 .exit = caif_exit_net, 384 .id = &caif_net_id, 385 .size = sizeof(struct caif_net), 386 }; 387 388 /* Initialize Caif devices list */ 389 static int __init caif_device_init(void) 390 { 391 int result; 392 cfg = cfcnfg_create(); 393 if (!cfg) { 394 pr_warn("can't create cfcnfg\n"); 395 goto err_cfcnfg_create_failed; 396 } 397 result = register_pernet_device(&caif_net_ops); 398 399 if (result) { 400 kfree(cfg); 401 cfg = NULL; 402 return result; 403 } 404 dev_add_pack(&caif_packet_type); 405 register_netdevice_notifier(&caif_device_notifier); 406 407 return result; 408 err_cfcnfg_create_failed: 409 return -ENODEV; 410 } 411 412 static void __exit caif_device_exit(void) 413 { 414 dev_remove_pack(&caif_packet_type); 415 unregister_pernet_device(&caif_net_ops); 416 unregister_netdevice_notifier(&caif_device_notifier); 417 cfcnfg_remove(cfg); 418 } 419 420 module_init(caif_device_init); 421 module_exit(caif_device_exit); 422