1 /* 2 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 * Maintained at www.Open-FCoE.org 18 */ 19 20 #include <linux/types.h> 21 #include <linux/module.h> 22 #include <linux/kernel.h> 23 #include <linux/list.h> 24 #include <linux/netdevice.h> 25 #include <linux/errno.h> 26 #include <linux/crc32.h> 27 #include <scsi/libfcoe.h> 28 29 #include "libfcoe.h" 30 31 MODULE_AUTHOR("Open-FCoE.org"); 32 MODULE_DESCRIPTION("FIP discovery protocol and FCoE transport for FCoE HBAs"); 33 MODULE_LICENSE("GPL v2"); 34 35 static int fcoe_transport_create(const char *, struct kernel_param *); 36 static int fcoe_transport_destroy(const char *, struct kernel_param *); 37 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp); 38 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *device); 39 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *device); 40 static int fcoe_transport_enable(const char *, struct kernel_param *); 41 static int fcoe_transport_disable(const char *, struct kernel_param *); 42 static int libfcoe_device_notification(struct notifier_block *notifier, 43 ulong event, void *ptr); 44 45 static LIST_HEAD(fcoe_transports); 46 static DEFINE_MUTEX(ft_mutex); 47 static LIST_HEAD(fcoe_netdevs); 48 static DEFINE_MUTEX(fn_mutex); 49 50 unsigned int libfcoe_debug_logging; 51 module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); 52 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); 53 54 module_param_call(show, NULL, fcoe_transport_show, NULL, S_IRUSR); 55 __MODULE_PARM_TYPE(show, "string"); 56 MODULE_PARM_DESC(show, " Show attached FCoE transports"); 57 58 module_param_call(create, fcoe_transport_create, NULL, 59 (void *)FIP_MODE_FABRIC, S_IWUSR); 60 __MODULE_PARM_TYPE(create, "string"); 61 MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); 62 63 module_param_call(create_vn2vn, fcoe_transport_create, NULL, 64 (void *)FIP_MODE_VN2VN, S_IWUSR); 65 __MODULE_PARM_TYPE(create_vn2vn, "string"); 66 MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance " 67 "on an Ethernet interface"); 68 69 module_param_call(destroy, fcoe_transport_destroy, NULL, NULL, S_IWUSR); 70 __MODULE_PARM_TYPE(destroy, "string"); 71 MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); 72 73 module_param_call(enable, fcoe_transport_enable, NULL, NULL, S_IWUSR); 74 __MODULE_PARM_TYPE(enable, "string"); 75 MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); 76 77 module_param_call(disable, fcoe_transport_disable, NULL, NULL, S_IWUSR); 78 __MODULE_PARM_TYPE(disable, "string"); 79 MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); 80 81 /* notification function for packets from net device */ 82 static struct notifier_block libfcoe_notifier = { 83 .notifier_call = libfcoe_device_notification, 84 }; 85 86 void __fcoe_get_lesb(struct fc_lport *lport, 87 struct fc_els_lesb *fc_lesb, 88 struct net_device *netdev) 89 { 90 unsigned int cpu; 91 u32 lfc, vlfc, mdac; 92 struct fcoe_dev_stats *devst; 93 struct fcoe_fc_els_lesb *lesb; 94 struct rtnl_link_stats64 temp; 95 96 lfc = 0; 97 vlfc = 0; 98 mdac = 0; 99 lesb = (struct fcoe_fc_els_lesb *)fc_lesb; 100 memset(lesb, 0, sizeof(*lesb)); 101 for_each_possible_cpu(cpu) { 102 devst = per_cpu_ptr(lport->dev_stats, cpu); 103 lfc += devst->LinkFailureCount; 104 vlfc += devst->VLinkFailureCount; 105 mdac += devst->MissDiscAdvCount; 106 } 107 lesb->lesb_link_fail = htonl(lfc); 108 lesb->lesb_vlink_fail = htonl(vlfc); 109 lesb->lesb_miss_fka = htonl(mdac); 110 lesb->lesb_fcs_error = 111 htonl(dev_get_stats(netdev, &temp)->rx_crc_errors); 112 } 113 EXPORT_SYMBOL_GPL(__fcoe_get_lesb); 114 115 void fcoe_wwn_to_str(u64 wwn, char *buf, int len) 116 { 117 u8 wwpn[8]; 118 119 u64_to_wwn(wwn, wwpn); 120 snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", 121 wwpn[0], wwpn[1], wwpn[2], wwpn[3], 122 wwpn[4], wwpn[5], wwpn[6], wwpn[7]); 123 } 124 EXPORT_SYMBOL_GPL(fcoe_wwn_to_str); 125 126 /** 127 * fcoe_validate_vport_create() - Validate a vport before creating it 128 * @vport: NPIV port to be created 129 * 130 * This routine is meant to add validation for a vport before creating it 131 * via fcoe_vport_create(). 132 * Current validations are: 133 * - WWPN supplied is unique for given lport 134 */ 135 int fcoe_validate_vport_create(struct fc_vport *vport) 136 { 137 struct Scsi_Host *shost = vport_to_shost(vport); 138 struct fc_lport *n_port = shost_priv(shost); 139 struct fc_lport *vn_port; 140 int rc = 0; 141 char buf[32]; 142 143 mutex_lock(&n_port->lp_mutex); 144 145 fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); 146 /* Check if the wwpn is not same as that of the lport */ 147 if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { 148 LIBFCOE_TRANSPORT_DBG("vport WWPN 0x%s is same as that of the " 149 "base port WWPN\n", buf); 150 rc = -EINVAL; 151 goto out; 152 } 153 154 /* Check if there is any existing vport with same wwpn */ 155 list_for_each_entry(vn_port, &n_port->vports, list) { 156 if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { 157 LIBFCOE_TRANSPORT_DBG("vport with given WWPN 0x%s " 158 "already exists\n", buf); 159 rc = -EINVAL; 160 break; 161 } 162 } 163 out: 164 mutex_unlock(&n_port->lp_mutex); 165 return rc; 166 } 167 EXPORT_SYMBOL_GPL(fcoe_validate_vport_create); 168 169 /** 170 * fcoe_get_wwn() - Get the world wide name from LLD if it supports it 171 * @netdev: the associated net device 172 * @wwn: the output WWN 173 * @type: the type of WWN (WWPN or WWNN) 174 * 175 * Returns: 0 for success 176 */ 177 int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) 178 { 179 const struct net_device_ops *ops = netdev->netdev_ops; 180 181 if (ops->ndo_fcoe_get_wwn) 182 return ops->ndo_fcoe_get_wwn(netdev, wwn, type); 183 return -EINVAL; 184 } 185 EXPORT_SYMBOL_GPL(fcoe_get_wwn); 186 187 /** 188 * fcoe_fc_crc() - Calculates the CRC for a given frame 189 * @fp: The frame to be checksumed 190 * 191 * This uses crc32() routine to calculate the CRC for a frame 192 * 193 * Return: The 32 bit CRC value 194 */ 195 u32 fcoe_fc_crc(struct fc_frame *fp) 196 { 197 struct sk_buff *skb = fp_skb(fp); 198 struct skb_frag_struct *frag; 199 unsigned char *data; 200 unsigned long off, len, clen; 201 u32 crc; 202 unsigned i; 203 204 crc = crc32(~0, skb->data, skb_headlen(skb)); 205 206 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 207 frag = &skb_shinfo(skb)->frags[i]; 208 off = frag->page_offset; 209 len = skb_frag_size(frag); 210 while (len > 0) { 211 clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK)); 212 data = kmap_atomic( 213 skb_frag_page(frag) + (off >> PAGE_SHIFT), 214 KM_SKB_DATA_SOFTIRQ); 215 crc = crc32(crc, data + (off & ~PAGE_MASK), clen); 216 kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ); 217 off += clen; 218 len -= clen; 219 } 220 } 221 return crc; 222 } 223 EXPORT_SYMBOL_GPL(fcoe_fc_crc); 224 225 /** 226 * fcoe_start_io() - Start FCoE I/O 227 * @skb: The packet to be transmitted 228 * 229 * This routine is called from the net device to start transmitting 230 * FCoE packets. 231 * 232 * Returns: 0 for success 233 */ 234 int fcoe_start_io(struct sk_buff *skb) 235 { 236 struct sk_buff *nskb; 237 int rc; 238 239 nskb = skb_clone(skb, GFP_ATOMIC); 240 if (!nskb) 241 return -ENOMEM; 242 rc = dev_queue_xmit(nskb); 243 if (rc != 0) 244 return rc; 245 kfree_skb(skb); 246 return 0; 247 } 248 EXPORT_SYMBOL_GPL(fcoe_start_io); 249 250 251 /** 252 * fcoe_clean_pending_queue() - Dequeue a skb and free it 253 * @lport: The local port to dequeue a skb on 254 */ 255 void fcoe_clean_pending_queue(struct fc_lport *lport) 256 { 257 struct fcoe_port *port = lport_priv(lport); 258 struct sk_buff *skb; 259 260 spin_lock_bh(&port->fcoe_pending_queue.lock); 261 while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) { 262 spin_unlock_bh(&port->fcoe_pending_queue.lock); 263 kfree_skb(skb); 264 spin_lock_bh(&port->fcoe_pending_queue.lock); 265 } 266 spin_unlock_bh(&port->fcoe_pending_queue.lock); 267 } 268 EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue); 269 270 /** 271 * fcoe_check_wait_queue() - Attempt to clear the transmit backlog 272 * @lport: The local port whose backlog is to be cleared 273 * 274 * This empties the wait_queue, dequeues the head of the wait_queue queue 275 * and calls fcoe_start_io() for each packet. If all skb have been 276 * transmitted it returns the qlen. If an error occurs it restores 277 * wait_queue (to try again later) and returns -1. 278 * 279 * The wait_queue is used when the skb transmit fails. The failed skb 280 * will go in the wait_queue which will be emptied by the timer function or 281 * by the next skb transmit. 282 */ 283 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb) 284 { 285 struct fcoe_port *port = lport_priv(lport); 286 int rc; 287 288 spin_lock_bh(&port->fcoe_pending_queue.lock); 289 290 if (skb) 291 __skb_queue_tail(&port->fcoe_pending_queue, skb); 292 293 if (port->fcoe_pending_queue_active) 294 goto out; 295 port->fcoe_pending_queue_active = 1; 296 297 while (port->fcoe_pending_queue.qlen) { 298 /* keep qlen > 0 until fcoe_start_io succeeds */ 299 port->fcoe_pending_queue.qlen++; 300 skb = __skb_dequeue(&port->fcoe_pending_queue); 301 302 spin_unlock_bh(&port->fcoe_pending_queue.lock); 303 rc = fcoe_start_io(skb); 304 spin_lock_bh(&port->fcoe_pending_queue.lock); 305 306 if (rc) { 307 __skb_queue_head(&port->fcoe_pending_queue, skb); 308 /* undo temporary increment above */ 309 port->fcoe_pending_queue.qlen--; 310 break; 311 } 312 /* undo temporary increment above */ 313 port->fcoe_pending_queue.qlen--; 314 } 315 316 if (port->fcoe_pending_queue.qlen < port->min_queue_depth) 317 lport->qfull = 0; 318 if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer)) 319 mod_timer(&port->timer, jiffies + 2); 320 port->fcoe_pending_queue_active = 0; 321 out: 322 if (port->fcoe_pending_queue.qlen > port->max_queue_depth) 323 lport->qfull = 1; 324 spin_unlock_bh(&port->fcoe_pending_queue.lock); 325 } 326 EXPORT_SYMBOL_GPL(fcoe_check_wait_queue); 327 328 /** 329 * fcoe_queue_timer() - The fcoe queue timer 330 * @lport: The local port 331 * 332 * Calls fcoe_check_wait_queue on timeout 333 */ 334 void fcoe_queue_timer(ulong lport) 335 { 336 fcoe_check_wait_queue((struct fc_lport *)lport, NULL); 337 } 338 EXPORT_SYMBOL_GPL(fcoe_queue_timer); 339 340 /** 341 * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC 342 * @skb: The packet to be transmitted 343 * @tlen: The total length of the trailer 344 * @fps: The fcoe context 345 * 346 * This routine allocates a page for frame trailers. The page is re-used if 347 * there is enough room left on it for the current trailer. If there isn't 348 * enough buffer left a new page is allocated for the trailer. Reference to 349 * the page from this function as well as the skbs using the page fragments 350 * ensure that the page is freed at the appropriate time. 351 * 352 * Returns: 0 for success 353 */ 354 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, 355 struct fcoe_percpu_s *fps) 356 { 357 struct page *page; 358 359 page = fps->crc_eof_page; 360 if (!page) { 361 page = alloc_page(GFP_ATOMIC); 362 if (!page) 363 return -ENOMEM; 364 365 fps->crc_eof_page = page; 366 fps->crc_eof_offset = 0; 367 } 368 369 get_page(page); 370 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page, 371 fps->crc_eof_offset, tlen); 372 skb->len += tlen; 373 skb->data_len += tlen; 374 skb->truesize += tlen; 375 fps->crc_eof_offset += sizeof(struct fcoe_crc_eof); 376 377 if (fps->crc_eof_offset >= PAGE_SIZE) { 378 fps->crc_eof_page = NULL; 379 fps->crc_eof_offset = 0; 380 put_page(page); 381 } 382 383 return 0; 384 } 385 EXPORT_SYMBOL_GPL(fcoe_get_paged_crc_eof); 386 387 /** 388 * fcoe_transport_lookup - find an fcoe transport that matches a netdev 389 * @netdev: The netdev to look for from all attached transports 390 * 391 * Returns : ptr to the fcoe transport that supports this netdev or NULL 392 * if not found. 393 * 394 * The ft_mutex should be held when this is called 395 */ 396 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *netdev) 397 { 398 struct fcoe_transport *ft = NULL; 399 400 list_for_each_entry(ft, &fcoe_transports, list) 401 if (ft->match && ft->match(netdev)) 402 return ft; 403 return NULL; 404 } 405 406 /** 407 * fcoe_transport_attach - Attaches an FCoE transport 408 * @ft: The fcoe transport to be attached 409 * 410 * Returns : 0 for success 411 */ 412 int fcoe_transport_attach(struct fcoe_transport *ft) 413 { 414 int rc = 0; 415 416 mutex_lock(&ft_mutex); 417 if (ft->attached) { 418 LIBFCOE_TRANSPORT_DBG("transport %s already attached\n", 419 ft->name); 420 rc = -EEXIST; 421 goto out_attach; 422 } 423 424 /* Add default transport to the tail */ 425 if (strcmp(ft->name, FCOE_TRANSPORT_DEFAULT)) 426 list_add(&ft->list, &fcoe_transports); 427 else 428 list_add_tail(&ft->list, &fcoe_transports); 429 430 ft->attached = true; 431 LIBFCOE_TRANSPORT_DBG("attaching transport %s\n", ft->name); 432 433 out_attach: 434 mutex_unlock(&ft_mutex); 435 return rc; 436 } 437 EXPORT_SYMBOL(fcoe_transport_attach); 438 439 /** 440 * fcoe_transport_detach - Detaches an FCoE transport 441 * @ft: The fcoe transport to be attached 442 * 443 * Returns : 0 for success 444 */ 445 int fcoe_transport_detach(struct fcoe_transport *ft) 446 { 447 int rc = 0; 448 struct fcoe_netdev_mapping *nm = NULL, *tmp; 449 450 mutex_lock(&ft_mutex); 451 if (!ft->attached) { 452 LIBFCOE_TRANSPORT_DBG("transport %s already detached\n", 453 ft->name); 454 rc = -ENODEV; 455 goto out_attach; 456 } 457 458 /* remove netdev mapping for this transport as it is going away */ 459 mutex_lock(&fn_mutex); 460 list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) { 461 if (nm->ft == ft) { 462 LIBFCOE_TRANSPORT_DBG("transport %s going away, " 463 "remove its netdev mapping for %s\n", 464 ft->name, nm->netdev->name); 465 list_del(&nm->list); 466 kfree(nm); 467 } 468 } 469 mutex_unlock(&fn_mutex); 470 471 list_del(&ft->list); 472 ft->attached = false; 473 LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name); 474 475 out_attach: 476 mutex_unlock(&ft_mutex); 477 return rc; 478 479 } 480 EXPORT_SYMBOL(fcoe_transport_detach); 481 482 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp) 483 { 484 int i, j; 485 struct fcoe_transport *ft = NULL; 486 487 i = j = sprintf(buffer, "Attached FCoE transports:"); 488 mutex_lock(&ft_mutex); 489 list_for_each_entry(ft, &fcoe_transports, list) { 490 if (i >= PAGE_SIZE - IFNAMSIZ) 491 break; 492 i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name); 493 } 494 mutex_unlock(&ft_mutex); 495 if (i == j) 496 i += snprintf(&buffer[i], IFNAMSIZ, "none"); 497 return i; 498 } 499 500 static int __init fcoe_transport_init(void) 501 { 502 register_netdevice_notifier(&libfcoe_notifier); 503 return 0; 504 } 505 506 static int __exit fcoe_transport_exit(void) 507 { 508 struct fcoe_transport *ft; 509 510 unregister_netdevice_notifier(&libfcoe_notifier); 511 mutex_lock(&ft_mutex); 512 list_for_each_entry(ft, &fcoe_transports, list) 513 printk(KERN_ERR "FCoE transport %s is still attached!\n", 514 ft->name); 515 mutex_unlock(&ft_mutex); 516 return 0; 517 } 518 519 520 static int fcoe_add_netdev_mapping(struct net_device *netdev, 521 struct fcoe_transport *ft) 522 { 523 struct fcoe_netdev_mapping *nm; 524 525 nm = kmalloc(sizeof(*nm), GFP_KERNEL); 526 if (!nm) { 527 printk(KERN_ERR "Unable to allocate netdev_mapping"); 528 return -ENOMEM; 529 } 530 531 nm->netdev = netdev; 532 nm->ft = ft; 533 534 mutex_lock(&fn_mutex); 535 list_add(&nm->list, &fcoe_netdevs); 536 mutex_unlock(&fn_mutex); 537 return 0; 538 } 539 540 541 static void fcoe_del_netdev_mapping(struct net_device *netdev) 542 { 543 struct fcoe_netdev_mapping *nm = NULL, *tmp; 544 545 mutex_lock(&fn_mutex); 546 list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) { 547 if (nm->netdev == netdev) { 548 list_del(&nm->list); 549 kfree(nm); 550 mutex_unlock(&fn_mutex); 551 return; 552 } 553 } 554 mutex_unlock(&fn_mutex); 555 } 556 557 558 /** 559 * fcoe_netdev_map_lookup - find the fcoe transport that matches the netdev on which 560 * it was created 561 * 562 * Returns : ptr to the fcoe transport that supports this netdev or NULL 563 * if not found. 564 * 565 * The ft_mutex should be held when this is called 566 */ 567 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *netdev) 568 { 569 struct fcoe_transport *ft = NULL; 570 struct fcoe_netdev_mapping *nm; 571 572 mutex_lock(&fn_mutex); 573 list_for_each_entry(nm, &fcoe_netdevs, list) { 574 if (netdev == nm->netdev) { 575 ft = nm->ft; 576 mutex_unlock(&fn_mutex); 577 return ft; 578 } 579 } 580 581 mutex_unlock(&fn_mutex); 582 return NULL; 583 } 584 585 /** 586 * fcoe_if_to_netdev() - Parse a name buffer to get a net device 587 * @buffer: The name of the net device 588 * 589 * Returns: NULL or a ptr to net_device 590 */ 591 static struct net_device *fcoe_if_to_netdev(const char *buffer) 592 { 593 char *cp; 594 char ifname[IFNAMSIZ + 2]; 595 596 if (buffer) { 597 strlcpy(ifname, buffer, IFNAMSIZ); 598 cp = ifname + strlen(ifname); 599 while (--cp >= ifname && *cp == '\n') 600 *cp = '\0'; 601 return dev_get_by_name(&init_net, ifname); 602 } 603 return NULL; 604 } 605 606 /** 607 * libfcoe_device_notification() - Handler for net device events 608 * @notifier: The context of the notification 609 * @event: The type of event 610 * @ptr: The net device that the event was on 611 * 612 * This function is called by the Ethernet driver in case of link change event. 613 * 614 * Returns: 0 for success 615 */ 616 static int libfcoe_device_notification(struct notifier_block *notifier, 617 ulong event, void *ptr) 618 { 619 struct net_device *netdev = ptr; 620 621 switch (event) { 622 case NETDEV_UNREGISTER: 623 printk(KERN_ERR "libfcoe_device_notification: NETDEV_UNREGISTER %s\n", 624 netdev->name); 625 fcoe_del_netdev_mapping(netdev); 626 break; 627 } 628 return NOTIFY_OK; 629 } 630 631 632 /** 633 * fcoe_transport_create() - Create a fcoe interface 634 * @buffer: The name of the Ethernet interface to create on 635 * @kp: The associated kernel param 636 * 637 * Called from sysfs. This holds the ft_mutex while calling the 638 * registered fcoe transport's create function. 639 * 640 * Returns: 0 for success 641 */ 642 static int fcoe_transport_create(const char *buffer, struct kernel_param *kp) 643 { 644 int rc = -ENODEV; 645 struct net_device *netdev = NULL; 646 struct fcoe_transport *ft = NULL; 647 enum fip_state fip_mode = (enum fip_state)(long)kp->arg; 648 649 mutex_lock(&ft_mutex); 650 651 netdev = fcoe_if_to_netdev(buffer); 652 if (!netdev) { 653 LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buffer); 654 goto out_nodev; 655 } 656 657 ft = fcoe_netdev_map_lookup(netdev); 658 if (ft) { 659 LIBFCOE_TRANSPORT_DBG("transport %s already has existing " 660 "FCoE instance on %s.\n", 661 ft->name, netdev->name); 662 rc = -EEXIST; 663 goto out_putdev; 664 } 665 666 ft = fcoe_transport_lookup(netdev); 667 if (!ft) { 668 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 669 netdev->name); 670 goto out_putdev; 671 } 672 673 rc = fcoe_add_netdev_mapping(netdev, ft); 674 if (rc) { 675 LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping " 676 "for FCoE transport %s for %s.\n", 677 ft->name, netdev->name); 678 goto out_putdev; 679 } 680 681 /* pass to transport create */ 682 rc = ft->create ? ft->create(netdev, fip_mode) : -ENODEV; 683 if (rc) 684 fcoe_del_netdev_mapping(netdev); 685 686 LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n", 687 ft->name, (rc) ? "failed" : "succeeded", 688 netdev->name); 689 690 out_putdev: 691 dev_put(netdev); 692 out_nodev: 693 mutex_unlock(&ft_mutex); 694 return rc; 695 } 696 697 /** 698 * fcoe_transport_destroy() - Destroy a FCoE interface 699 * @buffer: The name of the Ethernet interface to be destroyed 700 * @kp: The associated kernel parameter 701 * 702 * Called from sysfs. This holds the ft_mutex while calling the 703 * registered fcoe transport's destroy function. 704 * 705 * Returns: 0 for success 706 */ 707 static int fcoe_transport_destroy(const char *buffer, struct kernel_param *kp) 708 { 709 int rc = -ENODEV; 710 struct net_device *netdev = NULL; 711 struct fcoe_transport *ft = NULL; 712 713 mutex_lock(&ft_mutex); 714 715 netdev = fcoe_if_to_netdev(buffer); 716 if (!netdev) { 717 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buffer); 718 goto out_nodev; 719 } 720 721 ft = fcoe_netdev_map_lookup(netdev); 722 if (!ft) { 723 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 724 netdev->name); 725 goto out_putdev; 726 } 727 728 /* pass to transport destroy */ 729 rc = ft->destroy ? ft->destroy(netdev) : -ENODEV; 730 fcoe_del_netdev_mapping(netdev); 731 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n", 732 ft->name, (rc) ? "failed" : "succeeded", 733 netdev->name); 734 735 out_putdev: 736 dev_put(netdev); 737 out_nodev: 738 mutex_unlock(&ft_mutex); 739 return rc; 740 } 741 742 /** 743 * fcoe_transport_disable() - Disables a FCoE interface 744 * @buffer: The name of the Ethernet interface to be disabled 745 * @kp: The associated kernel parameter 746 * 747 * Called from sysfs. 748 * 749 * Returns: 0 for success 750 */ 751 static int fcoe_transport_disable(const char *buffer, struct kernel_param *kp) 752 { 753 int rc = -ENODEV; 754 struct net_device *netdev = NULL; 755 struct fcoe_transport *ft = NULL; 756 757 mutex_lock(&ft_mutex); 758 759 netdev = fcoe_if_to_netdev(buffer); 760 if (!netdev) 761 goto out_nodev; 762 763 ft = fcoe_netdev_map_lookup(netdev); 764 if (!ft) 765 goto out_putdev; 766 767 rc = ft->disable ? ft->disable(netdev) : -ENODEV; 768 769 out_putdev: 770 dev_put(netdev); 771 out_nodev: 772 mutex_unlock(&ft_mutex); 773 774 if (rc == -ERESTARTSYS) 775 return restart_syscall(); 776 else 777 return rc; 778 } 779 780 /** 781 * fcoe_transport_enable() - Enables a FCoE interface 782 * @buffer: The name of the Ethernet interface to be enabled 783 * @kp: The associated kernel parameter 784 * 785 * Called from sysfs. 786 * 787 * Returns: 0 for success 788 */ 789 static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp) 790 { 791 int rc = -ENODEV; 792 struct net_device *netdev = NULL; 793 struct fcoe_transport *ft = NULL; 794 795 mutex_lock(&ft_mutex); 796 797 netdev = fcoe_if_to_netdev(buffer); 798 if (!netdev) 799 goto out_nodev; 800 801 ft = fcoe_netdev_map_lookup(netdev); 802 if (!ft) 803 goto out_putdev; 804 805 rc = ft->enable ? ft->enable(netdev) : -ENODEV; 806 807 out_putdev: 808 dev_put(netdev); 809 out_nodev: 810 mutex_unlock(&ft_mutex); 811 return rc; 812 } 813 814 /** 815 * libfcoe_init() - Initialization routine for libfcoe.ko 816 */ 817 static int __init libfcoe_init(void) 818 { 819 fcoe_transport_init(); 820 821 return 0; 822 } 823 module_init(libfcoe_init); 824 825 /** 826 * libfcoe_exit() - Tear down libfcoe.ko 827 */ 828 static void __exit libfcoe_exit(void) 829 { 830 fcoe_transport_exit(); 831 } 832 module_exit(libfcoe_exit); 833