aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-05-05 15:05:08 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-06 18:33:36 -0400
commit3d0a3cc9d72047e4baa76021c897f64fc84cc543 (patch)
tree121b07aa7e131380681659734d780042b9c776ca
parent5cf4d323f8864dab818d500ec74f2fcb9ad5bf89 (diff)
netxen: fix bonding support
o Pause traffic during mac addr change. o Enable setting mac address for NX3031. Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/netxen/netxen_nic.h6
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c28
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h10
-rw-r--r--drivers/net/netxen/netxen_nic_init.c7
-rw-r--r--drivers/net/netxen/netxen_nic_main.c45
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c154
6 files changed, 82 insertions, 168 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index d368e24c023..9350c8663fd 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1264,9 +1264,10 @@ struct netxen_adapter {
1264 1264
1265 int (*enable_phy_interrupts) (struct netxen_adapter *); 1265 int (*enable_phy_interrupts) (struct netxen_adapter *);
1266 int (*disable_phy_interrupts) (struct netxen_adapter *); 1266 int (*disable_phy_interrupts) (struct netxen_adapter *);
1267 int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); 1267 int (*macaddr_set) (struct netxen_adapter *, u8 *);
1268 int (*set_mtu) (struct netxen_adapter *, int); 1268 int (*set_mtu) (struct netxen_adapter *, int);
1269 int (*set_promisc) (struct netxen_adapter *, u32); 1269 int (*set_promisc) (struct netxen_adapter *, u32);
1270 void (*set_multi) (struct net_device *);
1270 int (*phy_read) (struct netxen_adapter *, long reg, u32 *); 1271 int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
1271 int (*phy_write) (struct netxen_adapter *, long reg, u32 val); 1272 int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
1272 int (*init_port) (struct netxen_adapter *, int); 1273 int (*init_port) (struct netxen_adapter *, int);
@@ -1331,6 +1332,9 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
1331int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); 1332int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
1332int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); 1333int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
1333 1334
1335int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
1336int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
1337
1334#define NXRD32(adapter, off) \ 1338#define NXRD32(adapter, off) \
1335 (adapter->hw_read_wx(adapter, off)) 1339 (adapter->hw_read_wx(adapter, off))
1336#define NXWR32(adapter, off, val) \ 1340#define NXWR32(adapter, off, val) \
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index be643ea3523..86c9e78ec39 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -321,27 +321,6 @@ static unsigned crb_hub_agt[64] =
321 321
322#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ 322#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
323 323
324int netxen_nic_set_mac(struct net_device *netdev, void *p)
325{
326 struct netxen_adapter *adapter = netdev_priv(netdev);
327 struct sockaddr *addr = p;
328
329 if (netif_running(netdev))
330 return -EBUSY;
331
332 if (!is_valid_ether_addr(addr->sa_data))
333 return -EADDRNOTAVAIL;
334
335 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
336
337 /* For P3, MAC addr is not set in NIU */
338 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
339 if (adapter->macaddr_set)
340 adapter->macaddr_set(adapter, addr->sa_data);
341
342 return 0;
343}
344
345#define NETXEN_UNICAST_ADDR(port, index) \ 324#define NETXEN_UNICAST_ADDR(port, index) \
346 (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8)) 325 (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
347#define NETXEN_MCAST_ADDR(port, index) \ 326#define NETXEN_MCAST_ADDR(port, index) \
@@ -643,6 +622,13 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
643 } 622 }
644} 623}
645 624
625int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
626{
627 /* assuming caller has already copied new addr to netdev */
628 netxen_p3_nic_set_multi(adapter->netdev);
629 return 0;
630}
631
646#define NETXEN_CONFIG_INTR_COALESCE 3 632#define NETXEN_CONFIG_INTR_COALESCE 3
647 633
648/* 634/*
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index f20c96591a8..d4e83333978 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -42,8 +42,6 @@ struct netxen_adapter;
42 42
43void netxen_nic_set_link_parameters(struct netxen_adapter *adapter); 43void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
44 44
45typedef u8 netxen_ethernet_macaddr_t[6];
46
47/* Nibble or Byte mode for phy interface (GbE mode only) */ 45/* Nibble or Byte mode for phy interface (GbE mode only) */
48 46
49#define _netxen_crb_get_bit(var, bit) ((var >> bit) & 0x1) 47#define _netxen_crb_get_bit(var, bit) ((var >> bit) & 0x1)
@@ -395,14 +393,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
395int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 393int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
396 u32 mode); 394 u32 mode);
397 395
398/* set the MAC address for a given MAC */
399int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
400 netxen_ethernet_macaddr_t addr);
401
402/* XG version */
403int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
404 netxen_ethernet_macaddr_t addr);
405
406/* Generic enable for GbE ports. Will detect the speed of the link. */ 396/* Generic enable for GbE ports. Will detect the speed of the link. */
407int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port); 397int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
408 398
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index de9ebbd841b..4a51c31330d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -319,13 +319,15 @@ err_out:
319 319
320void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) 320void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
321{ 321{
322 adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
323 adapter->set_multi = netxen_p2_nic_set_multi;
324
322 switch (adapter->ahw.port_type) { 325 switch (adapter->ahw.port_type) {
323 case NETXEN_NIC_GBE: 326 case NETXEN_NIC_GBE:
324 adapter->enable_phy_interrupts = 327 adapter->enable_phy_interrupts =
325 netxen_niu_gbe_enable_phy_interrupts; 328 netxen_niu_gbe_enable_phy_interrupts;
326 adapter->disable_phy_interrupts = 329 adapter->disable_phy_interrupts =
327 netxen_niu_gbe_disable_phy_interrupts; 330 netxen_niu_gbe_disable_phy_interrupts;
328 adapter->macaddr_set = netxen_niu_macaddr_set;
329 adapter->set_mtu = netxen_nic_set_mtu_gb; 331 adapter->set_mtu = netxen_nic_set_mtu_gb;
330 adapter->set_promisc = netxen_niu_set_promiscuous_mode; 332 adapter->set_promisc = netxen_niu_set_promiscuous_mode;
331 adapter->phy_read = netxen_niu_gbe_phy_read; 333 adapter->phy_read = netxen_niu_gbe_phy_read;
@@ -339,7 +341,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
339 netxen_niu_xgbe_enable_phy_interrupts; 341 netxen_niu_xgbe_enable_phy_interrupts;
340 adapter->disable_phy_interrupts = 342 adapter->disable_phy_interrupts =
341 netxen_niu_xgbe_disable_phy_interrupts; 343 netxen_niu_xgbe_disable_phy_interrupts;
342 adapter->macaddr_set = netxen_niu_xg_macaddr_set;
343 adapter->set_mtu = netxen_nic_set_mtu_xgb; 344 adapter->set_mtu = netxen_nic_set_mtu_xgb;
344 adapter->init_port = netxen_niu_xg_init_port; 345 adapter->init_port = netxen_niu_xg_init_port;
345 adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode; 346 adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
@@ -353,6 +354,8 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
353 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 354 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
354 adapter->set_mtu = nx_fw_cmd_set_mtu; 355 adapter->set_mtu = nx_fw_cmd_set_mtu;
355 adapter->set_promisc = netxen_p3_nic_set_promisc; 356 adapter->set_promisc = netxen_p3_nic_set_promisc;
357 adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
358 adapter->set_multi = netxen_p3_nic_set_multi;
356 } 359 }
357} 360}
358 361
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index a5577f8b6c0..83dadfd78c3 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -442,20 +442,38 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
442 442
443 if (!is_valid_ether_addr(netdev->perm_addr)) 443 if (!is_valid_ether_addr(netdev->perm_addr))
444 dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr); 444 dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
445 else
446 adapter->macaddr_set(adapter, netdev->dev_addr);
447 445
448 return 0; 446 return 0;
449} 447}
450 448
449int netxen_nic_set_mac(struct net_device *netdev, void *p)
450{
451 struct netxen_adapter *adapter = netdev_priv(netdev);
452 struct sockaddr *addr = p;
453
454 if (!is_valid_ether_addr(addr->sa_data))
455 return -EINVAL;
456
457 if (netif_running(netdev)) {
458 netif_device_detach(netdev);
459 netxen_napi_disable(adapter);
460 }
461
462 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
463 adapter->macaddr_set(adapter, addr->sa_data);
464
465 if (netif_running(netdev)) {
466 netif_device_attach(netdev);
467 netxen_napi_enable(adapter);
468 }
469 return 0;
470}
471
451static void netxen_set_multicast_list(struct net_device *dev) 472static void netxen_set_multicast_list(struct net_device *dev)
452{ 473{
453 struct netxen_adapter *adapter = netdev_priv(dev); 474 struct netxen_adapter *adapter = netdev_priv(dev);
454 475
455 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 476 adapter->set_multi(dev);
456 netxen_p3_nic_set_multi(dev);
457 else
458 netxen_p2_nic_set_multi(dev);
459} 477}
460 478
461static const struct net_device_ops netxen_netdev_ops = { 479static const struct net_device_ops netxen_netdev_ops = {
@@ -782,16 +800,13 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
782 netxen_nic_driver_name, adapter->portnum); 800 netxen_nic_driver_name, adapter->portnum);
783 return err; 801 return err;
784 } 802 }
785 adapter->macaddr_set(adapter, netdev->dev_addr); 803 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
786 804 adapter->macaddr_set(adapter, netdev->dev_addr);
787 netxen_nic_set_link_parameters(adapter);
788 805
789 netxen_set_multicast_list(netdev); 806 adapter->set_multi(netdev);
790 if (adapter->set_mtu) 807 adapter->set_mtu(adapter, netdev->mtu);
791 adapter->set_mtu(adapter, netdev->mtu);
792 808
793 adapter->ahw.linkup = 0; 809 adapter->ahw.linkup = 0;
794 mod_timer(&adapter->watchdog_timer, jiffies);
795 810
796 netxen_napi_enable(adapter); 811 netxen_napi_enable(adapter);
797 812
@@ -800,6 +815,10 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
800 815
801 if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) 816 if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
802 netxen_linkevent_request(adapter, 1); 817 netxen_linkevent_request(adapter, 1);
818 else
819 netxen_nic_set_link_parameters(adapter);
820
821 mod_timer(&adapter->watchdog_timer, jiffies);
803 822
804 return 0; 823 return 0;
805} 824}
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 5e2698bf575..5941c79be72 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -402,76 +402,6 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
402 return 0; 402 return 0;
403} 403}
404 404
405/*
406 * Return the current station MAC address.
407 * Note that the passed-in value must already be in network byte order.
408 */
409static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
410 netxen_ethernet_macaddr_t * addr)
411{
412 u32 stationhigh;
413 u32 stationlow;
414 int phy = adapter->physical_port;
415 u8 val[8];
416
417 if (addr == NULL)
418 return -EINVAL;
419 if ((phy < 0) || (phy > 3))
420 return -EINVAL;
421
422 stationhigh = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy));
423 stationlow = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy));
424 ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
425 ((__le32 *)val)[0] = cpu_to_le32(stationlow);
426
427 memcpy(addr, val + 2, 6);
428
429 return 0;
430}
431
432/*
433 * Set the station MAC address.
434 * Note that the passed-in value must already be in network byte order.
435 */
436int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
437 netxen_ethernet_macaddr_t addr)
438{
439 u8 temp[4];
440 u32 val;
441 int phy = adapter->physical_port;
442 unsigned char mac_addr[6];
443 int i;
444
445 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
446 return 0;
447
448 for (i = 0; i < 10; i++) {
449 temp[0] = temp[1] = 0;
450 memcpy(temp + 2, addr, 2);
451 val = le32_to_cpu(*(__le32 *)temp);
452 if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), val))
453 return -EIO;
454
455 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
456 val = le32_to_cpu(*(__le32 *)temp);
457 if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), val))
458 return -2;
459
460 netxen_niu_macaddr_get(adapter,
461 (netxen_ethernet_macaddr_t *) mac_addr);
462 if (memcmp(mac_addr, addr, 6) == 0)
463 break;
464 }
465
466 if (i == 10) {
467 printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
468 netxen_nic_driver_name, adapter->netdev->name);
469 printk(KERN_ERR "MAC address set: %pM.\n", addr);
470 printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
471 }
472 return 0;
473}
474
475/* Disable a GbE interface */ 405/* Disable a GbE interface */
476int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) 406int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
477{ 407{
@@ -561,57 +491,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
561 return 0; 491 return 0;
562} 492}
563 493
564/*
565 * Set the MAC address for an XG port
566 * Note that the passed-in value must already be in network byte order.
567 */
568int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
569 netxen_ethernet_macaddr_t addr)
570{
571 int phy = adapter->physical_port;
572 u8 temp[4];
573 u32 val;
574
575 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
576 return 0;
577
578 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
579 return -EIO;
580
581 temp[0] = temp[1] = 0;
582 switch (phy) {
583 case 0:
584 memcpy(temp + 2, addr, 2);
585 val = le32_to_cpu(*(__le32 *)temp);
586 if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, val))
587 return -EIO;
588
589 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
590 val = le32_to_cpu(*(__le32 *)temp);
591 if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, val))
592 return -EIO;
593 break;
594
595 case 1:
596 memcpy(temp + 2, addr, 2);
597 val = le32_to_cpu(*(__le32 *)temp);
598 if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, val))
599 return -EIO;
600
601 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
602 val = le32_to_cpu(*(__le32 *)temp);
603 if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, val))
604 return -EIO;
605 break;
606
607 default:
608 printk(KERN_ERR "Unknown port %d\n", phy);
609 break;
610 }
611
612 return 0;
613}
614
615int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 494int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
616 u32 mode) 495 u32 mode)
617{ 496{
@@ -636,3 +515,36 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
636 515
637 return 0; 516 return 0;
638} 517}
518
519int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
520{
521 u32 mac_hi, mac_lo;
522 u32 reg_hi, reg_lo;
523
524 u8 phy = adapter->physical_port;
525 u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
526 NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
527
528 if (phy >= phy_count)
529 return -EINVAL;
530
531 mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
532 mac_hi = addr[2] | ((u32)addr[3] << 8) |
533 ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
534
535 if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
536 reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
537 reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
538 } else {
539 reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
540 reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
541 }
542
543 /* write twice to flush */
544 if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
545 return -EIO;
546 if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
547 return -EIO;
548
549 return 0;
550}