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 /** 87 * fcoe_link_speed_update() - Update the supported and actual link speeds 88 * @lport: The local port to update speeds for 89 * 90 * Returns: 0 if the ethtool query was successful 91 * -1 if the ethtool query failed 92 */ 93 int fcoe_link_speed_update(struct fc_lport *lport) 94 { 95 struct net_device *netdev = fcoe_get_netdev(lport); 96 struct ethtool_cmd ecmd; 97 98 if (!__ethtool_get_settings(netdev, &ecmd)) { 99 lport->link_supported_speeds &= 100 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); 101 if (ecmd.supported & (SUPPORTED_1000baseT_Half | 102 SUPPORTED_1000baseT_Full)) 103 lport->link_supported_speeds |= FC_PORTSPEED_1GBIT; 104 if (ecmd.supported & SUPPORTED_10000baseT_Full) 105 lport->link_supported_speeds |= 106 FC_PORTSPEED_10GBIT; 107 switch (ethtool_cmd_speed(&ecmd)) { 108 case SPEED_1000: 109 lport->link_speed = FC_PORTSPEED_1GBIT; 110 break; 111 case SPEED_10000: 112 lport->link_speed = FC_PORTSPEED_10GBIT; 113 break; 114 } 115 return 0; 116 } 117 return -1; 118 } 119 EXPORT_SYMBOL_GPL(fcoe_link_speed_update); 120 121 /** 122 * __fcoe_get_lesb() - Get the Link Error Status Block (LESB) for a given lport 123 * @lport: The local port to update speeds for 124 * @fc_lesb: Pointer to the LESB to be filled up 125 * @netdev: Pointer to the netdev that is associated with the lport 126 * 127 * Note, the Link Error Status Block (LESB) for FCoE is defined in FC-BB-6 128 * Clause 7.11 in v1.04. 129 */ 130 void __fcoe_get_lesb(struct fc_lport *lport, 131 struct fc_els_lesb *fc_lesb, 132 struct net_device *netdev) 133 { 134 unsigned int cpu; 135 u32 lfc, vlfc, mdac; 136 struct fc_stats *stats; 137 struct fcoe_fc_els_lesb *lesb; 138 struct rtnl_link_stats64 temp; 139 140 lfc = 0; 141 vlfc = 0; 142 mdac = 0; 143 lesb = (struct fcoe_fc_els_lesb *)fc_lesb; 144 memset(lesb, 0, sizeof(*lesb)); 145 for_each_possible_cpu(cpu) { 146 stats = per_cpu_ptr(lport->stats, cpu); 147 lfc += stats->LinkFailureCount; 148 vlfc += stats->VLinkFailureCount; 149 mdac += stats->MissDiscAdvCount; 150 } 151 lesb->lesb_link_fail = htonl(lfc); 152 lesb->lesb_vlink_fail = htonl(vlfc); 153 lesb->lesb_miss_fka = htonl(mdac); 154 lesb->lesb_fcs_error = 155 htonl(dev_get_stats(netdev, &temp)->rx_crc_errors); 156 } 157 EXPORT_SYMBOL_GPL(__fcoe_get_lesb); 158 159 /** 160 * fcoe_get_lesb() - Fill the FCoE Link Error Status Block 161 * @lport: the local port 162 * @fc_lesb: the link error status block 163 */ 164 void fcoe_get_lesb(struct fc_lport *lport, 165 struct fc_els_lesb *fc_lesb) 166 { 167 struct net_device *netdev = fcoe_get_netdev(lport); 168 169 __fcoe_get_lesb(lport, fc_lesb, netdev); 170 } 171 EXPORT_SYMBOL_GPL(fcoe_get_lesb); 172 173 /** 174 * fcoe_ctlr_get_lesb() - Get the Link Error Status Block (LESB) for a given 175 * fcoe controller device 176 * @ctlr_dev: The given fcoe controller device 177 * 178 */ 179 void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) 180 { 181 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 182 struct net_device *netdev = fcoe_get_netdev(fip->lp); 183 struct fcoe_fc_els_lesb *fcoe_lesb; 184 struct fc_els_lesb fc_lesb; 185 186 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); 187 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); 188 189 ctlr_dev->lesb.lesb_link_fail = 190 ntohl(fcoe_lesb->lesb_link_fail); 191 ctlr_dev->lesb.lesb_vlink_fail = 192 ntohl(fcoe_lesb->lesb_vlink_fail); 193 ctlr_dev->lesb.lesb_miss_fka = 194 ntohl(fcoe_lesb->lesb_miss_fka); 195 ctlr_dev->lesb.lesb_symb_err = 196 ntohl(fcoe_lesb->lesb_symb_err); 197 ctlr_dev->lesb.lesb_err_block = 198 ntohl(fcoe_lesb->lesb_err_block); 199 ctlr_dev->lesb.lesb_fcs_error = 200 ntohl(fcoe_lesb->lesb_fcs_error); 201 } 202 EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb); 203 204 void fcoe_wwn_to_str(u64 wwn, char *buf, int len) 205 { 206 u8 wwpn[8]; 207 208 u64_to_wwn(wwn, wwpn); 209 snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", 210 wwpn[0], wwpn[1], wwpn[2], wwpn[3], 211 wwpn[4], wwpn[5], wwpn[6], wwpn[7]); 212 } 213 EXPORT_SYMBOL_GPL(fcoe_wwn_to_str); 214 215 /** 216 * fcoe_validate_vport_create() - Validate a vport before creating it 217 * @vport: NPIV port to be created 218 * 219 * This routine is meant to add validation for a vport before creating it 220 * via fcoe_vport_create(). 221 * Current validations are: 222 * - WWPN supplied is unique for given lport 223 */ 224 int fcoe_validate_vport_create(struct fc_vport *vport) 225 { 226 struct Scsi_Host *shost = vport_to_shost(vport); 227 struct fc_lport *n_port = shost_priv(shost); 228 struct fc_lport *vn_port; 229 int rc = 0; 230 char buf[32]; 231 232 mutex_lock(&n_port->lp_mutex); 233 234 fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); 235 /* Check if the wwpn is not same as that of the lport */ 236 if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { 237 LIBFCOE_TRANSPORT_DBG("vport WWPN 0x%s is same as that of the " 238 "base port WWPN\n", buf); 239 rc = -EINVAL; 240 goto out; 241 } 242 243 /* Check if there is any existing vport with same wwpn */ 244 list_for_each_entry(vn_port, &n_port->vports, list) { 245 if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { 246 LIBFCOE_TRANSPORT_DBG("vport with given WWPN 0x%s " 247 "already exists\n", buf); 248 rc = -EINVAL; 249 break; 250 } 251 } 252 out: 253 mutex_unlock(&n_port->lp_mutex); 254 return rc; 255 } 256 EXPORT_SYMBOL_GPL(fcoe_validate_vport_create); 257 258 /** 259 * fcoe_get_wwn() - Get the world wide name from LLD if it supports it 260 * @netdev: the associated net device 261 * @wwn: the output WWN 262 * @type: the type of WWN (WWPN or WWNN) 263 * 264 * Returns: 0 for success 265 */ 266 int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) 267 { 268 const struct net_device_ops *ops = netdev->netdev_ops; 269 270 if (ops->ndo_fcoe_get_wwn) 271 return ops->ndo_fcoe_get_wwn(netdev, wwn, type); 272 return -EINVAL; 273 } 274 EXPORT_SYMBOL_GPL(fcoe_get_wwn); 275 276 /** 277 * fcoe_fc_crc() - Calculates the CRC for a given frame 278 * @fp: The frame to be checksumed 279 * 280 * This uses crc32() routine to calculate the CRC for a frame 281 * 282 * Return: The 32 bit CRC value 283 */ 284 u32 fcoe_fc_crc(struct fc_frame *fp) 285 { 286 struct sk_buff *skb = fp_skb(fp); 287 struct skb_frag_struct *frag; 288 unsigned char *data; 289 unsigned long off, len, clen; 290 u32 crc; 291 unsigned i; 292 293 crc = crc32(~0, skb->data, skb_headlen(skb)); 294 295 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 296 frag = &skb_shinfo(skb)->frags[i]; 297 off = frag->page_offset; 298 len = skb_frag_size(frag); 299 while (len > 0) { 300 clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK)); 301 data = kmap_atomic( 302 skb_frag_page(frag) + (off >> PAGE_SHIFT)); 303 crc = crc32(crc, data + (off & ~PAGE_MASK), clen); 304 kunmap_atomic(data); 305 off += clen; 306 len -= clen; 307 } 308 } 309 return crc; 310 } 311 EXPORT_SYMBOL_GPL(fcoe_fc_crc); 312 313 /** 314 * fcoe_start_io() - Start FCoE I/O 315 * @skb: The packet to be transmitted 316 * 317 * This routine is called from the net device to start transmitting 318 * FCoE packets. 319 * 320 * Returns: 0 for success 321 */ 322 int fcoe_start_io(struct sk_buff *skb) 323 { 324 struct sk_buff *nskb; 325 int rc; 326 327 nskb = skb_clone(skb, GFP_ATOMIC); 328 if (!nskb) 329 return -ENOMEM; 330 rc = dev_queue_xmit(nskb); 331 if (rc != 0) 332 return rc; 333 kfree_skb(skb); 334 return 0; 335 } 336 EXPORT_SYMBOL_GPL(fcoe_start_io); 337 338 339 /** 340 * fcoe_clean_pending_queue() - Dequeue a skb and free it 341 * @lport: The local port to dequeue a skb on 342 */ 343 void fcoe_clean_pending_queue(struct fc_lport *lport) 344 { 345 struct fcoe_port *port = lport_priv(lport); 346 struct sk_buff *skb; 347 348 spin_lock_bh(&port->fcoe_pending_queue.lock); 349 while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) { 350 spin_unlock_bh(&port->fcoe_pending_queue.lock); 351 kfree_skb(skb); 352 spin_lock_bh(&port->fcoe_pending_queue.lock); 353 } 354 spin_unlock_bh(&port->fcoe_pending_queue.lock); 355 } 356 EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue); 357 358 /** 359 * fcoe_check_wait_queue() - Attempt to clear the transmit backlog 360 * @lport: The local port whose backlog is to be cleared 361 * 362 * This empties the wait_queue, dequeues the head of the wait_queue queue 363 * and calls fcoe_start_io() for each packet. If all skb have been 364 * transmitted it returns the qlen. If an error occurs it restores 365 * wait_queue (to try again later) and returns -1. 366 * 367 * The wait_queue is used when the skb transmit fails. The failed skb 368 * will go in the wait_queue which will be emptied by the timer function or 369 * by the next skb transmit. 370 */ 371 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb) 372 { 373 struct fcoe_port *port = lport_priv(lport); 374 int rc; 375 376 spin_lock_bh(&port->fcoe_pending_queue.lock); 377 378 if (skb) 379 __skb_queue_tail(&port->fcoe_pending_queue, skb); 380 381 if (port->fcoe_pending_queue_active) 382 goto out; 383 port->fcoe_pending_queue_active = 1; 384 385 while (port->fcoe_pending_queue.qlen) { 386 /* keep qlen > 0 until fcoe_start_io succeeds */ 387 port->fcoe_pending_queue.qlen++; 388 skb = __skb_dequeue(&port->fcoe_pending_queue); 389 390 spin_unlock_bh(&port->fcoe_pending_queue.lock); 391 rc = fcoe_start_io(skb); 392 spin_lock_bh(&port->fcoe_pending_queue.lock); 393 394 if (rc) { 395 __skb_queue_head(&port->fcoe_pending_queue, skb); 396 /* undo temporary increment above */ 397 port->fcoe_pending_queue.qlen--; 398 break; 399 } 400 /* undo temporary increment above */ 401 port->fcoe_pending_queue.qlen--; 402 } 403 404 if (port->fcoe_pending_queue.qlen < port->min_queue_depth) 405 lport->qfull = 0; 406 if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer)) 407 mod_timer(&port->timer, jiffies + 2); 408 port->fcoe_pending_queue_active = 0; 409 out: 410 if (port->fcoe_pending_queue.qlen > port->max_queue_depth) 411 lport->qfull = 1; 412 spin_unlock_bh(&port->fcoe_pending_queue.lock); 413 } 414 EXPORT_SYMBOL_GPL(fcoe_check_wait_queue); 415 416 /** 417 * fcoe_queue_timer() - The fcoe queue timer 418 * @lport: The local port 419 * 420 * Calls fcoe_check_wait_queue on timeout 421 */ 422 void fcoe_queue_timer(ulong lport) 423 { 424 fcoe_check_wait_queue((struct fc_lport *)lport, NULL); 425 } 426 EXPORT_SYMBOL_GPL(fcoe_queue_timer); 427 428 /** 429 * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC 430 * @skb: The packet to be transmitted 431 * @tlen: The total length of the trailer 432 * @fps: The fcoe context 433 * 434 * This routine allocates a page for frame trailers. The page is re-used if 435 * there is enough room left on it for the current trailer. If there isn't 436 * enough buffer left a new page is allocated for the trailer. Reference to 437 * the page from this function as well as the skbs using the page fragments 438 * ensure that the page is freed at the appropriate time. 439 * 440 * Returns: 0 for success 441 */ 442 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, 443 struct fcoe_percpu_s *fps) 444 { 445 struct page *page; 446 447 page = fps->crc_eof_page; 448 if (!page) { 449 page = alloc_page(GFP_ATOMIC); 450 if (!page) 451 return -ENOMEM; 452 453 fps->crc_eof_page = page; 454 fps->crc_eof_offset = 0; 455 } 456 457 get_page(page); 458 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page, 459 fps->crc_eof_offset, tlen); 460 skb->len += tlen; 461 skb->data_len += tlen; 462 skb->truesize += tlen; 463 fps->crc_eof_offset += sizeof(struct fcoe_crc_eof); 464 465 if (fps->crc_eof_offset >= PAGE_SIZE) { 466 fps->crc_eof_page = NULL; 467 fps->crc_eof_offset = 0; 468 put_page(page); 469 } 470 471 return 0; 472 } 473 EXPORT_SYMBOL_GPL(fcoe_get_paged_crc_eof); 474 475 /** 476 * fcoe_transport_lookup - find an fcoe transport that matches a netdev 477 * @netdev: The netdev to look for from all attached transports 478 * 479 * Returns : ptr to the fcoe transport that supports this netdev or NULL 480 * if not found. 481 * 482 * The ft_mutex should be held when this is called 483 */ 484 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *netdev) 485 { 486 struct fcoe_transport *ft = NULL; 487 488 list_for_each_entry(ft, &fcoe_transports, list) 489 if (ft->match && ft->match(netdev)) 490 return ft; 491 return NULL; 492 } 493 494 /** 495 * fcoe_transport_attach - Attaches an FCoE transport 496 * @ft: The fcoe transport to be attached 497 * 498 * Returns : 0 for success 499 */ 500 int fcoe_transport_attach(struct fcoe_transport *ft) 501 { 502 int rc = 0; 503 504 mutex_lock(&ft_mutex); 505 if (ft->attached) { 506 LIBFCOE_TRANSPORT_DBG("transport %s already attached\n", 507 ft->name); 508 rc = -EEXIST; 509 goto out_attach; 510 } 511 512 /* Add default transport to the tail */ 513 if (strcmp(ft->name, FCOE_TRANSPORT_DEFAULT)) 514 list_add(&ft->list, &fcoe_transports); 515 else 516 list_add_tail(&ft->list, &fcoe_transports); 517 518 ft->attached = true; 519 LIBFCOE_TRANSPORT_DBG("attaching transport %s\n", ft->name); 520 521 out_attach: 522 mutex_unlock(&ft_mutex); 523 return rc; 524 } 525 EXPORT_SYMBOL(fcoe_transport_attach); 526 527 /** 528 * fcoe_transport_detach - Detaches an FCoE transport 529 * @ft: The fcoe transport to be attached 530 * 531 * Returns : 0 for success 532 */ 533 int fcoe_transport_detach(struct fcoe_transport *ft) 534 { 535 int rc = 0; 536 struct fcoe_netdev_mapping *nm = NULL, *tmp; 537 538 mutex_lock(&ft_mutex); 539 if (!ft->attached) { 540 LIBFCOE_TRANSPORT_DBG("transport %s already detached\n", 541 ft->name); 542 rc = -ENODEV; 543 goto out_attach; 544 } 545 546 /* remove netdev mapping for this transport as it is going away */ 547 mutex_lock(&fn_mutex); 548 list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) { 549 if (nm->ft == ft) { 550 LIBFCOE_TRANSPORT_DBG("transport %s going away, " 551 "remove its netdev mapping for %s\n", 552 ft->name, nm->netdev->name); 553 list_del(&nm->list); 554 kfree(nm); 555 } 556 } 557 mutex_unlock(&fn_mutex); 558 559 list_del(&ft->list); 560 ft->attached = false; 561 LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name); 562 563 out_attach: 564 mutex_unlock(&ft_mutex); 565 return rc; 566 567 } 568 EXPORT_SYMBOL(fcoe_transport_detach); 569 570 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp) 571 { 572 int i, j; 573 struct fcoe_transport *ft = NULL; 574 575 i = j = sprintf(buffer, "Attached FCoE transports:"); 576 mutex_lock(&ft_mutex); 577 list_for_each_entry(ft, &fcoe_transports, list) { 578 if (i >= PAGE_SIZE - IFNAMSIZ) 579 break; 580 i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name); 581 } 582 mutex_unlock(&ft_mutex); 583 if (i == j) 584 i += snprintf(&buffer[i], IFNAMSIZ, "none"); 585 return i; 586 } 587 588 static int __init fcoe_transport_init(void) 589 { 590 register_netdevice_notifier(&libfcoe_notifier); 591 return 0; 592 } 593 594 static int fcoe_transport_exit(void) 595 { 596 struct fcoe_transport *ft; 597 598 unregister_netdevice_notifier(&libfcoe_notifier); 599 mutex_lock(&ft_mutex); 600 list_for_each_entry(ft, &fcoe_transports, list) 601 printk(KERN_ERR "FCoE transport %s is still attached!\n", 602 ft->name); 603 mutex_unlock(&ft_mutex); 604 return 0; 605 } 606 607 608 static int fcoe_add_netdev_mapping(struct net_device *netdev, 609 struct fcoe_transport *ft) 610 { 611 struct fcoe_netdev_mapping *nm; 612 613 nm = kmalloc(sizeof(*nm), GFP_KERNEL); 614 if (!nm) { 615 printk(KERN_ERR "Unable to allocate netdev_mapping"); 616 return -ENOMEM; 617 } 618 619 nm->netdev = netdev; 620 nm->ft = ft; 621 622 mutex_lock(&fn_mutex); 623 list_add(&nm->list, &fcoe_netdevs); 624 mutex_unlock(&fn_mutex); 625 return 0; 626 } 627 628 629 static void fcoe_del_netdev_mapping(struct net_device *netdev) 630 { 631 struct fcoe_netdev_mapping *nm = NULL, *tmp; 632 633 mutex_lock(&fn_mutex); 634 list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) { 635 if (nm->netdev == netdev) { 636 list_del(&nm->list); 637 kfree(nm); 638 mutex_unlock(&fn_mutex); 639 return; 640 } 641 } 642 mutex_unlock(&fn_mutex); 643 } 644 645 646 /** 647 * fcoe_netdev_map_lookup - find the fcoe transport that matches the netdev on which 648 * it was created 649 * 650 * Returns : ptr to the fcoe transport that supports this netdev or NULL 651 * if not found. 652 * 653 * The ft_mutex should be held when this is called 654 */ 655 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *netdev) 656 { 657 struct fcoe_transport *ft = NULL; 658 struct fcoe_netdev_mapping *nm; 659 660 mutex_lock(&fn_mutex); 661 list_for_each_entry(nm, &fcoe_netdevs, list) { 662 if (netdev == nm->netdev) { 663 ft = nm->ft; 664 mutex_unlock(&fn_mutex); 665 return ft; 666 } 667 } 668 669 mutex_unlock(&fn_mutex); 670 return NULL; 671 } 672 673 /** 674 * fcoe_if_to_netdev() - Parse a name buffer to get a net device 675 * @buffer: The name of the net device 676 * 677 * Returns: NULL or a ptr to net_device 678 */ 679 static struct net_device *fcoe_if_to_netdev(const char *buffer) 680 { 681 char *cp; 682 char ifname[IFNAMSIZ + 2]; 683 684 if (buffer) { 685 strlcpy(ifname, buffer, IFNAMSIZ); 686 cp = ifname + strlen(ifname); 687 while (--cp >= ifname && *cp == '\n') 688 *cp = '\0'; 689 return dev_get_by_name(&init_net, ifname); 690 } 691 return NULL; 692 } 693 694 /** 695 * libfcoe_device_notification() - Handler for net device events 696 * @notifier: The context of the notification 697 * @event: The type of event 698 * @ptr: The net device that the event was on 699 * 700 * This function is called by the Ethernet driver in case of link change event. 701 * 702 * Returns: 0 for success 703 */ 704 static int libfcoe_device_notification(struct notifier_block *notifier, 705 ulong event, void *ptr) 706 { 707 struct net_device *netdev = ptr; 708 709 switch (event) { 710 case NETDEV_UNREGISTER: 711 LIBFCOE_TRANSPORT_DBG("NETDEV_UNREGISTER %s\n", 712 netdev->name); 713 fcoe_del_netdev_mapping(netdev); 714 break; 715 } 716 return NOTIFY_OK; 717 } 718 719 ssize_t fcoe_ctlr_create_store(struct bus_type *bus, 720 const char *buf, size_t count) 721 { 722 struct net_device *netdev = NULL; 723 struct fcoe_transport *ft = NULL; 724 struct fcoe_ctlr_device *ctlr_dev = NULL; 725 int rc = 0; 726 int err; 727 728 mutex_lock(&ft_mutex); 729 730 netdev = fcoe_if_to_netdev(buf); 731 if (!netdev) { 732 LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf); 733 rc = -ENODEV; 734 goto out_nodev; 735 } 736 737 ft = fcoe_netdev_map_lookup(netdev); 738 if (ft) { 739 LIBFCOE_TRANSPORT_DBG("transport %s already has existing " 740 "FCoE instance on %s.\n", 741 ft->name, netdev->name); 742 rc = -EEXIST; 743 goto out_putdev; 744 } 745 746 ft = fcoe_transport_lookup(netdev); 747 if (!ft) { 748 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 749 netdev->name); 750 rc = -ENODEV; 751 goto out_putdev; 752 } 753 754 /* pass to transport create */ 755 err = ft->alloc ? ft->alloc(netdev) : -ENODEV; 756 if (err) { 757 fcoe_del_netdev_mapping(netdev); 758 rc = -ENOMEM; 759 goto out_putdev; 760 } 761 762 err = fcoe_add_netdev_mapping(netdev, ft); 763 if (err) { 764 LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping " 765 "for FCoE transport %s for %s.\n", 766 ft->name, netdev->name); 767 rc = -ENODEV; 768 goto out_putdev; 769 } 770 771 LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n", 772 ft->name, (ctlr_dev) ? "succeeded" : "failed", 773 netdev->name); 774 775 out_putdev: 776 dev_put(netdev); 777 out_nodev: 778 mutex_unlock(&ft_mutex); 779 if (rc) 780 return rc; 781 return count; 782 } 783 784 ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus, 785 const char *buf, size_t count) 786 { 787 int rc = -ENODEV; 788 struct net_device *netdev = NULL; 789 struct fcoe_transport *ft = NULL; 790 791 mutex_lock(&ft_mutex); 792 793 netdev = fcoe_if_to_netdev(buf); 794 if (!netdev) { 795 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf); 796 goto out_nodev; 797 } 798 799 ft = fcoe_netdev_map_lookup(netdev); 800 if (!ft) { 801 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 802 netdev->name); 803 goto out_putdev; 804 } 805 806 /* pass to transport destroy */ 807 rc = ft->destroy(netdev); 808 if (rc) 809 goto out_putdev; 810 811 fcoe_del_netdev_mapping(netdev); 812 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n", 813 ft->name, (rc) ? "failed" : "succeeded", 814 netdev->name); 815 rc = count; /* required for successful return */ 816 out_putdev: 817 dev_put(netdev); 818 out_nodev: 819 mutex_unlock(&ft_mutex); 820 return rc; 821 } 822 EXPORT_SYMBOL(fcoe_ctlr_destroy_store); 823 824 /** 825 * fcoe_transport_create() - Create a fcoe interface 826 * @buffer: The name of the Ethernet interface to create on 827 * @kp: The associated kernel param 828 * 829 * Called from sysfs. This holds the ft_mutex while calling the 830 * registered fcoe transport's create function. 831 * 832 * Returns: 0 for success 833 */ 834 static int fcoe_transport_create(const char *buffer, struct kernel_param *kp) 835 { 836 int rc = -ENODEV; 837 struct net_device *netdev = NULL; 838 struct fcoe_transport *ft = NULL; 839 enum fip_state fip_mode = (enum fip_state)(long)kp->arg; 840 841 mutex_lock(&ft_mutex); 842 843 netdev = fcoe_if_to_netdev(buffer); 844 if (!netdev) { 845 LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buffer); 846 goto out_nodev; 847 } 848 849 ft = fcoe_netdev_map_lookup(netdev); 850 if (ft) { 851 LIBFCOE_TRANSPORT_DBG("transport %s already has existing " 852 "FCoE instance on %s.\n", 853 ft->name, netdev->name); 854 rc = -EEXIST; 855 goto out_putdev; 856 } 857 858 ft = fcoe_transport_lookup(netdev); 859 if (!ft) { 860 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 861 netdev->name); 862 goto out_putdev; 863 } 864 865 rc = fcoe_add_netdev_mapping(netdev, ft); 866 if (rc) { 867 LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping " 868 "for FCoE transport %s for %s.\n", 869 ft->name, netdev->name); 870 goto out_putdev; 871 } 872 873 /* pass to transport create */ 874 rc = ft->create ? ft->create(netdev, fip_mode) : -ENODEV; 875 if (rc) 876 fcoe_del_netdev_mapping(netdev); 877 878 LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n", 879 ft->name, (rc) ? "failed" : "succeeded", 880 netdev->name); 881 882 out_putdev: 883 dev_put(netdev); 884 out_nodev: 885 mutex_unlock(&ft_mutex); 886 return rc; 887 } 888 889 /** 890 * fcoe_transport_destroy() - Destroy a FCoE interface 891 * @buffer: The name of the Ethernet interface to be destroyed 892 * @kp: The associated kernel parameter 893 * 894 * Called from sysfs. This holds the ft_mutex while calling the 895 * registered fcoe transport's destroy function. 896 * 897 * Returns: 0 for success 898 */ 899 static int fcoe_transport_destroy(const char *buffer, struct kernel_param *kp) 900 { 901 int rc = -ENODEV; 902 struct net_device *netdev = NULL; 903 struct fcoe_transport *ft = NULL; 904 905 mutex_lock(&ft_mutex); 906 907 netdev = fcoe_if_to_netdev(buffer); 908 if (!netdev) { 909 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buffer); 910 goto out_nodev; 911 } 912 913 ft = fcoe_netdev_map_lookup(netdev); 914 if (!ft) { 915 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 916 netdev->name); 917 goto out_putdev; 918 } 919 920 /* pass to transport destroy */ 921 rc = ft->destroy ? ft->destroy(netdev) : -ENODEV; 922 fcoe_del_netdev_mapping(netdev); 923 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n", 924 ft->name, (rc) ? "failed" : "succeeded", 925 netdev->name); 926 927 out_putdev: 928 dev_put(netdev); 929 out_nodev: 930 mutex_unlock(&ft_mutex); 931 return rc; 932 } 933 934 /** 935 * fcoe_transport_disable() - Disables a FCoE interface 936 * @buffer: The name of the Ethernet interface to be disabled 937 * @kp: The associated kernel parameter 938 * 939 * Called from sysfs. 940 * 941 * Returns: 0 for success 942 */ 943 static int fcoe_transport_disable(const char *buffer, struct kernel_param *kp) 944 { 945 int rc = -ENODEV; 946 struct net_device *netdev = NULL; 947 struct fcoe_transport *ft = NULL; 948 949 mutex_lock(&ft_mutex); 950 951 netdev = fcoe_if_to_netdev(buffer); 952 if (!netdev) 953 goto out_nodev; 954 955 ft = fcoe_netdev_map_lookup(netdev); 956 if (!ft) 957 goto out_putdev; 958 959 rc = ft->disable ? ft->disable(netdev) : -ENODEV; 960 961 out_putdev: 962 dev_put(netdev); 963 out_nodev: 964 mutex_unlock(&ft_mutex); 965 return rc; 966 } 967 968 /** 969 * fcoe_transport_enable() - Enables a FCoE interface 970 * @buffer: The name of the Ethernet interface to be enabled 971 * @kp: The associated kernel parameter 972 * 973 * Called from sysfs. 974 * 975 * Returns: 0 for success 976 */ 977 static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp) 978 { 979 int rc = -ENODEV; 980 struct net_device *netdev = NULL; 981 struct fcoe_transport *ft = NULL; 982 983 mutex_lock(&ft_mutex); 984 985 netdev = fcoe_if_to_netdev(buffer); 986 if (!netdev) 987 goto out_nodev; 988 989 ft = fcoe_netdev_map_lookup(netdev); 990 if (!ft) 991 goto out_putdev; 992 993 rc = ft->enable ? ft->enable(netdev) : -ENODEV; 994 995 out_putdev: 996 dev_put(netdev); 997 out_nodev: 998 mutex_unlock(&ft_mutex); 999 return rc; 1000 } 1001 1002 /** 1003 * libfcoe_init() - Initialization routine for libfcoe.ko 1004 */ 1005 static int __init libfcoe_init(void) 1006 { 1007 int rc = 0; 1008 1009 rc = fcoe_transport_init(); 1010 if (rc) 1011 return rc; 1012 1013 rc = fcoe_sysfs_setup(); 1014 if (rc) 1015 fcoe_transport_exit(); 1016 1017 return rc; 1018 } 1019 module_init(libfcoe_init); 1020 1021 /** 1022 * libfcoe_exit() - Tear down libfcoe.ko 1023 */ 1024 static void __exit libfcoe_exit(void) 1025 { 1026 fcoe_sysfs_teardown(); 1027 fcoe_transport_exit(); 1028 } 1029 module_exit(libfcoe_exit); 1030