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 20MODULE_AUTHOR("Open-FCoE.org"); 21MODULE_DESCRIPTION("FIP discovery protocol and FCoE transport for FCoE HBAs"); 22MODULE_LICENSE("GPL v2"); 23 24static int fcoe_transport_create(const char *, const struct kernel_param *); 25static int fcoe_transport_destroy(const char *, const struct kernel_param *); 26static int fcoe_transport_show(char *buffer, const struct kernel_param *kp); 27static struct fcoe_transport *fcoe_transport_lookup(struct net_device *device); 28static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *device); 29static int fcoe_transport_enable(const char *, const struct kernel_param *); 30static int fcoe_transport_disable(const char *, const struct kernel_param *); 31static int libfcoe_device_notification(struct notifier_block *notifier, 32 ulong event, void *ptr); 33 34static LIST_HEAD(fcoe_transports); 35static DEFINE_MUTEX(ft_mutex); 36static LIST_HEAD(fcoe_netdevs); 37static DEFINE_MUTEX(fn_mutex); 38 39unsigned int libfcoe_debug_logging; 40module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); 41MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); 42 43module_param_call(show, NULL, fcoe_transport_show, NULL, S_IRUSR); 44__MODULE_PARM_TYPE(show, "string"); 45MODULE_PARM_DESC(show, " Show attached FCoE transports"); 46 47module_param_call(create, fcoe_transport_create, NULL, 48 (void *)FIP_MODE_FABRIC, S_IWUSR); 49__MODULE_PARM_TYPE(create, "string"); 50MODULE_PARM_DESC(create, " Creates fcoe instance on an ethernet interface"); 51 52module_param_call(create_vn2vn, fcoe_transport_create, NULL, 53 (void *)FIP_MODE_VN2VN, S_IWUSR); 54__MODULE_PARM_TYPE(create_vn2vn, "string"); 55MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance " 56 "on an Ethernet interface"); 57 58module_param_call(destroy, fcoe_transport_destroy, NULL, NULL, S_IWUSR); 59__MODULE_PARM_TYPE(destroy, "string"); 60MODULE_PARM_DESC(destroy, " Destroys fcoe instance on an ethernet interface"); 61 62module_param_call(enable, fcoe_transport_enable, NULL, NULL, S_IWUSR); 63__MODULE_PARM_TYPE(enable, "string"); 64MODULE_PARM_DESC(enable, " Enables fcoe on an ethernet interface."); 65 66module_param_call(disable, fcoe_transport_disable, NULL, NULL, S_IWUSR); 67__MODULE_PARM_TYPE(disable, "string"); 68MODULE_PARM_DESC(disable, " Disables fcoe on an ethernet interface."); 69 70/* notification function for packets from net device */ 71static struct notifier_block libfcoe_notifier = { 72 .notifier_call = libfcoe_device_notification, 73}; 74 75static 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 98static 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 */ 117int 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} 158EXPORT_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 */ 169void __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} 196EXPORT_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 */ 203void 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} 210EXPORT_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 */ 218void 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} 227EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb); 228 229void 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} 238EXPORT_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 */ 249int 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 } 277out: 278 mutex_unlock(&n_port->lp_mutex); 279 return rc; 280} 281EXPORT_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 */ 291int 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} 299EXPORT_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 */ 309u32 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} 336EXPORT_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 */ 347int 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} 361EXPORT_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 */ 368void 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} 381EXPORT_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 */ 397void 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; 435out: 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} 440EXPORT_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 */ 448void 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} 454EXPORT_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 */ 470int 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} 501EXPORT_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 */ 512static 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 */ 528int 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 549out_attach: 550 mutex_unlock(&ft_mutex); 551 return rc; 552} 553EXPORT_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 */ 561int 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 591out_attach: 592 mutex_unlock(&ft_mutex); 593 return rc; 594 595} 596EXPORT_SYMBOL(fcoe_transport_detach); 597 598static 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 616static int __init fcoe_transport_init(void) 617{ 618 register_netdevice_notifier(&libfcoe_notifier); 619 return 0; 620} 621 622static 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 636static 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 657static 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 */ 684static 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 */ 708static 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 */ 733static 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 748ssize_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 801out_putdev: 802 dev_put(netdev); 803out_nodev: 804 mutex_unlock(&ft_mutex); 805 if (rc) 806 return rc; 807 return count; 808} 809 810ssize_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 */ 841out_putdev: 842 dev_put(netdev); 843out_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 */ 858static 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 907out_putdev: 908 dev_put(netdev); 909out_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 */ 924static 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 953out_putdev: 954 dev_put(netdev); 955out_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 */ 969static 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 988out_putdev: 989 dev_put(netdev); 990out_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 */ 1004static 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 1023out_putdev: 1024 dev_put(netdev); 1025out_nodev: 1026 mutex_unlock(&ft_mutex); 1027 return rc; 1028} 1029 1030/** 1031 * libfcoe_init() - Initialization routine for libfcoe.ko 1032 */ 1033static 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} 1047module_init(libfcoe_init); 1048 1049/** 1050 * libfcoe_exit() - Tear down libfcoe.ko 1051 */ 1052static void __exit libfcoe_exit(void) 1053{ 1054 fcoe_sysfs_teardown(); 1055 fcoe_transport_exit(); 1056} 1057module_exit(libfcoe_exit); 1058