diff options
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 194 |
1 files changed, 124 insertions, 70 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 15ba96c..e2da4d2 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -132,6 +132,7 @@ static const struct be_ethtool_stat et_rx_stats[] = { {DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */ {DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */ {DRVSTAT_RX_INFO(rx_compl)}, + {DRVSTAT_RX_INFO(rx_compl_err)}, {DRVSTAT_RX_INFO(rx_mcast_pkts)}, /* Number of page allocation failures while posting receive buffers * to HW. @@ -181,7 +182,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { #define BE_NO_LOOPBACK 0xff static void be_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) + struct ethtool_drvinfo *drvinfo) { struct be_adapter *adapter = netdev_priv(netdev); @@ -201,8 +202,7 @@ static void be_get_drvinfo(struct net_device *netdev, drvinfo->eedump_len = 0; } -static u32 -lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name) +static u32 lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name) { u32 data_read = 0, eof; u8 addn_status; @@ -212,14 +212,14 @@ lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name) memset(&data_len_cmd, 0, sizeof(data_len_cmd)); /* data_offset and data_size should be 0 to get reg len */ status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0, - file_name, &data_read, &eof, &addn_status); + file_name, &data_read, &eof, + &addn_status); return data_read; } -static int -lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, - u32 buf_len, void *buf) +static int lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, + u32 buf_len, void *buf) { struct be_dma_mem read_cmd; u32 read_len = 0, total_read_len = 0, chunk_size; @@ -229,11 +229,11 @@ lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, read_cmd.size = LANCER_READ_FILE_CHUNK; read_cmd.va = pci_alloc_consistent(adapter->pdev, read_cmd.size, - &read_cmd.dma); + &read_cmd.dma); if (!read_cmd.va) { dev_err(&adapter->pdev->dev, - "Memory allocation failure while reading dump\n"); + "Memory allocation failure while reading dump\n"); return -ENOMEM; } @@ -242,8 +242,8 @@ lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, LANCER_READ_FILE_CHUNK); chunk_size = ALIGN(chunk_size, 4); status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size, - total_read_len, file_name, &read_len, - &eof, &addn_status); + total_read_len, file_name, + &read_len, &eof, &addn_status); if (!status) { memcpy(buf + total_read_len, read_cmd.va, read_len); total_read_len += read_len; @@ -254,13 +254,12 @@ lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, } } pci_free_consistent(adapter->pdev, read_cmd.size, read_cmd.va, - read_cmd.dma); + read_cmd.dma); return status; } -static int -be_get_reg_len(struct net_device *netdev) +static int be_get_reg_len(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); u32 log_size = 0; @@ -271,7 +270,7 @@ be_get_reg_len(struct net_device *netdev) if (be_physfn(adapter)) { if (lancer_chip(adapter)) log_size = lancer_cmd_get_file_len(adapter, - LANCER_FW_DUMP_FILE); + LANCER_FW_DUMP_FILE); else be_cmd_get_reg_len(adapter, &log_size); } @@ -287,7 +286,7 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) memset(buf, 0, regs->len); if (lancer_chip(adapter)) lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE, - regs->len, buf); + regs->len, buf); else be_cmd_get_regs(adapter, regs->len, buf); } @@ -337,9 +336,8 @@ static int be_set_coalesce(struct net_device *netdev, return 0; } -static void -be_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, uint64_t *data) +static void be_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) { struct be_adapter *adapter = netdev_priv(netdev); struct be_rx_obj *rxo; @@ -390,9 +388,8 @@ be_get_ethtool_stats(struct net_device *netdev, } } -static void -be_get_stat_strings(struct net_device *netdev, uint32_t stringset, - uint8_t *data) +static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset, + uint8_t *data) { struct be_adapter *adapter = netdev_priv(netdev); int i, j; @@ -642,16 +639,15 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) adapter->rx_fc = ecmd->rx_pause; status = be_cmd_set_flow_control(adapter, - adapter->tx_fc, adapter->rx_fc); + adapter->tx_fc, adapter->rx_fc); if (status) dev_warn(&adapter->pdev->dev, "Pause param set failed.\n"); return status; } -static int -be_set_phys_id(struct net_device *netdev, - enum ethtool_phys_id_state state) +static int be_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) { struct be_adapter *adapter = netdev_priv(netdev); @@ -708,8 +704,7 @@ static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump) return status; } -static void -be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { struct be_adapter *adapter = netdev_priv(netdev); @@ -723,8 +718,7 @@ be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) memset(&wol->sopass, 0, sizeof(wol->sopass)); } -static int -be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { struct be_adapter *adapter = netdev_priv(netdev); @@ -744,8 +738,7 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) return 0; } -static int -be_test_ddr_dma(struct be_adapter *adapter) +static int be_test_ddr_dma(struct be_adapter *adapter) { int ret, i; struct be_dma_mem ddrdma_cmd; @@ -761,7 +754,7 @@ be_test_ddr_dma(struct be_adapter *adapter) for (i = 0; i < 2; i++) { ret = be_cmd_ddr_dma_test(adapter, pattern[i], - 4096, &ddrdma_cmd); + 4096, &ddrdma_cmd); if (ret != 0) goto err; } @@ -773,20 +766,17 @@ err: } static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, - u64 *status) + u64 *status) { - be_cmd_set_loopback(adapter, adapter->hba_port_num, - loopback_type, 1); + be_cmd_set_loopback(adapter, adapter->hba_port_num, loopback_type, 1); *status = be_cmd_loopback_test(adapter, adapter->hba_port_num, - loopback_type, 1500, - 2, 0xabc); - be_cmd_set_loopback(adapter, adapter->hba_port_num, - BE_NO_LOOPBACK, 1); + loopback_type, 1500, 2, 0xabc); + be_cmd_set_loopback(adapter, adapter->hba_port_num, BE_NO_LOOPBACK, 1); return *status; } -static void -be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) +static void be_self_test(struct net_device *netdev, struct ethtool_test *test, + u64 *data) { struct be_adapter *adapter = netdev_priv(netdev); int status; @@ -801,12 +791,10 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); if (test->flags & ETH_TEST_FL_OFFLINE) { - if (be_loopback_test(adapter, BE_MAC_LOOPBACK, - &data[0]) != 0) + if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0) test->flags |= ETH_TEST_FL_FAILED; - if (be_loopback_test(adapter, BE_PHY_LOOPBACK, - &data[1]) != 0) + if (be_loopback_test(adapter, BE_PHY_LOOPBACK, &data[1]) != 0) test->flags |= ETH_TEST_FL_FAILED; if (test->flags & ETH_TEST_FL_EXTERNAL_LB) { @@ -832,16 +820,14 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) } } -static int -be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) +static int be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) { struct be_adapter *adapter = netdev_priv(netdev); return be_load_fw(adapter, efl->data); } -static int -be_get_eeprom_len(struct net_device *netdev) +static int be_get_eeprom_len(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); @@ -851,18 +837,17 @@ be_get_eeprom_len(struct net_device *netdev) if (lancer_chip(adapter)) { if (be_physfn(adapter)) return lancer_cmd_get_file_len(adapter, - LANCER_VPD_PF_FILE); + LANCER_VPD_PF_FILE); else return lancer_cmd_get_file_len(adapter, - LANCER_VPD_VF_FILE); + LANCER_VPD_VF_FILE); } else { return BE_READ_SEEPROM_LEN; } } -static int -be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, - uint8_t *data) +static int be_read_eeprom(struct net_device *netdev, + struct ethtool_eeprom *eeprom, uint8_t *data) { struct be_adapter *adapter = netdev_priv(netdev); struct be_dma_mem eeprom_cmd; @@ -875,10 +860,10 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, if (lancer_chip(adapter)) { if (be_physfn(adapter)) return lancer_cmd_read_file(adapter, LANCER_VPD_PF_FILE, - eeprom->len, data); + eeprom->len, data); else return lancer_cmd_read_file(adapter, LANCER_VPD_VF_FILE, - eeprom->len, data); + eeprom->len, data); } eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16); @@ -933,27 +918,27 @@ static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type) switch (flow_type) { case TCP_V4_FLOW: - if (adapter->rss_flags & RSS_ENABLE_IPV4) + if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4) data |= RXH_IP_DST | RXH_IP_SRC; - if (adapter->rss_flags & RSS_ENABLE_TCP_IPV4) + if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV4) data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; break; case UDP_V4_FLOW: - if (adapter->rss_flags & RSS_ENABLE_IPV4) + if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4) data |= RXH_IP_DST | RXH_IP_SRC; - if (adapter->rss_flags & RSS_ENABLE_UDP_IPV4) + if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV4) data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; break; case TCP_V6_FLOW: - if (adapter->rss_flags & RSS_ENABLE_IPV6) + if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6) data |= RXH_IP_DST | RXH_IP_SRC; - if (adapter->rss_flags & RSS_ENABLE_TCP_IPV6) + if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV6) data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; break; case UDP_V6_FLOW: - if (adapter->rss_flags & RSS_ENABLE_IPV6) + if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6) data |= RXH_IP_DST | RXH_IP_SRC; - if (adapter->rss_flags & RSS_ENABLE_UDP_IPV6) + if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV6) data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; break; } @@ -962,7 +947,7 @@ static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type) } static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, - u32 *rule_locs) + u32 *rule_locs) { struct be_adapter *adapter = netdev_priv(netdev); @@ -992,7 +977,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, struct be_rx_obj *rxo; int status = 0, i, j; u8 rsstable[128]; - u32 rss_flags = adapter->rss_flags; + u32 rss_flags = adapter->rss_info.rss_flags; if (cmd->data != L3_RSS_FLAGS && cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS)) @@ -1039,7 +1024,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, return -EINVAL; } - if (rss_flags == adapter->rss_flags) + if (rss_flags == adapter->rss_info.rss_flags) return status; if (be_multi_rxq(adapter)) { @@ -1051,9 +1036,11 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, } } } - status = be_cmd_rss_config(adapter, rsstable, rss_flags, 128); + + status = be_cmd_rss_config(adapter, adapter->rss_info.rsstable, + rss_flags, 128, adapter->rss_info.rss_hkey); if (!status) - adapter->rss_flags = rss_flags; + adapter->rss_info.rss_flags = rss_flags; return status; } @@ -1103,6 +1090,69 @@ static int be_set_channels(struct net_device *netdev, return be_update_queues(adapter); } +static u32 be_get_rxfh_indir_size(struct net_device *netdev) +{ + return RSS_INDIR_TABLE_LEN; +} + +static u32 be_get_rxfh_key_size(struct net_device *netdev) +{ + return RSS_HASH_KEY_LEN; +} + +static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int i; + struct rss_info *rss = &adapter->rss_info; + + if (indir) { + for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) + indir[i] = rss->rss_queue[i]; + } + + if (hkey) + memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN); + + return 0; +} + +static int be_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *hkey) +{ + int rc = 0, i, j; + struct be_adapter *adapter = netdev_priv(netdev); + u8 rsstable[RSS_INDIR_TABLE_LEN]; + + if (indir) { + struct be_rx_obj *rxo; + for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) { + j = indir[i]; + rxo = &adapter->rx_obj[j]; + rsstable[i] = rxo->rss_id; + adapter->rss_info.rss_queue[i] = j; + } + } else { + memcpy(rsstable, adapter->rss_info.rsstable, + RSS_INDIR_TABLE_LEN); + } + + if (!hkey) + hkey = adapter->rss_info.rss_hkey; + + rc = be_cmd_rss_config(adapter, rsstable, + adapter->rss_info.rss_flags, + RSS_INDIR_TABLE_LEN, hkey); + if (rc) { + adapter->rss_info.rss_flags = RSS_ENABLE_NONE; + return -EIO; + } + memcpy(adapter->rss_info.rss_hkey, hkey, RSS_HASH_KEY_LEN); + memcpy(adapter->rss_info.rsstable, rsstable, + RSS_INDIR_TABLE_LEN); + return 0; +} + const struct ethtool_ops be_ethtool_ops = { .get_settings = be_get_settings, .get_drvinfo = be_get_drvinfo, @@ -1129,6 +1179,10 @@ const struct ethtool_ops be_ethtool_ops = { .self_test = be_self_test, .get_rxnfc = be_get_rxnfc, .set_rxnfc = be_set_rxnfc, + .get_rxfh_indir_size = be_get_rxfh_indir_size, + .get_rxfh_key_size = be_get_rxfh_key_size, + .get_rxfh = be_get_rxfh, + .set_rxfh = be_set_rxfh, .get_channels = be_get_channels, .set_channels = be_set_channels }; |