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 += READ_ONCE(stats->LinkFailureCount); 187 vlfc += READ_ONCE(stats->VLinkFailureCount); 188 mdac += READ_ONCE(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 strscpy(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(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(const char *buf, size_t count) 811 { 812 int rc = -ENODEV; 813 struct net_device *netdev = NULL; 814 struct fcoe_transport *ft = NULL; 815 816 mutex_lock(&ft_mutex); 817 818 netdev = fcoe_if_to_netdev(buf); 819 if (!netdev) { 820 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf); 821 goto out_nodev; 822 } 823 824 ft = fcoe_netdev_map_lookup(netdev); 825 if (!ft) { 826 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 827 netdev->name); 828 goto out_putdev; 829 } 830 831 /* pass to transport destroy */ 832 rc = ft->destroy(netdev); 833 if (rc) 834 goto out_putdev; 835 836 fcoe_del_netdev_mapping(netdev); 837 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n", 838 ft->name, (rc) ? "failed" : "succeeded", 839 netdev->name); 840 rc = count; /* required for successful return */ 841 out_putdev: 842 dev_put(netdev); 843 out_nodev: 844 mutex_unlock(&ft_mutex); 845 return rc; 846 } 847 848 /** 849 * fcoe_transport_create() - Create a fcoe interface 850 * @buffer: The name of the Ethernet interface to create on 851 * @kp: The associated kernel param 852 * 853 * Called from sysfs. This holds the ft_mutex while calling the 854 * registered fcoe transport's create function. 855 * 856 * Returns: 0 for success 857 */ 858 static int fcoe_transport_create(const char *buffer, 859 const struct kernel_param *kp) 860 { 861 int rc = -ENODEV; 862 struct net_device *netdev = NULL; 863 struct fcoe_transport *ft = NULL; 864 enum fip_mode fip_mode = (enum fip_mode)(uintptr_t)kp->arg; 865 866 mutex_lock(&ft_mutex); 867 868 netdev = fcoe_if_to_netdev(buffer); 869 if (!netdev) { 870 LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buffer); 871 goto out_nodev; 872 } 873 874 ft = fcoe_netdev_map_lookup(netdev); 875 if (ft) { 876 LIBFCOE_TRANSPORT_DBG("transport %s already has existing " 877 "FCoE instance on %s.\n", 878 ft->name, netdev->name); 879 rc = -EEXIST; 880 goto out_putdev; 881 } 882 883 ft = fcoe_transport_lookup(netdev); 884 if (!ft) { 885 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 886 netdev->name); 887 goto out_putdev; 888 } 889 890 rc = fcoe_add_netdev_mapping(netdev, ft); 891 if (rc) { 892 LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping " 893 "for FCoE transport %s for %s.\n", 894 ft->name, netdev->name); 895 goto out_putdev; 896 } 897 898 /* pass to transport create */ 899 rc = ft->create ? ft->create(netdev, fip_mode) : -ENODEV; 900 if (rc) 901 fcoe_del_netdev_mapping(netdev); 902 903 LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n", 904 ft->name, (rc) ? "failed" : "succeeded", 905 netdev->name); 906 907 out_putdev: 908 dev_put(netdev); 909 out_nodev: 910 mutex_unlock(&ft_mutex); 911 return rc; 912 } 913 914 /** 915 * fcoe_transport_destroy() - Destroy a FCoE interface 916 * @buffer: The name of the Ethernet interface to be destroyed 917 * @kp: The associated kernel parameter 918 * 919 * Called from sysfs. This holds the ft_mutex while calling the 920 * registered fcoe transport's destroy function. 921 * 922 * Returns: 0 for success 923 */ 924 static int fcoe_transport_destroy(const char *buffer, 925 const struct kernel_param *kp) 926 { 927 int rc = -ENODEV; 928 struct net_device *netdev = NULL; 929 struct fcoe_transport *ft = NULL; 930 931 mutex_lock(&ft_mutex); 932 933 netdev = fcoe_if_to_netdev(buffer); 934 if (!netdev) { 935 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buffer); 936 goto out_nodev; 937 } 938 939 ft = fcoe_netdev_map_lookup(netdev); 940 if (!ft) { 941 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n", 942 netdev->name); 943 goto out_putdev; 944 } 945 946 /* pass to transport destroy */ 947 rc = ft->destroy ? ft->destroy(netdev) : -ENODEV; 948 fcoe_del_netdev_mapping(netdev); 949 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n", 950 ft->name, (rc) ? "failed" : "succeeded", 951 netdev->name); 952 953 out_putdev: 954 dev_put(netdev); 955 out_nodev: 956 mutex_unlock(&ft_mutex); 957 return rc; 958 } 959 960 /** 961 * fcoe_transport_disable() - Disables a FCoE interface 962 * @buffer: The name of the Ethernet interface to be disabled 963 * @kp: The associated kernel parameter 964 * 965 * Called from sysfs. 966 * 967 * Returns: 0 for success 968 */ 969 static int fcoe_transport_disable(const char *buffer, 970 const struct kernel_param *kp) 971 { 972 int rc = -ENODEV; 973 struct net_device *netdev = NULL; 974 struct fcoe_transport *ft = NULL; 975 976 mutex_lock(&ft_mutex); 977 978 netdev = fcoe_if_to_netdev(buffer); 979 if (!netdev) 980 goto out_nodev; 981 982 ft = fcoe_netdev_map_lookup(netdev); 983 if (!ft) 984 goto out_putdev; 985 986 rc = ft->disable ? ft->disable(netdev) : -ENODEV; 987 988 out_putdev: 989 dev_put(netdev); 990 out_nodev: 991 mutex_unlock(&ft_mutex); 992 return rc; 993 } 994 995 /** 996 * fcoe_transport_enable() - Enables a FCoE interface 997 * @buffer: The name of the Ethernet interface to be enabled 998 * @kp: The associated kernel parameter 999 * 1000 * Called from sysfs. 1001 * 1002 * Returns: 0 for success 1003 */ 1004 static int fcoe_transport_enable(const char *buffer, 1005 const struct kernel_param *kp) 1006 { 1007 int rc = -ENODEV; 1008 struct net_device *netdev = NULL; 1009 struct fcoe_transport *ft = NULL; 1010 1011 mutex_lock(&ft_mutex); 1012 1013 netdev = fcoe_if_to_netdev(buffer); 1014 if (!netdev) 1015 goto out_nodev; 1016 1017 ft = fcoe_netdev_map_lookup(netdev); 1018 if (!ft) 1019 goto out_putdev; 1020 1021 rc = ft->enable ? ft->enable(netdev) : -ENODEV; 1022 1023 out_putdev: 1024 dev_put(netdev); 1025 out_nodev: 1026 mutex_unlock(&ft_mutex); 1027 return rc; 1028 } 1029 1030 /** 1031 * libfcoe_init() - Initialization routine for libfcoe.ko 1032 */ 1033 static int __init libfcoe_init(void) 1034 { 1035 int rc = 0; 1036 1037 rc = fcoe_transport_init(); 1038 if (rc) 1039 return rc; 1040 1041 rc = fcoe_sysfs_setup(); 1042 if (rc) 1043 fcoe_transport_exit(); 1044 1045 return rc; 1046 } 1047 module_init(libfcoe_init); 1048 1049 /** 1050 * libfcoe_exit() - Tear down libfcoe.ko 1051 */ 1052 static void __exit libfcoe_exit(void) 1053 { 1054 fcoe_sysfs_teardown(); 1055 fcoe_transport_exit(); 1056 } 1057 module_exit(libfcoe_exit); 1058