diff options
| -rw-r--r-- | drivers/staging/octeon/ethernet.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index b8479517dce2..492c5029992d 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c | |||
| @@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n" | |||
| 111 | "\tallows packets to be sent without lock contention in the packet\n" | 111 | "\tallows packets to be sent without lock contention in the packet\n" |
| 112 | "\tscheduler resulting in some cases in improved throughput.\n"); | 112 | "\tscheduler resulting in some cases in improved throughput.\n"); |
| 113 | 113 | ||
| 114 | |||
| 115 | /* | ||
| 116 | * The offset from mac_addr_base that should be used for the next port | ||
| 117 | * that is configured. By convention, if any mgmt ports exist on the | ||
| 118 | * chip, they get the first mac addresses, The ports controlled by | ||
| 119 | * this driver are numbered sequencially following any mgmt addresses | ||
| 120 | * that may exist. | ||
| 121 | */ | ||
| 122 | static unsigned int cvm_oct_mac_addr_offset; | ||
| 123 | |||
| 114 | /** | 124 | /** |
| 115 | * Periodic timer to check auto negotiation | 125 | * Periodic timer to check auto negotiation |
| 116 | */ | 126 | */ |
| @@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
| 474 | */ | 484 | */ |
| 475 | int cvm_oct_common_init(struct net_device *dev) | 485 | int cvm_oct_common_init(struct net_device *dev) |
| 476 | { | 486 | { |
| 477 | static int count; | ||
| 478 | char mac[8] = { 0x00, 0x00, | ||
| 479 | octeon_bootinfo->mac_addr_base[0], | ||
| 480 | octeon_bootinfo->mac_addr_base[1], | ||
| 481 | octeon_bootinfo->mac_addr_base[2], | ||
| 482 | octeon_bootinfo->mac_addr_base[3], | ||
| 483 | octeon_bootinfo->mac_addr_base[4], | ||
| 484 | octeon_bootinfo->mac_addr_base[5] + count | ||
| 485 | }; | ||
| 486 | struct octeon_ethernet *priv = netdev_priv(dev); | 487 | struct octeon_ethernet *priv = netdev_priv(dev); |
| 488 | struct sockaddr sa; | ||
| 489 | u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) | | ||
| 490 | ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) | | ||
| 491 | ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) | | ||
| 492 | ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) | | ||
| 493 | ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) | | ||
| 494 | (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff); | ||
| 495 | |||
| 496 | mac += cvm_oct_mac_addr_offset; | ||
| 497 | sa.sa_data[0] = (mac >> 40) & 0xff; | ||
| 498 | sa.sa_data[1] = (mac >> 32) & 0xff; | ||
| 499 | sa.sa_data[2] = (mac >> 24) & 0xff; | ||
| 500 | sa.sa_data[3] = (mac >> 16) & 0xff; | ||
| 501 | sa.sa_data[4] = (mac >> 8) & 0xff; | ||
| 502 | sa.sa_data[5] = mac & 0xff; | ||
| 503 | |||
| 504 | if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count) | ||
| 505 | printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:" | ||
| 506 | " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | ||
| 507 | sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff, | ||
| 508 | sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff, | ||
| 509 | sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff); | ||
| 510 | cvm_oct_mac_addr_offset++; | ||
| 487 | 511 | ||
| 488 | /* | 512 | /* |
| 489 | * Force the interface to use the POW send if always_use_pow | 513 | * Force the interface to use the POW send if always_use_pow |
| @@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev) | |||
| 496 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) | 520 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) |
| 497 | dev->features |= NETIF_F_IP_CSUM; | 521 | dev->features |= NETIF_F_IP_CSUM; |
| 498 | 522 | ||
| 499 | count++; | ||
| 500 | |||
| 501 | /* We do our own locking, Linux doesn't need to */ | 523 | /* We do our own locking, Linux doesn't need to */ |
| 502 | dev->features |= NETIF_F_LLTX; | 524 | dev->features |= NETIF_F_LLTX; |
| 503 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); | 525 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); |
| 504 | 526 | ||
| 505 | cvm_oct_mdio_setup_device(dev); | 527 | cvm_oct_mdio_setup_device(dev); |
| 506 | dev->netdev_ops->ndo_set_mac_address(dev, mac); | 528 | dev->netdev_ops->ndo_set_mac_address(dev, &sa); |
| 507 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); | 529 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); |
| 508 | 530 | ||
| 509 | /* | 531 | /* |
| @@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void) | |||
| 620 | 642 | ||
| 621 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); | 643 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); |
| 622 | 644 | ||
| 645 | if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
| 646 | cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */ | ||
| 647 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
| 648 | cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */ | ||
| 649 | else | ||
| 650 | cvm_oct_mac_addr_offset = 0; | ||
| 651 | |||
| 623 | cvm_oct_proc_initialize(); | 652 | cvm_oct_proc_initialize(); |
| 624 | cvm_oct_rx_initialize(); | 653 | cvm_oct_rx_initialize(); |
| 625 | cvm_oct_configure_common_hw(); | 654 | cvm_oct_configure_common_hw(); |
