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 | |
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')
-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_timeout_task); - netxen_nic_erase_pxe(adapter); + i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); + if (i != 0x55555555) + physical_port[adapter->portnum] = i; + netif_carrier_off(netdev); netif_stop_queue(netdev); - if((err = register_netdev(netdev))) - DPRINTK(1, ERR, "register_netdev failed port #%d" - " aborting\n", i+1); + if ((err = register_netdev(netdev))) { + printk(KERN_ERR "%s: register_netdev failed port #%d" + " aborting\n", netxen_nic_driver_name, + adapter->portnum); + err = -EIO; + goto err_out_free_dev; + } + + pci_set_drvdata(pdev, adapter); switch (adapter->ahw.board_type) { case NETXEN_NIC_GBE: @@ -519,21 +577,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } adapter->driver_mismatch = 0; - if(netxen_probe_flag == 0) - netxen_probe_flag ++; return 0; - err_out_free_dev: - if (adapter->flags & NETXEN_NIC_MSI_ENABLED) - pci_disable_msi(pdev); - - unregister_netdev(adapter->netdev); - free_netdev(adapter->netdev); - - netxen_free_adapter_offload(adapter); +err_out_free_dev: + if (adapter->portnum == 0) + netxen_free_adapter_offload(adapter); - err_out_free_rx_buffer: +err_out_free_rx_buffer: for (i = 0; i < MAX_RCV_CTX; ++i) { recv_ctx = &adapter->recv_ctx[i]; for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { @@ -546,14 +597,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } vfree(cmd_buf_arr); - err_out_free_adapter: +err_out_free_adapter: + if (adapter->flags & NETXEN_NIC_MSI_ENABLED) + pci_disable_msi(pdev); + pci_set_drvdata(pdev, NULL); - kfree(adapter); if (db_ptr) iounmap(db_ptr); - err_out_iounmap: +err_out_iounmap: if (mem_ptr0) iounmap(mem_ptr0); if (mem_ptr1) @@ -561,9 +614,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (mem_ptr2) iounmap(mem_ptr2); - err_out_free_res: +err_out_free_netdev: + free_netdev(netdev); + +err_out_free_res: pci_release_regions(pdev); - err_out_disable_pdev: + +err_out_disable_pdev: pci_disable_device(pdev); return err; } @@ -578,36 +635,39 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) int i; int ctxid, ring; - netdev = pci_get_drvdata(pdev); - adapter = netdev_priv(netdev); + adapter = pci_get_drvdata(pdev); if (adapter == NULL) return; + netdev = adapter->netdev; + + netxen_nic_disable_int(adapter); + if (adapter->irq) + free_irq(adapter->irq, adapter); + if (adapter->stop_port) adapter->stop_port(adapter); + if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) + pci_disable_msi(pdev); + + if (adapter->portnum == 0) + netxen_free_adapter_offload(adapter); + if (adapter->irq) free_irq(adapter->irq, adapter); if(adapter->portnum == 0) { /* leave the hw in the same state as reboot */ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); netxen_pinit_from_rom(adapter, 0); + udelay(500); netxen_load_firmware(adapter); - netxen_free_adapter_offload(adapter); + netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); } - udelay(500); - - if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) - pci_disable_msi(pdev); if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) netxen_free_hw_resources(adapter); - iounmap(adapter->ahw.db_base); - iounmap(adapter->ahw.pci_base0); - iounmap(adapter->ahw.pci_base1); - iounmap(adapter->ahw.pci_base2); - for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { recv_ctx = &adapter->recv_ctx[ctxid]; for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { @@ -626,14 +686,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) } } - vfree(adapter->cmd_buf_arr); unregister_netdev(netdev); - free_netdev(netdev); + + vfree(adapter->cmd_buf_arr); + + iounmap(adapter->ahw.db_base); + iounmap(adapter->ahw.pci_base0); + iounmap(adapter->ahw.pci_base1); + iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); + free_netdev(netdev); } /* @@ -668,9 +734,9 @@ static int netxen_nic_open(struct net_device *netdev) netxen_post_rx_buffers(adapter, ctx, ring); } adapter->irq = adapter->ahw.pdev->irq; - err = request_irq(adapter->ahw.pdev->irq, &netxen_intr, - IRQF_SHARED | IRQF_SAMPLE_RANDOM, - netdev->name, adapter); + err = request_irq(adapter->ahw.pdev->irq, netxen_intr, + SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, + adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); netxen_free_hw_resources(adapter); @@ -690,10 +756,9 @@ static int netxen_nic_open(struct net_device *netdev) adapter->macaddr_set(adapter, netdev->dev_addr); if (adapter->init_port && adapter->init_port(adapter, adapter->portnum) != 0) { + del_timer_sync(&adapter->watchdog_timer); printk(KERN_ERR "%s: Failed to initialize port %d\n", netxen_nic_driver_name, adapter->portnum); - free_irq(adapter->irq, adapter); - netxen_free_hw_resources(adapter); return -EIO; } @@ -722,10 +787,6 @@ static int netxen_nic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_stop_queue(netdev); - netxen_nic_disable_int(adapter); - if (adapter->irq) - free_irq(adapter->irq, adapter); - cmd_buff = adapter->cmd_buf_arr; for (i = 0; i < adapter->max_tx_desc_count; i++) { buffrag = cmd_buff->frag_array; @@ -879,6 +940,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); netxen_set_cmd_desc_port(hwdesc, adapter->portnum); + netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -968,9 +1030,18 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) producer = get_next_index(producer, max_tx_desc_count); } } + + i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); + + hw->cmd_desc_head[saved_producer].flags_opcode = + cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode); + hw->cmd_desc_head[saved_producer].num_of_buffers_total_length = + cpu_to_le32(hw->cmd_desc_head[saved_producer]. + num_of_buffers_total_length); + spin_lock_bh(&adapter->tx_lock); - adapter->stats.txbytes += - netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); + adapter->stats.txbytes += i; + /* Code to update the adapter considering how many producer threads are currently working */ if ((--adapter->num_threads) == 0) { @@ -1010,18 +1081,17 @@ static void netxen_tx_timeout_task(struct work_struct *work) { struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, tx_timeout_task); - struct net_device *netdev = adapter->netdev; unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", - netxen_nic_driver_name, netdev->name); + netxen_nic_driver_name, adapter->netdev->name); spin_lock_irqsave(&adapter->lock, flags); - netxen_nic_close(netdev); - netxen_nic_open(netdev); + netxen_nic_close(adapter->netdev); + netxen_nic_open(adapter->netdev); spin_unlock_irqrestore(&adapter->lock, flags); - netdev->trans_start = jiffies; - netif_wake_queue(netdev); + adapter->netdev->trans_start = jiffies; + netif_wake_queue(adapter->netdev); } static int diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index ad2486f2f64..cef90a78351 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -94,7 +94,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, long timeout = 0; long result = 0; long restore = 0; - long phy = adapter->portnum; + long phy = physical_port[adapter->portnum]; __u32 address; __u32 command; __u32 status; @@ -190,7 +190,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, long timeout = 0; long result = 0; long restore = 0; - long phy = adapter->portnum; + long phy = physical_port[adapter->portnum]; __u32 address; __u32 command; __u32 status; @@ -454,16 +454,18 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) { - u32 ret = 0; - int portnum = adapter->portnum; - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_XGE_CONFIG_1 +(0x10000 * portnum), - 0x1447); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_XG1_CONFIG_1 + - (0x10000 * portnum), 0x5); + u32 reg; + u32 portnum = physical_port[adapter->portnum]; + + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); + netxen_nic_hw_read_wx(adapter, + NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), ®, 4); + reg = (reg & ~0x2000UL); + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), reg); - return ret; + return 0; } /* @@ -571,7 +573,7 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter, { u32 stationhigh; u32 stationlow; - int phy = adapter->portnum; + int phy = physical_port[adapter->portnum]; u8 val[8]; if (addr == NULL) @@ -602,7 +604,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, { u8 temp[4]; u32 val; - int phy = adapter->portnum; + int phy = physical_port[adapter->portnum]; unsigned char mac_addr[6]; int i; @@ -724,8 +726,10 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) { __u32 mac_cfg0; - int port = adapter->portnum; + u32 port = physical_port[adapter->portnum]; + if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), @@ -738,7 +742,10 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) { __u32 mac_cfg; + u32 port = physical_port[adapter->portnum]; + if (port != 0) + return -EINVAL; mac_cfg = 0; netxen_xg_soft_reset(mac_cfg); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0, @@ -752,7 +759,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode) { __u32 reg; - int port = adapter->portnum; + u32 port = physical_port[adapter->portnum]; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -809,21 +816,47 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t addr) { + int phy = physical_port[adapter->portnum]; u8 temp[4]; u32 val; + if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) + return -EIO; + temp[0] = temp[1] = 0; - memcpy(temp + 2, addr, 2); - val = le32_to_cpu(*(__le32 *)temp); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, - &val, 4)) + switch (phy) { + case 0: + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); + if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, + &val, 4)) return -EIO; - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); - val = le32_to_cpu(*(__le32 *)temp); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, - &val, 4)) + memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); + val = le32_to_cpu(*(__le32 *)temp); + if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, + &val, 4)) + return -EIO; + break; + + case 1: + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); + if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, + &val, 4)) + return -EIO; + + memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); + val = le32_to_cpu(*(__le32 *)temp); + if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, + &val, 4)) return -EIO; + break; + + default: + printk(KERN_ERR "Unknown port %d\n", phy); + break; + } return 0; } @@ -835,7 +868,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t * addr) { - int phy = adapter->portnum; + int phy = physical_port[adapter->portnum]; u32 stationhigh; u32 stationlow; u8 val[8]; @@ -863,21 +896,21 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode) { __u32 reg; - int port = adapter->portnum; + u32 port = physical_port[adapter->portnum]; if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return -EINVAL; - if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1 + - (0x10000 * port), ®, 4)) - return -EIO; + if (netxen_nic_hw_read_wx(adapter, + NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) + return -EIO; if (mode == NETXEN_NIU_PROMISC_MODE) reg = (reg | 0x2000UL); else reg = (reg & ~0x2000UL); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1 + - (0x10000 * port), reg); + netxen_crb_writelit_adapter(adapter, + NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); return 0; } diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 12bcaf9743b..9457fc7249c 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -108,6 +108,13 @@ #define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4) #define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4) +#define CRB_V2P_0 NETXEN_NIC_REG(0x290) +#define CRB_V2P_1 NETXEN_NIC_REG(0x294) +#define CRB_V2P_2 NETXEN_NIC_REG(0x298) +#define CRB_V2P_3 NETXEN_NIC_REG(0x29c) +#define CRB_V2P(port) (CRB_V2P_0+((port)*4)) +#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) + /* used for ethtool tests */ #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) |