diff options
author | Amit S. Kale <amitkale@netxen.com> | 2006-11-29 12:00:10 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-02 00:16:36 -0500 |
commit | cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6 (patch) | |
tree | 2ea32fc89dab2257b359a0577ae06c6565cc99d1 /drivers/net/netxen/netxen_nic_niu.c | |
parent | edf901638144525a140c68be01be1b22e6041a6d (diff) |
[PATCH] NetXen: temp monitoring, newer firmware support, mm footprint reduction
NetXen: 1G/10G Ethernet Driver updates
- Temparature monitoring and device control
- Memory footprint reduction
- Driver changes to support newer version of firmware
Signed-off-by: Amit S. Kale <amitkale@netxen.com>
netxen_nic.h | 165 ++++++++++++++++++++++++++++++++--
netxen_nic_ethtool.c | 89 ++++++++++++------
netxen_nic_hdr.h | 71 +++++++++++++-
netxen_nic_hw.c | 206 +++++++++++++++++++++++++++++--------------
netxen_nic_hw.h | 8 +
netxen_nic_init.c | 239 +++++++++++++++++++++++++++++++++++++++++---------
netxen_nic_ioctl.h | 12 +-
netxen_nic_isr.c | 54 +++++------
netxen_nic_main.c | 121 +++++++++++++++++--------
netxen_nic_niu.c | 172 +++++++++++++++++++++++++++--------
netxen_nic_phan_reg.h | 24 ++++-
11 files changed, 891 insertions(+), 270 deletions(-)
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_niu.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 172 |
1 files changed, 133 insertions, 39 deletions
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 6e421c876fe5..7950a04532e6 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -6,12 +6,12 @@ | |||
6 | * modify it under the terms of the GNU General Public License | 6 | * modify it under the terms of the GNU General Public License |
7 | * as published by the Free Software Foundation; either version 2 | 7 | * as published by the Free Software Foundation; either version 2 |
8 | * of the License, or (at your option) any later version. | 8 | * of the License, or (at your option) any later version. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, but | 10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
@@ -32,19 +32,56 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include "netxen_nic.h" | 34 | #include "netxen_nic.h" |
35 | #include <linux/delay.h> | 35 | |
36 | #define NETXEN_GB_MAC_SOFT_RESET 0x80000000 | ||
37 | #define NETXEN_GB_MAC_RESET_PROT_BLK 0x000F0000 | ||
38 | #define NETXEN_GB_MAC_ENABLE_TX_RX 0x00000005 | ||
39 | #define NETXEN_GB_MAC_PAUSED_FRMS 0x00000020 | ||
40 | |||
41 | static long phy_lock_timeout = 100000000; | ||
42 | |||
43 | static inline int phy_lock(void) | ||
44 | { | ||
45 | int i; | ||
46 | int done = 0, timeout = 0; | ||
47 | |||
48 | while (!done) { | ||
49 | done = readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); | ||
50 | if (done == 1) | ||
51 | break; | ||
52 | if (timeout >= phy_lock_timeout) { | ||
53 | return -1; | ||
54 | } | ||
55 | timeout++; | ||
56 | if (!in_atomic()) | ||
57 | schedule(); | ||
58 | else { | ||
59 | for (i = 0; i < 20; i++) | ||
60 | cpu_relax(); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static inline int phy_unlock(void) | ||
69 | { | ||
70 | readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); | ||
71 | return 0; | ||
72 | } | ||
36 | 73 | ||
37 | /* | 74 | /* |
38 | * netxen_niu_gbe_phy_read - read a register from the GbE PHY via | 75 | * netxen_niu_gbe_phy_read - read a register from the GbE PHY via |
39 | * mii management interface. | 76 | * mii management interface. |
40 | * | 77 | * |
41 | * Note: The MII management interface goes through port 0. | 78 | * Note: The MII management interface goes through port 0. |
42 | * Individual phys are addressed as follows: | 79 | * Individual phys are addressed as follows: |
43 | * @param phy [15:8] phy id | 80 | * @param phy [15:8] phy id |
44 | * @param reg [7:0] register number | 81 | * @param reg [7:0] register number |
45 | * | 82 | * |
46 | * @returns 0 on success | 83 | * @returns 0 on success |
47 | * -1 on error | 84 | * -1 on error |
48 | * | 85 | * |
49 | */ | 86 | */ |
50 | int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, | 87 | int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, |
@@ -56,10 +93,17 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, | |||
56 | __le32 address; | 93 | __le32 address; |
57 | __le32 command; | 94 | __le32 command; |
58 | __le32 status; | 95 | __le32 status; |
59 | __le32 mii_cfg; | ||
60 | __le32 mac_cfg0; | 96 | __le32 mac_cfg0; |
61 | 97 | ||
62 | /* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */ | 98 | if (phy_lock() != 0) { |
99 | return -1; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * MII mgmt all goes through port 0 MAC interface, | ||
104 | * so it cannot be in reset | ||
105 | */ | ||
106 | |||
63 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), | 107 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
64 | &mac_cfg0, 4)) | 108 | &mac_cfg0, 4)) |
65 | return -EIO; | 109 | return -EIO; |
@@ -77,18 +121,6 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, | |||
77 | restore = 1; | 121 | restore = 1; |
78 | } | 122 | } |
79 | 123 | ||
80 | /* reset MII management interface */ | ||
81 | mii_cfg = 0; | ||
82 | netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); | ||
83 | netxen_gb_mii_mgmt_reset(mii_cfg); | ||
84 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0), | ||
85 | &mii_cfg, 4)) | ||
86 | return -EIO; | ||
87 | netxen_gb_mii_mgmt_unset(mii_cfg); | ||
88 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0), | ||
89 | &mii_cfg, 4)) | ||
90 | return -EIO; | ||
91 | |||
92 | address = 0; | 124 | address = 0; |
93 | netxen_gb_mii_mgmt_reg_addr(address, reg); | 125 | netxen_gb_mii_mgmt_reg_addr(address, reg); |
94 | netxen_gb_mii_mgmt_phy_addr(address, phy); | 126 | netxen_gb_mii_mgmt_phy_addr(address, phy); |
@@ -130,7 +162,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, | |||
130 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | 162 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
131 | &mac_cfg0, 4)) | 163 | &mac_cfg0, 4)) |
132 | return -EIO; | 164 | return -EIO; |
133 | 165 | phy_unlock(); | |
134 | return result; | 166 | return result; |
135 | } | 167 | } |
136 | 168 | ||
@@ -139,12 +171,12 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, | |||
139 | * mii management interface. | 171 | * mii management interface. |
140 | * | 172 | * |
141 | * Note: The MII management interface goes through port 0. | 173 | * Note: The MII management interface goes through port 0. |
142 | * Individual phys are addressed as follows: | 174 | * Individual phys are addressed as follows: |
143 | * @param phy [15:8] phy id | 175 | * @param phy [15:8] phy id |
144 | * @param reg [7:0] register number | 176 | * @param reg [7:0] register number |
145 | * | 177 | * |
146 | * @returns 0 on success | 178 | * @returns 0 on success |
147 | * -1 on error | 179 | * -1 on error |
148 | * | 180 | * |
149 | */ | 181 | */ |
150 | int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, | 182 | int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, |
@@ -158,7 +190,11 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, | |||
158 | __le32 status; | 190 | __le32 status; |
159 | __le32 mac_cfg0; | 191 | __le32 mac_cfg0; |
160 | 192 | ||
161 | /* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */ | 193 | /* |
194 | * MII mgmt all goes through port 0 MAC interface, so it | ||
195 | * cannot be in reset | ||
196 | */ | ||
197 | |||
162 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), | 198 | if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
163 | &mac_cfg0, 4)) | 199 | &mac_cfg0, 4)) |
164 | return -EIO; | 200 | return -EIO; |
@@ -382,14 +418,23 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
382 | } | 418 | } |
383 | 419 | ||
384 | } else { | 420 | } else { |
385 | /* We don't have link. Cable must be unconnected. */ | 421 | /* |
386 | /* Enable phy interrupts so we take action when plugged in */ | 422 | * We don't have link. Cable must be unconnected. |
423 | * Enable phy interrupts so we take action when | ||
424 | * plugged in. | ||
425 | */ | ||
426 | |||
387 | netxen_crb_writelit_adapter(adapter, | 427 | netxen_crb_writelit_adapter(adapter, |
388 | NETXEN_NIU_GB_MAC_CONFIG_0 | 428 | NETXEN_NIU_GB_MAC_CONFIG_0 |
389 | (port), 0x80000000); | 429 | (port), |
430 | NETXEN_GB_MAC_SOFT_RESET); | ||
390 | netxen_crb_writelit_adapter(adapter, | 431 | netxen_crb_writelit_adapter(adapter, |
391 | NETXEN_NIU_GB_MAC_CONFIG_0 | 432 | NETXEN_NIU_GB_MAC_CONFIG_0 |
392 | (port), 0x0000f0025); | 433 | (port), |
434 | NETXEN_GB_MAC_RESET_PROT_BLK | ||
435 | | NETXEN_GB_MAC_ENABLE_TX_RX | ||
436 | | | ||
437 | NETXEN_GB_MAC_PAUSED_FRMS); | ||
393 | if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) | 438 | if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) |
394 | printk(KERN_ERR PFX | 439 | printk(KERN_ERR PFX |
395 | "ERROR clearing PHY interrupts\n"); | 440 | "ERROR clearing PHY interrupts\n"); |
@@ -407,10 +452,34 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
407 | return result; | 452 | return result; |
408 | } | 453 | } |
409 | 454 | ||
455 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | ||
456 | { | ||
457 | long reg = 0, ret = 0; | ||
458 | |||
459 | if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { | ||
460 | netxen_crb_writelit_adapter(adapter, | ||
461 | NETXEN_NIU_XG1_CONFIG_0, 0x5); | ||
462 | /* XXX hack for Mez cards: both ports in promisc mode */ | ||
463 | netxen_nic_hw_read_wx(adapter, | ||
464 | NETXEN_NIU_XGE_CONFIG_1, ®, 4); | ||
465 | reg = (reg | 0x2000UL); | ||
466 | netxen_crb_writelit_adapter(adapter, | ||
467 | NETXEN_NIU_XGE_CONFIG_1, reg); | ||
468 | reg = 0; | ||
469 | netxen_nic_hw_read_wx(adapter, | ||
470 | NETXEN_NIU_XG1_CONFIG_1, ®, 4); | ||
471 | reg = (reg | 0x2000UL); | ||
472 | netxen_crb_writelit_adapter(adapter, | ||
473 | NETXEN_NIU_XG1_CONFIG_1, reg); | ||
474 | } | ||
475 | |||
476 | return ret; | ||
477 | } | ||
478 | |||
410 | /* | 479 | /* |
411 | * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts | 480 | * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts |
412 | * @param enable 0 means don't enable the port | 481 | * @param enable 0 means don't enable the port |
413 | * 1 means enable (or re-enable) the port | 482 | * 1 means enable (or re-enable) the port |
414 | */ | 483 | */ |
415 | int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, | 484 | int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, |
416 | int port, long enable) | 485 | int port, long enable) |
@@ -421,7 +490,10 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, | |||
421 | printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" | 490 | printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" |
422 | " (device enable = %d)\n", (int)port, (int)enable); | 491 | " (device enable = %d)\n", (int)port, (int)enable); |
423 | 492 | ||
424 | /* The read of the PHY INT status will clear the pending interrupt status */ | 493 | /* |
494 | * The read of the PHY INT status will clear the pending | ||
495 | * interrupt status | ||
496 | */ | ||
425 | if (netxen_niu_gbe_phy_read(adapter, port, | 497 | if (netxen_niu_gbe_phy_read(adapter, port, |
426 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, | 498 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, |
427 | &int_src) != 0) | 499 | &int_src) != 0) |
@@ -540,20 +612,42 @@ int netxen_niu_macaddr_set(struct netxen_port *port, | |||
540 | __le32 temp = 0; | 612 | __le32 temp = 0; |
541 | struct netxen_adapter *adapter = port->adapter; | 613 | struct netxen_adapter *adapter = port->adapter; |
542 | int phy = port->portnum; | 614 | int phy = port->portnum; |
615 | unsigned char mac_addr[MAX_ADDR_LEN]; | ||
616 | int i; | ||
617 | |||
618 | for (i = 0; i < 10; i++) { | ||
619 | memcpy(&temp, addr, 2); | ||
620 | temp <<= 16; | ||
621 | if (netxen_nic_hw_write_wx | ||
622 | (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &temp, 4)) | ||
623 | return -EIO; | ||
543 | 624 | ||
544 | memcpy(&temp, addr, 2); | 625 | temp = 0; |
545 | temp <<= 16; | ||
546 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), | ||
547 | &temp, 4)) | ||
548 | return -EIO; | ||
549 | 626 | ||
550 | temp = 0; | 627 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); |
628 | if (netxen_nic_hw_write_wx | ||
629 | (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &temp, 4)) | ||
630 | return -2; | ||
551 | 631 | ||
552 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | 632 | netxen_niu_macaddr_get(adapter, phy, |
553 | if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), | 633 | (netxen_ethernet_macaddr_t *) mac_addr); |
554 | &temp, 4)) | 634 | if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0)) |
555 | return -2; | 635 | break; |
636 | } | ||
556 | 637 | ||
638 | if (i == 10) { | ||
639 | printk(KERN_ERR "%s: cannot set Mac addr for %s\n", | ||
640 | netxen_nic_driver_name, port->netdev->name); | ||
641 | printk(KERN_ERR "MAC address set: " | ||
642 | "%02x:%02x:%02x:%02x:%02x:%02x.\n", | ||
643 | addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); | ||
644 | |||
645 | printk(KERN_ERR "MAC address get: " | ||
646 | "%02x:%02x:%02x:%02x:%02x:%02x.\n", | ||
647 | mac_addr[0], | ||
648 | mac_addr[1], | ||
649 | mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); | ||
650 | } | ||
557 | return 0; | 651 | return 0; |
558 | } | 652 | } |
559 | 653 | ||