netxen_nic_ethtool.c
来自「linux 内核源代码」· C语言 代码 · 共 770 行 · 第 1/2 页
C
770 行
} }}static u32 netxen_nic_test_link(struct net_device *dev){ struct netxen_adapter *adapter = netdev_priv(dev); __u32 status; int val; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { if (adapter->phy_read && adapter->phy_read(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status) != 0) return -EIO; else { val = netxen_get_phy_link(status); return !val; } } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); return (val == XG_LINK_UP) ? 0 : 1; } return -EIO;}static intnetxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * bytes){ struct netxen_adapter *adapter = netdev_priv(dev); int offset; int ret; if (eeprom->len == 0) return -EINVAL; eeprom->magic = (adapter->pdev)->vendor | ((adapter->pdev)->device << 16); offset = eeprom->offset; ret = netxen_rom_fast_read_words(adapter, offset, bytes, eeprom->len); if (ret < 0) return ret; return 0;}static intnetxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * bytes){ struct netxen_adapter *adapter = netdev_priv(dev); int offset = eeprom->offset; static int flash_start; static int ready_to_flash; int ret; if (flash_start == 0) { netxen_halt_pegs(adapter); ret = netxen_flash_unlock(adapter); if (ret < 0) { printk(KERN_ERR "%s: Flash unlock failed.\n", netxen_nic_driver_name); return ret; } printk(KERN_INFO "%s: flash unlocked. \n", netxen_nic_driver_name); last_schedule_time = jiffies; ret = netxen_flash_erase_secondary(adapter); if (ret != FLASH_SUCCESS) { printk(KERN_ERR "%s: Flash erase failed.\n", netxen_nic_driver_name); return ret; } printk(KERN_INFO "%s: secondary flash erased successfully.\n", netxen_nic_driver_name); flash_start = 1; return 0; } if (offset == NETXEN_BOOTLD_START) { ret = netxen_flash_erase_primary(adapter); if (ret != FLASH_SUCCESS) { printk(KERN_ERR "%s: Flash erase failed.\n", netxen_nic_driver_name); return ret; } ret = netxen_rom_se(adapter, NETXEN_USER_START); if (ret != FLASH_SUCCESS) return ret; ret = netxen_rom_se(adapter, NETXEN_FIXED_START); if (ret != FLASH_SUCCESS) return ret; printk(KERN_INFO "%s: primary flash erased successfully\n", netxen_nic_driver_name); ret = netxen_backup_crbinit(adapter); if (ret != FLASH_SUCCESS) { printk(KERN_ERR "%s: CRBinit backup failed.\n", netxen_nic_driver_name); return ret; } printk(KERN_INFO "%s: CRBinit backup done.\n", netxen_nic_driver_name); ready_to_flash = 1; } if (!ready_to_flash) { printk(KERN_ERR "%s: Invalid write sequence, returning...\n", netxen_nic_driver_name); return -EINVAL; } return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);}static voidnetxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring){ struct netxen_adapter *adapter = netdev_priv(dev); int i; ring->rx_pending = 0; ring->rx_jumbo_pending = 0; for (i = 0; i < MAX_RCV_CTX; ++i) { ring->rx_pending += adapter->recv_ctx[i]. rcv_desc[RCV_DESC_NORMAL_CTXID].max_rx_desc_count; ring->rx_jumbo_pending += adapter->recv_ctx[i]. rcv_desc[RCV_DESC_JUMBO_CTXID].max_rx_desc_count; } ring->tx_pending = adapter->max_tx_desc_count; ring->rx_max_pending = MAX_RCV_DESCRIPTORS; ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST; ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS; ring->rx_mini_max_pending = 0; ring->rx_mini_pending = 0;}static voidnetxen_nic_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause){ 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(port), &val); pause->rx_pause = netxen_gb_get_rx_flowctl(val); 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); }}static intnetxen_nic_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause){ struct netxen_adapter *adapter = netdev_priv(dev); __u32 val; 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(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(port), val); /* set autoneg */ 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; 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); } 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){ struct netxen_adapter *adapter = netdev_priv(dev); u32 data_read, data_written; netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read); if ((data_read & 0xffff) != PHAN_VENDOR_ID) return 1; data_written = (u32)0xa5a5a5a5; netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST)); if (data_written != data_read) return 1; return 0;}static int netxen_get_sset_count(struct net_device *dev, int sset){ switch (sset) { case ETH_SS_TEST: return NETXEN_NIC_TEST_LEN; case ETH_SS_STATS: return NETXEN_NIC_STATS_LEN; default: return -EOPNOTSUPP; }}static voidnetxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, u64 * data){ 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 voidnetxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data){ int index; switch (stringset) { case ETH_SS_TEST: memcpy(data, *netxen_nic_gstrings_test, NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN); break; case ETH_SS_STATS: for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) { memcpy(data + index * ETH_GSTRING_LEN, netxen_nic_gstrings_stats[index].stat_string, ETH_GSTRING_LEN); } break; }}static voidnetxen_nic_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 * data){ struct netxen_adapter *adapter = netdev_priv(dev); int index; for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) { char *p = (char *)adapter + netxen_nic_gstrings_stats[index].stat_offset; data[index] = (netxen_nic_gstrings_stats[index].sizeof_stat == sizeof(u64)) ? *(u64 *) p : *(u32 *) p; }}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;}struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, .get_drvinfo = netxen_nic_get_drvinfo, .get_regs_len = netxen_nic_get_regs_len, .get_regs = netxen_nic_get_regs, .get_link = ethtool_op_get_link, .get_eeprom_len = netxen_nic_get_eeprom_len, .get_eeprom = netxen_nic_get_eeprom, .set_eeprom = netxen_nic_set_eeprom, .get_ringparam = netxen_nic_get_ringparam, .get_pauseparam = netxen_nic_get_pauseparam, .set_pauseparam = netxen_nic_set_pauseparam, .set_tx_csum = ethtool_op_set_tx_csum, .set_sg = ethtool_op_set_sg, .set_tso = ethtool_op_set_tso, .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,};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?