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