diff options
Diffstat (limited to 'drivers/net/netxen')
| -rw-r--r-- | drivers/net/netxen/netxen_nic.h | 17 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 30 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 149 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 2 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 21 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 10 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 94 |
7 files changed, 136 insertions, 187 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 8e8a97839cb..77220687b92 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 74 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.74" +#define _NETXEN_NIC_LINUX_SUBVERSION 75 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.75" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -174,7 +174,7 @@ #define MAX_NUM_CARDS 4 -#define MAX_BUFFERS_PER_CMD 32 +#define NETXEN_MAX_FRAGS_PER_TX 14 #define MAX_TSO_HEADER_DESC 2 #define MGMT_CMD_DESC_RESV 4 #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ @@ -558,7 +558,7 @@ struct netxen_recv_crb { */ struct netxen_cmd_buffer { struct sk_buff *skb; - struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; + struct netxen_skb_frag frag_array[MAX_SKB_FRAGS + 1]; u32 frag_count; }; @@ -739,7 +739,8 @@ struct netxen_recv_context { #define NX_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c #define NX_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d #define NX_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e -#define NX_CDRP_CMD_MAX 0x0000001f +#define NX_CDRP_CMD_CONFIG_GBE_PORT 0x0000001f +#define NX_CDRP_CMD_MAX 0x00000020 #define NX_RCODE_SUCCESS 0 #define NX_RCODE_NO_HOST_MEM 1 @@ -1054,6 +1055,7 @@ typedef struct { #define NX_FW_CAPABILITY_BDG (1 << 8) #define NX_FW_CAPABILITY_FVLANTX (1 << 9) #define NX_FW_CAPABILITY_HW_LRO (1 << 10) +#define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11) /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -1132,6 +1134,7 @@ typedef struct { #define NETXEN_NIC_MSI_ENABLED 0x02 #define NETXEN_NIC_MSIX_ENABLED 0x04 #define NETXEN_NIC_LRO_ENABLED 0x08 +#define NETXEN_NIC_LRO_DISABLED 0x00 #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_IS_MSI_FAMILY(adapter) \ @@ -1174,7 +1177,7 @@ struct netxen_adapter { u8 max_sds_rings; u8 driver_mismatch; u8 msix_supported; - u8 rx_csum; + u8 __pad; u8 pci_using_dac; u8 portnum; u8 physical_port; @@ -1348,6 +1351,8 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); void netxen_pci_camqm_read_2M(struct netxen_adapter *, u64, u64 *); void netxen_pci_camqm_write_2M(struct netxen_adapter *, u64, u64); +int nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, + u32 speed, u32 duplex, u32 autoneg); int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 12612127a08..f16966afa64 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -112,6 +112,21 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) return 0; } +int +nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, + u32 speed, u32 duplex, u32 autoneg) +{ + + return netxen_issue_cmd(adapter, + adapter->ahw.pci_func, + NXHAL_VERSION, + speed, + duplex, + autoneg, + NX_CDRP_CMD_CONFIG_GBE_PORT); + +} + static int nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) { @@ -255,19 +270,6 @@ out_free_rq: } static void -nx_fw_cmd_reset_ctx(struct netxen_adapter *adapter) -{ - - netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, - adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, - NX_CDRP_CMD_DESTROY_RX_CTX); - - netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, - adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, - NX_CDRP_CMD_DESTROY_TX_CTX); -} - -static void nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; @@ -698,8 +700,6 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) goto done; - if (reset_devices) - nx_fw_cmd_reset_ctx(adapter); err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index b30de24f4a5..b34fb74d07e 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -117,7 +117,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->port = PORT_TP; - ecmd->speed = adapter->link_speed; + ethtool_cmd_speed_set(ecmd, adapter->link_speed); ecmd->duplex = adapter->link_duplex; ecmd->autoneg = adapter->link_autoneg; @@ -134,7 +134,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } if (netif_running(dev) && adapter->has_link_events) { - ecmd->speed = adapter->link_speed; + ethtool_cmd_speed_set(ecmd, adapter->link_speed); ecmd->autoneg = adapter->link_autoneg; ecmd->duplex = adapter->link_duplex; goto skip; @@ -146,10 +146,10 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u16 pcifn = adapter->ahw.pci_func; val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn)); - ecmd->speed = P3_LINK_SPEED_MHZ * - P3_LINK_SPEED_VAL(pcifn, val); + ethtool_cmd_speed_set(ecmd, P3_LINK_SPEED_MHZ * + P3_LINK_SPEED_VAL(pcifn, val)); } else - ecmd->speed = SPEED_10000; + ethtool_cmd_speed_set(ecmd, SPEED_10000); ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; @@ -214,7 +214,6 @@ skip: check_sfp_module = netif_running(dev) && adapter->has_link_events; } else { - ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); @@ -252,53 +251,25 @@ static int netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_adapter *adapter = netdev_priv(dev); - __u32 status; + u32 speed = ethtool_cmd_speed(ecmd); + int ret; - /* read which mode */ - if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - /* autonegotiation */ - if (adapter->phy_write && - adapter->phy_write(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - ecmd->autoneg) != 0) - return -EIO; - else - adapter->link_autoneg = ecmd->autoneg; + if (adapter->ahw.port_type != NETXEN_NIC_GBE) + return -EOPNOTSUPP; - if (adapter->phy_read && - adapter->phy_read(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) - return -EIO; + if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG)) + return -EOPNOTSUPP; - /* speed */ - switch (ecmd->speed) { - case SPEED_10: - netxen_set_phy_speed(status, 0); - break; - case SPEED_100: - netxen_set_phy_speed(status, 1); - break; - case SPEED_1000: - netxen_set_phy_speed(status, 2); - break; - } - /* set duplex mode */ - if (ecmd->duplex == DUPLEX_HALF) - netxen_clear_phy_duplex(status); - if (ecmd->duplex == DUPLEX_FULL) - netxen_set_phy_duplex(status); - if (adapter->phy_write && - adapter->phy_write(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - *((int *)&status)) != 0) - return -EIO; - else { - adapter->link_speed = ecmd->speed; - adapter->link_duplex = ecmd->duplex; - } - } else + ret = nx_fw_cmd_set_gbe_port(adapter, speed, ecmd->duplex, + ecmd->autoneg); + if (ret == NX_RCODE_NOT_SUPPORTED) return -EOPNOTSUPP; + else if (ret) + return -EIO; + + adapter->link_speed = speed; + adapter->link_duplex = ecmd->duplex; + adapter->link_autoneg = ecmd->autoneg; if (!netif_running(dev)) return 0; @@ -706,48 +677,6 @@ netxen_nic_get_ethtool_stats(struct net_device *dev, } } -static u32 netxen_nic_get_tx_csum(struct net_device *dev) -{ - return dev->features & NETIF_F_IP_CSUM; -} - -static u32 netxen_nic_get_rx_csum(struct net_device *dev) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - return adapter->rx_csum; -} - -static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - adapter->rx_csum = !!data; - return 0; -} - -static u32 netxen_nic_get_tso(struct net_device *dev) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0; - - return (dev->features & NETIF_F_TSO) != 0; -} - -static int netxen_nic_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - struct netxen_adapter *adapter = netdev_priv(dev); - - dev->features |= NETIF_F_TSO; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - dev->features |= NETIF_F_TSO6; - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - static void netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { @@ -882,35 +811,6 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } -static int netxen_nic_set_flags(struct net_device *netdev, u32 data) -{ - struct netxen_adapter *adapter = netdev_priv(netdev); - int hw_lro; - - if (data & ~ETH_FLAG_LRO) - return -EINVAL; - - if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) - return -EINVAL; - - if (data & ETH_FLAG_LRO) { - hw_lro = NETXEN_NIC_LRO_ENABLED; - netdev->features |= NETIF_F_LRO; - } else { - hw_lro = 0; - netdev->features &= ~NETIF_F_LRO; - } - - if (netxen_config_hw_lro(adapter, hw_lro)) - return -EIO; - - if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter)) - return -EIO; - - - return 0; -} - const struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, @@ -924,21 +824,12 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { .set_ringparam = netxen_nic_set_ringparam, .get_pauseparam = netxen_nic_get_pauseparam, .set_pauseparam = netxen_nic_set_pauseparam, - .get_tx_csum = netxen_nic_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .get_tso = netxen_nic_get_tso, - .set_tso = netxen_nic_set_tso, .get_wol = netxen_nic_get_wol, .set_wol = netxen_nic_set_wol, .self_test = netxen_nic_diag_test, .get_strings = netxen_nic_get_strings, .get_ethtool_stats = netxen_nic_get_ethtool_stats, .get_sset_count = netxen_get_sset_count, - .get_rx_csum = netxen_nic_get_rx_csum, - .set_rx_csum = netxen_nic_set_rx_csum, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, - .get_flags = ethtool_op_get_flags, - .set_flags = netxen_nic_set_flags, }; diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index d8bd73d7e29..dc1967c1f31 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -780,7 +780,7 @@ enum { /* * capabilities register, can be used to selectively enable/disable features - * for backward compability + * for backward compatibility */ #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 37d3ebd65be..5cef718fe35 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -655,7 +655,7 @@ nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op) } static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, - u8 *addr, struct list_head *del_list) + const u8 *addr, struct list_head *del_list) { struct list_head *head; nx_mac_list_t *cur; @@ -686,7 +686,9 @@ static void netxen_p3_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; - u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static const u8 bcast_addr[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; u32 mode = VPORT_MISS_MODE_DROP; LIST_HEAD(del_list); struct list_head *head; @@ -807,9 +809,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable) u64 word; int rv = 0; - if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable) - return 0; - memset(&req, 0, sizeof(nx_nic_req_t)); req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); @@ -825,8 +824,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable) "configure hw lro request\n"); } - adapter->flags ^= NETXEN_NIC_LRO_ENABLED; - return rv; } @@ -869,9 +866,11 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) u64 word; int i, rv; - u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, - 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, - 0x255b0ec26d5a56daULL }; + static const u64 key[] = { + 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, + 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, + 0x255b0ec26d5a56daULL + }; memset(&req, 0, sizeof(nx_nic_req_t)); @@ -895,7 +894,7 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) ((u64)(enable & 0x1) << 8) | ((0x7ULL) << 48); req.words[0] = cpu_to_le64(word); - for (i = 0; i < 5; i++) + for (i = 0; i < ARRAY_SIZE(key); i++) req.words[i+1] = cpu_to_le64(key[i]); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 95fe552aa27..7f999671c7b 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -214,13 +214,12 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) tx_ring->num_desc = adapter->num_txd; tx_ring->txq = netdev_get_tx_queue(netdev, 0); - cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); + cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); goto err_out; } - memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; @@ -279,8 +278,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) break; } - rds_ring->rx_buf_arr = (struct netxen_rx_buffer *) - vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); + rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { printk(KERN_ERR "%s: Failed to allocate " "rx buffer ring %d\n", @@ -288,7 +286,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) /* free whatever was already allocated */ goto err_out; } - memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles @@ -1486,7 +1483,8 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter, if (!skb) goto no_skb; - if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) { + if (likely((adapter->netdev->features & NETIF_F_RXCSUM) + && cksum == STATUS_CKSUM_OK)) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 50820beac3a..b644383017f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -38,12 +38,9 @@ #include <linux/sysfs.h> #include <linux/aer.h> -MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); +MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Intelligent Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); -MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); -MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); -MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); char netxen_nic_driver_name[] = "netxen_nic"; @@ -488,6 +485,37 @@ static void netxen_set_multicast_list(struct net_device *dev) adapter->set_multi(dev); } +static u32 netxen_fix_features(struct net_device *dev, u32 features) +{ + if (!(features & NETIF_F_RXCSUM)) { + netdev_info(dev, "disabling LRO as RXCSUM is off\n"); + + features &= ~NETIF_F_LRO; + } + + return features; +} + +static int netxen_set_features(struct net_device *dev, u32 features) +{ + struct netxen_adapter *adapter = netdev_priv(dev); + int hw_lro; + + if (!((dev->features ^ features) & NETIF_F_LRO)) + return 0; + + hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED + : NETXEN_NIC_LRO_DISABLED; + + if (netxen_config_hw_lro(adapter, hw_lro)) + return -EIO; + + if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter)) + return -EIO; + + return 0; +} + static const struct net_device_ops netxen_netdev_ops = { .ndo_open = netxen_nic_open, .ndo_stop = netxen_nic_close, @@ -498,6 +526,8 @@ static const struct net_device_ops netxen_netdev_ops = { .ndo_set_mac_address = netxen_nic_set_mac, .ndo_change_mtu = netxen_nic_change_mtu, .ndo_tx_timeout = netxen_tx_timeout, + .ndo_fix_features = netxen_fix_features, + .ndo_set_features = netxen_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = netxen_nic_poll_controller, #endif @@ -765,8 +795,6 @@ netxen_check_options(struct netxen_adapter *adapter) if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1); - adapter->flags &= ~NETXEN_NIC_LRO_ENABLED; - if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; @@ -910,7 +938,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter) struct nx_host_sds_ring *sds_ring; int err, ring; - unsigned long flags = IRQF_SAMPLE_RANDOM; + unsigned long flags = 0; struct net_device *netdev = adapter->netdev; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; @@ -993,7 +1021,7 @@ __netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) netxen_config_intr_coalesce(adapter); - if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO) + if (netdev->features & NETIF_F_LRO) netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED); netxen_napi_enable(adapter); @@ -1037,6 +1065,9 @@ __netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev); + if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) + netxen_linkevent_request(adapter, 0); + if (adapter->stop_port) adapter->stop_port(adapter); @@ -1198,7 +1229,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter, int err = 0; struct pci_dev *pdev = adapter->pdev; - adapter->rx_csum = 1; adapter->mc_enabled = 0; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) adapter->max_mc_count = 38; @@ -1212,14 +1242,13 @@ netxen_setup_netdev(struct netxen_adapter *adapter, SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); - netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); - netdev->features |= (NETIF_F_GRO); - netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); - netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); - } + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + + netdev->vlan_features |= netdev->hw_features; if (adapter->pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; @@ -1227,10 +1256,12 @@ netxen_setup_netdev(struct netxen_adapter *adapter, } if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX) - netdev->features |= (NETIF_F_HW_VLAN_TX); + netdev->hw_features |= NETIF_F_HW_VLAN_TX; if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO) - netdev->features |= NETIF_F_LRO; + netdev->hw_features |= NETIF_F_LRO; + + netdev->features |= netdev->hw_features; netdev->irq = adapter->msix_entries[0].vector; @@ -1240,7 +1271,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter, dev_warn(&pdev->dev, "failed to read mac addr\n"); netif_carrier_off(netdev); - netif_stop_queue(netdev); err = register_netdev(netdev); if (err) { @@ -1281,6 +1311,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int i = 0, err; int pci_func_id = PCI_FUNC(pdev->devfn); uint8_t revision_id; + u32 val; if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { pr_warning("%s: chip revisions between 0x%x-0x%x " @@ -1356,6 +1387,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + if (adapter->portnum == 0) { + val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); + if (val != 0xffffffff && val != 0) { + NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0); + adapter->need_fw_reset = 1; + } + } + err = netxen_start_firmware(adapter); if (err) goto err_out_decr_ref; @@ -1838,6 +1877,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct cmd_desc_type0 *hwdesc, *first_desc; struct pci_dev *pdev; int i, k; + int delta = 0; + struct skb_frag_struct *frag; u32 producer; int frag_count, no_of_desc; @@ -1845,6 +1886,21 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) frag_count = skb_shinfo(skb)->nr_frags + 1; + /* 14 frags supported for normal packet and + * 32 frags supported for TSO packet + */ + if (!skb_is_gso(skb) && frag_count > NETXEN_MAX_FRAGS_PER_TX) { + + for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) { + frag = &skb_shinfo(skb)->frags[i]; + delta += frag->size; + } + + if (!__pskb_pull_tail(skb, delta)) + goto drop_packet; + + frag_count = 1 + skb_shinfo(skb)->nr_frags; + } /* 4 fragments per cmd des */ no_of_desc = (frag_count + 3) >> 2; |
