diff options
author | Mithlesh Thukral <mithlesh@netxen.com> | 2007-04-20 07:55:26 -0700 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 11:01:06 -0400 |
commit | 6c80b18df3537d1221ab34555c150bccbfd90260 (patch) | |
tree | b82c057feb8a4c5c4ba0171b268599ea357eb2a9 /drivers/net/netxen | |
parent | 5d512f5594f9f4829b099c87f7bc6f683ef146ca (diff) |
NetXen: Port swap feature for multi port cards
NetXen: Port Swap feature
This patch will allow a port numbers on the card to be swapped in
host driver. This feature is applicable to cards having more than
1 port.
Signed-off by: Milan Bag <mbag@netxen.com>
Signed-off by: Mithlesh Thukral <mithlesh@netxen.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 21 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 143 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 3 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 67 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 63 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_isr.c | 29 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 306 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 93 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_phan_reg.h | 7 |
10 files changed, 468 insertions, 266 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 923ae6c029d..1e944d5eb45 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -205,6 +205,7 @@ enum { #define MAX_CMD_DESCRIPTORS 1024 #define MAX_RCV_DESCRIPTORS 16384 +#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) #define MAX_JUMBO_RCV_DESCRIPTORS 1024 #define MAX_LRO_RCV_DESCRIPTORS 64 @@ -303,6 +304,8 @@ struct netxen_ring_ctx { #define netxen_set_cmd_desc_port(cmd_desc, var) \ ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) +#define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ + ((cmd_desc)->port_ctxid |= ((var) & 0xF0)) #define netxen_set_cmd_desc_flags(cmd_desc, val) \ ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ @@ -445,7 +448,7 @@ struct status_desc { /* Bit pattern: 0-6 lro_count indicates frag sequence, 7 last_frag indicates last frag */ u8 lro; -} __attribute__ ((aligned(8))); +} __attribute__ ((aligned(16))); enum { NETXEN_RCV_PEG_0 = 0, @@ -723,6 +726,18 @@ struct netxen_skb_frag { u32 length; }; +#define _netxen_set_bits(config_word, start, bits, val) {\ + unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));\ + unsigned long long __tvalue = (val); \ + (config_word) &= ~__tmask; \ + (config_word) |= (((__tvalue) << (start)) & __tmask); \ +} + +#define _netxen_clear_bits(config_word, start, bits) {\ + unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start)); \ + (config_word) &= ~__tmask; \ +} + /* Following defines are for the state of the buffers */ #define NETXEN_BUFFER_FREE 0 #define NETXEN_BUFFER_BUSY 1 @@ -767,6 +782,8 @@ struct netxen_hardware_context { void __iomem *pci_base0; void __iomem *pci_base1; void __iomem *pci_base2; + unsigned long first_page_group_end; + unsigned long first_page_group_start; void __iomem *db_base; unsigned long db_len; @@ -862,6 +879,7 @@ struct netxen_adapter { struct netxen_adapter *master; struct net_device *netdev; struct pci_dev *pdev; + struct net_device_stats net_stats; unsigned char mac_addr[ETH_ALEN]; int mtu; int portnum; @@ -1152,4 +1170,5 @@ extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, extern struct ethtool_ops netxen_nic_ethtool_ops; +extern int physical_port[]; /* physical port # from virtual port.*/ #endif /* __NETXEN_NIC_H_ */ diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 24c68f42584..16fabb37748 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -40,8 +40,8 @@ #include <linux/ethtool.h> #include <linux/version.h> -#include "netxen_nic_hw.h" #include "netxen_nic.h" +#include "netxen_nic_hw.h" #include "netxen_nic_phan_reg.h" struct netxen_nic_stats { @@ -379,7 +379,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { /* GB: port specific registers */ if (mode == 0 && i >= 19) - window = adapter->portnum * + window = physical_port[adapter->portnum] * NETXEN_NIC_PORT_WINDOW; NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. @@ -537,16 +537,43 @@ netxen_nic_get_pauseparam(struct net_device *dev, { struct netxen_adapter *adapter = netdev_priv(dev); __u32 val; + int port = physical_port[adapter->portnum]; if (adapter->ahw.board_type == NETXEN_NIC_GBE) { + if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + return; /* get flow control settings */ - netxen_nic_read_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), - &val); + netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port), + &val); pause->rx_pause = netxen_gb_get_rx_flowctl(val); - pause->tx_pause = netxen_gb_get_tx_flowctl(val); - /* get autoneg settings */ - pause->autoneg = adapter->link_autoneg; + netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); + switch (port) { + case 0: + pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); + break; + case 1: + pause->tx_pause = !(netxen_gb_get_gb1_mask(val)); + break; + case 2: + pause->tx_pause = !(netxen_gb_get_gb2_mask(val)); + break; + case 3: + default: + pause->tx_pause = !(netxen_gb_get_gb3_mask(val)); + break; + } + } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) + return; + pause->rx_pause = 1; + netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); + if (port == 0) + pause->tx_pause = !(netxen_xg_get_xg0_mask(val)); + else + pause->tx_pause = !(netxen_xg_get_xg1_mask(val)); + } else { + printk(KERN_ERR"%s: Unknown board type: %x\n", + netxen_nic_driver_name, adapter->ahw.board_type); } } @@ -556,39 +583,74 @@ netxen_nic_set_pauseparam(struct net_device *dev, { struct netxen_adapter *adapter = netdev_priv(dev); __u32 val; - unsigned int autoneg; - + int port = physical_port[adapter->portnum]; /* read mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { + if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + return -EIO; /* set flow control */ netxen_nic_read_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), - (u32 *) & val); - if (pause->tx_pause) - netxen_gb_tx_flowctl(val); - else - netxen_gb_unset_tx_flowctl(val); + NETXEN_NIU_GB_MAC_CONFIG_0(port), &val); + if (pause->rx_pause) netxen_gb_rx_flowctl(val); else netxen_gb_unset_rx_flowctl(val); - netxen_nic_write_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), - *&val); + netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), + val); /* set autoneg */ - autoneg = pause->autoneg; - if (adapter->phy_write - && adapter->phy_write(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - autoneg) != 0) + netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); + switch (port) { + case 0: + if (pause->tx_pause) + netxen_gb_unset_gb0_mask(val); + else + netxen_gb_set_gb0_mask(val); + break; + case 1: + if (pause->tx_pause) + netxen_gb_unset_gb1_mask(val); + else + netxen_gb_set_gb1_mask(val); + break; + case 2: + if (pause->tx_pause) + netxen_gb_unset_gb2_mask(val); + else + netxen_gb_set_gb2_mask(val); + break; + case 3: + default: + if (pause->tx_pause) + netxen_gb_unset_gb3_mask(val); + else + netxen_gb_set_gb3_mask(val); + break; + } + netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); + } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return -EIO; - else { - adapter->link_autoneg = pause->autoneg; - return 0; + netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); + if (port == 0) { + if (pause->tx_pause) + netxen_xg_unset_xg0_mask(val); + else + netxen_xg_set_xg0_mask(val); + } else { + if (pause->tx_pause) + netxen_xg_unset_xg1_mask(val); + else + netxen_xg_set_xg1_mask(val); } - } else - return -EOPNOTSUPP; + netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); + } else { + printk(KERN_ERR "%s: Unknown board type: %x\n", + netxen_nic_driver_name, + adapter->ahw.board_type); + } + return 0; } static int netxen_nic_reg_test(struct net_device *dev) @@ -619,23 +681,12 @@ static void netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, u64 * data) { - if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* offline tests */ - /* link test */ - if ((data[1] = (u64) netxen_nic_test_link(dev))) - eth_test->flags |= ETH_TEST_FL_FAILED; - - /* register tests */ - if ((data[0] = netxen_nic_reg_test(dev))) - eth_test->flags |= ETH_TEST_FL_FAILED; - } else { /* online tests */ - /* register tests */ - if((data[0] = netxen_nic_reg_test(dev))) - eth_test->flags |= ETH_TEST_FL_FAILED; - - /* link test */ - if ((data[1] = (u64) netxen_nic_test_link(dev))) - eth_test->flags |= ETH_TEST_FL_FAILED; - } + memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN); + if ((data[0] = netxen_nic_reg_test(dev))) + eth_test->flags |= ETH_TEST_FL_FAILED; + /* link test */ + if ((data[1] = (u64) netxen_nic_test_link(dev))) + eth_test->flags |= ETH_TEST_FL_FAILED; } static void diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index b826bca9c4e..608e37b349b 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -467,6 +467,8 @@ enum { #define NETXEN_PCI_OCM1 (0x05100000UL) #define NETXEN_PCI_OCM1_MAX (0x051fffffUL) #define NETXEN_PCI_CRBSPACE (0x06000000UL) +#define NETXEN_PCI_128MB_SIZE (0x08000000UL) +#define NETXEN_PCI_32MB_SIZE (0x02000000UL) #define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM) @@ -528,6 +530,7 @@ enum { #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) +#define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) #define NETXEN_NIU_FULL_LEVEL_XG (NETXEN_CRB_NIU + 0x00450) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 74517b640c2..3f4853fdba7 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -145,7 +145,7 @@ struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x184), }, /* - * Instance 3, + * Instance 2, */ { { @@ -194,7 +194,7 @@ struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x228), }, /* - * Instance 4, + * Instance 3, */ { { @@ -310,7 +310,6 @@ void netxen_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct dev_mc_list *mc_ptr; - __u32 netxen_mac_addr_cntl_data = 0; mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { @@ -318,43 +317,10 @@ void netxen_nic_set_multi(struct net_device *netdev) adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE); } else { - if (adapter->unset_promisc && - adapter->ahw.boardcfg.board_type - != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) + if (adapter->unset_promisc) adapter->unset_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE); } - if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { - netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03); - netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_enable_xtnd0(netxen_mac_addr_cntl_data); - netxen_nic_mcr_set_enable_xtnd1(netxen_mac_addr_cntl_data); - netxen_nic_mcr_set_enable_xtnd2(netxen_mac_addr_cntl_data); - netxen_nic_mcr_set_enable_xtnd3(netxen_mac_addr_cntl_data); - } else { - netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00); - netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x01); - netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x02); - netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x03); - } - writel(netxen_mac_addr_cntl_data, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_MAC_ADDR_CNTL_REG)); - if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { - writel(netxen_mac_addr_cntl_data, - NETXEN_CRB_NORMALIZE(adapter, - NETXEN_MULTICAST_ADDR_HI_0)); - } else { - writel(netxen_mac_addr_cntl_data, - NETXEN_CRB_NORMALIZE(adapter, - NETXEN_MULTICAST_ADDR_HI_1)); - } - netxen_mac_addr_cntl_data = 0; - writel(netxen_mac_addr_cntl_data, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_NIU_GB_DROP_WRONGADDR)); } /* @@ -390,7 +356,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) void *addr; int loops = 0, err = 0; int ctx, ring; - u32 card_cmdring = 0; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int func_id = adapter->portnum; @@ -402,11 +367,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); - /* Window 1 call */ - card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING)); - - DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n", - card_cmdring); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); @@ -449,7 +409,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } memset(addr, 0, sizeof(struct netxen_ring_ctx)); adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->ctx_id = adapter->portnum; + adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); adapter->ctx_desc->cmd_consumer_offset = cpu_to_le64(adapter->ctx_desc_phys_addr + sizeof(struct netxen_ring_ctx)); @@ -551,10 +511,6 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) adapter->ahw.cmd_desc_phys_addr); adapter->ahw.cmd_desc_head = NULL; } - /* Special handling: there are 2 ports on this board */ - if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { - adapter->ahw.max_ports = 2; - } for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { recv_ctx = &adapter->recv_ctx[ctx]; @@ -735,7 +691,10 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) count++; } - adapter->curr_window = wndw; + if (wndw == NETXEN_WINDOW_ONE) + adapter->curr_window = 1; + else + adapter->curr_window = 0; } void netxen_load_firmware(struct netxen_adapter *adapter) @@ -1055,18 +1014,18 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) { netxen_nic_write_w0(adapter, - NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->portnum), - new_mtu); + NETXEN_NIU_GB_MAX_FRAME_SIZE( + physical_port[adapter->portnum]), new_mtu); return 0; } int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; - if (adapter->portnum == 0) + if (physical_port[adapter->portnum] == 0) netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); - else if (adapter->portnum == 1) + else netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); return 0; @@ -1074,7 +1033,7 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) { - netxen_niu_gbe_init_port(adapter, adapter->portnum); + netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]); } void diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 94459cf6dc1..245bf13c7ba 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -220,6 +220,69 @@ typedef enum { _netxen_crb_get_bit(config_word, 1) #define netxen_get_gb_mii_mgmt_notvalid(config_word) \ _netxen_crb_get_bit(config_word, 2) +/* + * NIU XG Pause Ctl Register + * + * Bit 0 : xg0_mask => 1:disable tx pause frames + * Bit 1 : xg0_request => 1:request single pause frame + * Bit 2 : xg0_on_off => 1:request is pause on, 0:off + * Bit 3 : xg1_mask => 1:disable tx pause frames + * Bit 4 : xg1_request => 1:request single pause frame + * Bit 5 : xg1_on_off => 1:request is pause on, 0:off + */ + +#define netxen_xg_set_xg0_mask(config_word) \ + ((config_word) |= 1 << 0) +#define netxen_xg_set_xg1_mask(config_word) \ + ((config_word) |= 1 << 3) + +#define netxen_xg_get_xg0_mask(config_word) \ + _netxen_crb_get_bit((config_word), 0) +#define netxen_xg_get_xg1_mask(config_word) \ + _netxen_crb_get_bit((config_word), 3) + +#define netxen_xg_unset_xg0_mask(config_word) \ + ((config_word) &= ~(1 << 0)) +#define netxen_xg_unset_xg1_mask(config_word) \ + ((config_word) &= ~(1 << 3)) + +/* + * NIU XG Pause Ctl Register + * + * Bit 0 : xg0_mask => 1:disable tx pause frames + * Bit 1 : xg0_request => 1:request single pause frame + * Bit 2 : xg0_on_off => 1:request is pause on, 0:off + * Bit 3 : xg1_mask => 1:disable tx pause frames + * Bit 4 : xg1_request => 1:request single pause frame + * Bit 5 : xg1_on_off => 1:request is pause on, 0:off + */ +#define netxen_gb_set_gb0_mask(config_word) \ + ((config_word) |= 1 << 0) +#define netxen_gb_set_gb1_mask(config_word) \ + ((config_word) |= 1 << 2) +#define netxen_gb_set_gb2_mask(config_word) \ + ((config_word) |= 1 << 4) +#define netxen_gb_set_gb3_mask(config_word) \ + ((config_word) |= 1 << 6) + +#define netxen_gb_get_gb0_mask(config_word) \ + _netxen_crb_get_bit((config_word), 0) +#define netxen_gb_get_gb1_mask(config_word) \ + _netxen_crb_get_bit((config_word), 2) +#define netxen_gb_get_gb2_mask(config_word) \ + _netxen_crb_get_bit((config_word), 4) +#define netxen_gb_get_gb3_mask(config_word) \ + _netxen_crb_get_bit((config_word), 6) + +#define netxen_gb_unset_gb0_mask(config_word) \ + ((config_word) &= ~(1 << 0)) +#define netxen_gb_unset_gb1_mask(config_word) \ + ((config_word) &= ~(1 << 2)) +#define netxen_gb_unset_gb2_mask(config_word) \ + ((config_word) &= ~(1 << 4)) +#define netxen_gb_unset_gb3_mask(config_word) \ + ((config_word) &= ~(1 << 6)) + /* * PHY-Specific MII control/status registers. diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 2a3a91d2c38..3cd7e35bfbc 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1033,7 +1033,7 @@ void netxen_watchdog_task(struct work_struct *work) struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, watchdog_task); - if (netxen_nic_check_temp(adapter)) + if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) return; netdev = adapter->netdev; diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 8510216c6b0..b213b062eb5 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -34,38 +34,38 @@ #include "netxen_nic_hw.h" #include "netxen_nic_phan_reg.h" -#if 0 /* * netxen_nic_get_stats - Get System Network Statistics * @netdev: network interface device structure */ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) { - struct netxen_port *port = netdev_priv(netdev); + struct netxen_adapter *adapter = netdev_priv(netdev); struct net_device_stats *stats = &adapter->net_stats; memset(stats, 0, sizeof(*stats)); /* total packets received */ - stats->rx_packets = port->stats.no_rcv; + stats->rx_packets = adapter->stats.no_rcv; /* total packets transmitted */ - stats->tx_packets = port->stats.xmitedframes + port->stats.xmitfinished; + stats->tx_packets = adapter->stats.xmitedframes + + adapter->stats.xmitfinished; /* total bytes received */ - stats->rx_bytes = port->stats.rxbytes; + stats->rx_bytes = adapter->stats.rxbytes; /* total bytes transmitted */ - stats->tx_bytes = port->stats.txbytes; + stats->tx_bytes = adapter->stats.txbytes; /* bad packets received */ - stats->rx_errors = port->stats.rcvdbadskb; + stats->rx_errors = adapter->stats.rcvdbadskb; /* packet transmit problems */ - stats->tx_errors = port->stats.nocmddescriptor; + stats->tx_errors = adapter->stats.nocmddescriptor; /* no space in linux buffers */ - stats->rx_dropped = port->stats.updropped; + stats->rx_dropped = adapter->stats.updropped; /* no space available in linux */ - stats->tx_dropped = port->stats.txdropped; + stats->tx_dropped = adapter->stats.txdropped; return stats; } -#endif + void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link) { struct net_device *netdev = adapter->netdev; @@ -116,9 +116,6 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) &status) == 0) { if (netxen_get_phy_int_link_status_changed(int_src)) { if (netxen_get_phy_link(status)) { - netxen_niu_gbe_init_port( - adapter, - adapter->portnum); printk(KERN_INFO "%s: %s Link UP\n", netxen_nic_driver_name, adapter->netdev->name); @@ -145,7 +142,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter) /* verify the offset */ val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); - val = val >> adapter->portnum; + val = val >> physical_port[adapter->portnum]; if (val == adapter->ahw.qg_linksup) return; @@ -179,7 +176,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) /* WINDOW = 1 */ val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); - val >>= (adapter->portnum * 8); + val >>= (physical_port[adapter->portnum] * 8); val1 = val & 0xff; if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 137fb579bd1..4e32bb678ea 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -76,6 +76,8 @@ static void netxen_nic_poll_controller(struct net_device *netdev); #endif static irqreturn_t netxen_intr(int irq, void *data); +int physical_port[] = {0, 1, 2, 3}; + /* PCI Device ID Table */ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { {PCI_DEVICE(0x4040, 0x0001)}, @@ -174,6 +176,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *mem_ptr0 = NULL; void __iomem *mem_ptr1 = NULL; void __iomem *mem_ptr2 = NULL; + unsigned long first_page_group_end; + unsigned long first_page_group_start; + u8 __iomem *db_ptr = NULL; unsigned long mem_base, mem_len, db_base, db_len; @@ -183,11 +188,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct netxen_rcv_desc_ctx *rcv_desc = NULL; struct netxen_cmd_buffer *cmd_buf_arr = NULL; u64 mac_addr[FLASH_NUM_PORTS + 1]; - static int valid_mac = 0; - static int netxen_probe_flag; + int valid_mac = 0; + u32 val; int pci_func_id = PCI_FUNC(pdev->devfn); printk(KERN_INFO "%s \n", netxen_nic_driver_string); + if (pdev->class != 0x020000) { printk(KERN_ERR"NetXen function %d, class %x will not" "be enabled.\n",pci_func_id, pdev->class); @@ -234,19 +240,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.pdev = pdev; adapter->ahw.pci_func = pci_func_id; + spin_lock_init(&adapter->tx_lock); + spin_lock_init(&adapter->lock); /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ mem_len = pci_resource_len(pdev, 0); /* 128 Meg of memory */ - mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); - mem_ptr1 = - ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE); - mem_ptr2 = - ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); + if (mem_len == NETXEN_PCI_128MB_SIZE) { + mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); + mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, + SECOND_PAGE_GROUP_SIZE); + mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, + THIRD_PAGE_GROUP_SIZE); + first_page_group_start = FIRST_PAGE_GROUP_START; + first_page_group_end = FIRST_PAGE_GROUP_END; + } else if (mem_len == NETXEN_PCI_32MB_SIZE) { + mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); + mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - + SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); + first_page_group_start = 0; + first_page_group_end = 0; + } else { + err = -EIO; + goto err_out_free_netdev; + } - if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { + if (((mem_ptr0 == 0UL) && (mem_len == NETXEN_PCI_128MB_SIZE)) || + (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { DPRINTK(ERR, "Cannot remap adapter memory aborting.:" "0 -> %p, 1 -> %p, 2 -> %p\n", @@ -276,17 +298,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); - adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; - if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || - (adapter->ahw.boardcfg.board_type == - NETXEN_BRDTYPE_P2_SB31_2G)) - adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; - else - adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; - adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; - adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; - - pci_set_drvdata(pdev, netdev); + adapter->ahw.pci_base0 = mem_ptr0; + adapter->ahw.first_page_group_start = first_page_group_start; + adapter->ahw.first_page_group_end = first_page_group_end; + adapter->ahw.pci_base1 = mem_ptr1; + adapter->ahw.pci_base2 = mem_ptr2; + adapter->ahw.db_base = db_ptr; + adapter->ahw.db_len = db_len; adapter->netdev = netdev; adapter->pdev = pdev; @@ -295,6 +313,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->open = netxen_nic_open; netdev->stop = netxen_nic_close; netdev->hard_start_xmit = netxen_nic_xmit_frame; + netdev->get_stats = netxen_nic_get_stats; netdev->set_multicast_list = netxen_nic_set_multi; netdev->set_mac_address = netxen_nic_set_mac; netdev->change_mtu = netxen_nic_change_mtu; @@ -324,6 +343,42 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } else adapter->flags |= NETXEN_NIC_MSI_ENABLED; + netdev->irq = pdev->irq; + INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); + + /* + * Set the CRB window to invalid. If any register in window 0 is + * accessed it should set the window to 0 and then reset it to 1. + */ + adapter->curr_window = 255; + + /* initialize the adapter */ + netxen_initialize_adapter_hw(adapter); + +#ifdef CONFIG_PPC + if ((adapter->ahw.boardcfg.board_type == + NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) && + (pci_func_id == 2)) + goto err_out_free_adapter; +#endif /* CONFIG_PPC */ + + /* + * Adapter in our case is quad port so initialize it before + * initializing the ports + */ + + netxen_initialize_adapter_ops(adapter); + + adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; + if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || + (adapter->ahw.boardcfg.board_type == + NETXEN_BRDTYPE_P2_SB31_2G)) + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; + else + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; + adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; + adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; + cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); if (cmd_buf_arr == NULL) { printk(KERN_ERR @@ -333,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_adapter; } memset(cmd_buf_arr, 0, TX_RINGSIZE); + adapter->cmd_buf_arr = cmd_buf_arr; for (i = 0; i < MAX_RCV_CTX; ++i) { recv_ctx = &adapter->recv_ctx[i]; @@ -380,23 +436,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } - adapter->cmd_buf_arr = cmd_buf_arr; - adapter->ahw.pci_base0 = mem_ptr0; - adapter->ahw.pci_base1 = mem_ptr1; - adapter->ahw.pci_base2 = mem_ptr2; - adapter->ahw.db_base = db_ptr; - adapter->ahw.db_len = db_len; - spin_lock_init(&adapter->tx_lock); - spin_lock_init(&adapter->lock); - /* initialize the adapter */ - netxen_initialize_adapter_hw(adapter); - - netxen_initialize_adapter_ops(adapter); - netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ + /* Mezz cards have PCI function 0,2,3 enabled */ - if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) - if (pci_func_id >= 2) + if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) + && (pci_func_id >= 2)) adapter->portnum = pci_func_id - 2; #ifdef CONFIG_IA64 @@ -407,16 +451,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } #endif - /* - * Set the CRB window to invalid. If any register in window 0 is - * accessed it should set the window to 0 and then reset it to 1. - */ - adapter->curr_window = 255; - /* - * Adapter in our case is quad port so initialize it before - * initializing the ports - */ - init_timer(&adapter->watchdog_timer); adapter->ahw.xg_linkup = 0; adapter->watchdog_timer.function = &netxen_watchdog; @@ -426,8 +460,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->proc_cmd_buf_counter = 0; adapter->ahw.revision_id = nx_p2_id; + /* make sure Window == 1 */ + netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_update_cmd_producer(adapter, 0); netxen_nic_update_cmd_consumer(adapter, 0); + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); if (netxen_is_flash_supported(adapter) == 0 && netxen_get_flash_mac_addr(adapter, mac_addr) == 0) @@ -463,20 +501,41 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } - /* - * Initialize all the CRB registers here. - */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); - - /* do this before waking up pegs so that we have valid dummy dma addr */ - if (adapter->portnum == 0) + if (adapter->portnum == 0) { err = netxen_initialize_adapter_offload(adapter); - if (err) - goto err_out_free_dev; + if (err) + goto err_out_free_rx_buffer; + val = readl(NETXEN_CRB_NORMALIZE(adapter, + NETXEN_CAM_RAM(0x1fc))); + if (val == 0x55555555) { + /* This is the first boot after power up */ + val = readl(NETXEN_CRB_NORMALIZE(adapter, + NETXEN_ROMUSB_GLB_SW_RESET)); + printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); + if (val != 0x80000f) { + /* clear the register for future unloads/loads */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, + NETXEN_CAM_RAM(0x1fc))); + printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); + err = -ENODEV; + goto err_out_free_dev; + } + + /* clear the register for future unloads/loads */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, + NETXEN_CAM_RAM(0x1fc))); + } + printk(KERN_INFO "State: 0x%0x\n", + readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); + + /* + * Tell the hardware our version number. + */ + i = (_NETXEN_NIC_LINUX_MAJOR << 16) + | ((_NETXEN_NIC_LINUX_MINOR << 8)) + | (_NETXEN_NIC_LINUX_SUBVERSION); + writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION)); - if (netxen_probe_flag == 0) { /* Unlock the HW, prompting the boot sequence */ writel(1, NETXEN_CRB_NORMALIZE(adapter, @@ -485,26 +544,25 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); } - if(netxen_probe_flag == 0) { - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); - netxen_pinit_from_rom(adapter, 0); - udelay(500); - netxen_load_firmware(adapter); - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); - } /* - * delay a while to ensure that the Pegs are up & running. - * Otherwise, we might see some flaky behaviour. + * See if the firmware gave us a virtual-physical port mapping. */ - udelay(100); - INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeo |