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