|
@@ -22,42 +22,37 @@ struct qlcnic_stats {
|
|
|
|
|
|
#define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
|
|
|
#define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
|
|
|
+static const u32 qlcnic_fw_dump_level[] = {
|
|
|
+ 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
|
|
|
+};
|
|
|
|
|
|
static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
|
|
|
- {"xmit_called",
|
|
|
- QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
|
|
|
- {"xmit_finished",
|
|
|
- QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
|
|
|
- {"rx_dropped",
|
|
|
- QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
|
|
|
- {"tx_dropped",
|
|
|
- QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
|
|
|
- {"csummed",
|
|
|
- QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
|
|
|
- {"rx_pkts",
|
|
|
- QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
|
|
|
- {"lro_pkts",
|
|
|
- QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
|
|
|
- {"rx_bytes",
|
|
|
- QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
|
|
|
- {"tx_bytes",
|
|
|
- QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
|
|
|
- {"lrobytes",
|
|
|
- QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
|
|
|
- {"lso_frames",
|
|
|
- QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
|
|
|
- {"xmit_on",
|
|
|
- QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
|
|
|
- {"xmit_off",
|
|
|
- QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
|
|
|
+ {"xmit_called", QLC_SIZEOF(stats.xmitcalled),
|
|
|
+ QLC_OFF(stats.xmitcalled)},
|
|
|
+ {"xmit_finished", QLC_SIZEOF(stats.xmitfinished),
|
|
|
+ QLC_OFF(stats.xmitfinished)},
|
|
|
+ {"rx_dropped", QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
|
|
|
+ {"tx_dropped", QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
|
|
|
+ {"csummed", QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
|
|
|
+ {"rx_pkts", QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
|
|
|
+ {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
|
|
|
+ {"rx_bytes", QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
|
|
|
+ {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
|
|
|
+ {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
|
|
|
+ {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
|
|
|
+ {"xmit_on", QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
|
|
|
+ {"xmit_off", QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
|
|
|
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
|
|
|
- QLC_OFF(stats.skb_alloc_failure)},
|
|
|
- {"null rxbuf",
|
|
|
- QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
|
|
|
+ QLC_OFF(stats.skb_alloc_failure)},
|
|
|
+ {"null rxbuf", QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
|
|
|
{"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
|
|
|
QLC_OFF(stats.rx_dma_map_error)},
|
|
|
{"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
|
|
|
QLC_OFF(stats.tx_dma_map_error)},
|
|
|
+ {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
|
|
|
+ QLC_OFF(stats.mac_filter_limit_overrun)},
|
|
|
+ {"spurious intr", QLC_SIZEOF(stats.spurious_intr),
|
|
|
+ QLC_OFF(stats.spurious_intr)},
|
|
|
|
|
|
};
|
|
|
|
|
@@ -78,7 +73,15 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
|
|
|
"tx numbytes",
|
|
|
};
|
|
|
|
|
|
-static const char qlcnic_mac_stats_strings [][ETH_GSTRING_LEN] = {
|
|
|
+static const char qlcnic_83xx_tx_stats_strings[][ETH_GSTRING_LEN] = {
|
|
|
+ "ctx_tx_bytes",
|
|
|
+ "ctx_tx_pkts",
|
|
|
+ "ctx_tx_errors",
|
|
|
+ "ctx_tx_dropped_pkts",
|
|
|
+ "ctx_tx_num_buffers",
|
|
|
+};
|
|
|
+
|
|
|
+static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = {
|
|
|
"mac_tx_frames",
|
|
|
"mac_tx_bytes",
|
|
|
"mac_tx_mcast_pkts",
|
|
@@ -110,25 +113,62 @@ static const char qlcnic_mac_stats_strings [][ETH_GSTRING_LEN] = {
|
|
|
"mac_rx_length_large",
|
|
|
"mac_rx_jabber",
|
|
|
"mac_rx_dropped",
|
|
|
- "mac_rx_crc_error",
|
|
|
+ "mac_crc_error",
|
|
|
"mac_align_error",
|
|
|
};
|
|
|
|
|
|
-#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
|
|
|
-#define QLCNIC_MAC_STATS_LEN ARRAY_SIZE(qlcnic_mac_stats_strings)
|
|
|
-#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
|
|
|
-#define QLCNIC_TOTAL_STATS_LEN QLCNIC_STATS_LEN + QLCNIC_MAC_STATS_LEN
|
|
|
+#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
|
|
|
+static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
|
|
|
+ "ctx_rx_bytes",
|
|
|
+ "ctx_rx_pkts",
|
|
|
+ "ctx_lro_pkt_cnt",
|
|
|
+ "ctx_ip_csum_error",
|
|
|
+ "ctx_rx_pkts_wo_ctx",
|
|
|
+ "ctx_rx_pkts_dropped_wo_sts",
|
|
|
+ "ctx_rx_osized_pkts",
|
|
|
+ "ctx_rx_pkts_dropped_wo_rds",
|
|
|
+ "ctx_rx_unexpected_mcast_pkts",
|
|
|
+ "ctx_invalid_mac_address",
|
|
|
+ "ctx_rx_rds_ring_prim_attemoted",
|
|
|
+ "ctx_rx_rds_ring_prim_success",
|
|
|
+ "ctx_num_lro_flows_added",
|
|
|
+ "ctx_num_lro_flows_removed",
|
|
|
+ "ctx_num_lro_flows_active",
|
|
|
+ "ctx_pkts_dropped_unknown",
|
|
|
+};
|
|
|
|
|
|
static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
|
|
|
"Register_Test_on_offline",
|
|
|
"Link_Test_on_offline",
|
|
|
"Interrupt_Test_offline",
|
|
|
"Internal_Loopback_offline",
|
|
|
- "External_Loopback_offline"
|
|
|
+ "EEPROM_Test_offline"
|
|
|
};
|
|
|
|
|
|
#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
|
|
|
|
|
|
+static inline int qlcnic_82xx_statistics(void)
|
|
|
+{
|
|
|
+ return QLCNIC_STATS_LEN + ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
|
|
|
+}
|
|
|
+
|
|
|
+static inline int qlcnic_83xx_statistics(void)
|
|
|
+{
|
|
|
+ return ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
|
|
|
+ ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
|
|
|
+ ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
|
|
|
+}
|
|
|
+
|
|
|
+static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
|
|
|
+{
|
|
|
+ if (qlcnic_82xx_check(adapter))
|
|
|
+ return qlcnic_82xx_statistics();
|
|
|
+ else if (qlcnic_83xx_check(adapter))
|
|
|
+ return qlcnic_83xx_statistics();
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
#define QLCNIC_RING_REGS_COUNT 20
|
|
|
#define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
|
|
|
#define QLCNIC_MAX_EEPROM_LEN 1024
|
|
@@ -148,6 +188,12 @@ static const u32 diag_registers[] = {
|
|
|
QLCNIC_PEG_ALIVE_COUNTER,
|
|
|
QLCNIC_PEG_HALT_STATUS1,
|
|
|
QLCNIC_PEG_HALT_STATUS2,
|
|
|
+ -1
|
|
|
+};
|
|
|
+
|
|
|
+static const u32 ext_diag_registers[] = {
|
|
|
+ CRB_XG_STATE_P3P,
|
|
|
+ ISR_INT_STATE_REG,
|
|
|
QLCNIC_CRB_PEG_NET_0+0x3c,
|
|
|
QLCNIC_CRB_PEG_NET_1+0x3c,
|
|
|
QLCNIC_CRB_PEG_NET_2+0x3c,
|
|
@@ -156,12 +202,19 @@ static const u32 diag_registers[] = {
|
|
|
};
|
|
|
|
|
|
#define QLCNIC_MGMT_API_VERSION 2
|
|
|
-#define QLCNIC_DEV_INFO_SIZE 1
|
|
|
-#define QLCNIC_ETHTOOL_REGS_VER 2
|
|
|
+#define QLCNIC_ETHTOOL_REGS_VER 3
|
|
|
+
|
|
|
static int qlcnic_get_regs_len(struct net_device *dev)
|
|
|
{
|
|
|
- return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
|
|
|
- QLCNIC_DEV_INFO_SIZE + 1;
|
|
|
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
+ u32 len;
|
|
|
+
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ len = qlcnic_83xx_get_regs_len(adapter);
|
|
|
+ else
|
|
|
+ len = sizeof(ext_diag_registers) + sizeof(diag_registers);
|
|
|
+
|
|
|
+ return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
|
|
|
}
|
|
|
|
|
|
static int qlcnic_get_eeprom_len(struct net_device *dev)
|
|
@@ -174,10 +227,9 @@ qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
|
|
|
{
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
u32 fw_major, fw_minor, fw_build;
|
|
|
-
|
|
|
- fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
|
|
|
- fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
|
|
|
- fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
|
|
|
+ fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
|
|
|
+ fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
|
|
|
+ fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
|
|
|
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
|
|
|
"%d.%d.%d", fw_major, fw_minor, fw_build);
|
|
|
|
|
@@ -192,7 +244,10 @@ static int
|
|
|
qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
{
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
+ struct qlcnic_hardware_context *ahw = adapter->ahw;
|
|
|
+ u32 speed, reg;
|
|
|
int check_sfp_module = 0;
|
|
|
+ u16 pcifn = ahw->pci_func;
|
|
|
|
|
|
/* read which mode */
|
|
|
if (adapter->ahw->port_type == QLCNIC_GBE) {
|
|
@@ -213,9 +268,12 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
ecmd->autoneg = adapter->ahw->link_autoneg;
|
|
|
|
|
|
} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
|
|
|
- u32 val;
|
|
|
+ u32 val = 0;
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ qlcnic_83xx_get_settings(adapter);
|
|
|
+ else
|
|
|
+ val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
|
|
|
|
|
|
- val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
|
|
|
if (val == QLCNIC_PORT_MODE_802_3_AP) {
|
|
|
ecmd->supported = SUPPORTED_1000baseT_Full;
|
|
|
ecmd->advertising = ADVERTISED_1000baseT_Full;
|
|
@@ -225,6 +283,12 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
}
|
|
|
|
|
|
if (netif_running(dev) && adapter->ahw->has_link_events) {
|
|
|
+ if (qlcnic_82xx_check(adapter)) {
|
|
|
+ reg = QLCRD32(adapter,
|
|
|
+ P3P_LINK_SPEED_REG(pcifn));
|
|
|
+ speed = P3P_LINK_SPEED_VAL(pcifn, reg);
|
|
|
+ ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
|
|
|
+ }
|
|
|
ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed);
|
|
|
ecmd->autoneg = adapter->ahw->link_autoneg;
|
|
|
ecmd->duplex = adapter->ahw->link_duplex;
|
|
@@ -294,6 +358,13 @@ skip:
|
|
|
ecmd->port = PORT_TP;
|
|
|
}
|
|
|
break;
|
|
|
+ case QLCNIC_BRDTYPE_83XX_10G:
|
|
|
+ ecmd->autoneg = AUTONEG_DISABLE;
|
|
|
+ ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
|
|
|
+ ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP);
|
|
|
+ ecmd->port = PORT_FIBRE;
|
|
|
+ check_sfp_module = netif_running(dev) && ahw->has_link_events;
|
|
|
+ break;
|
|
|
default:
|
|
|
dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
|
|
|
adapter->ahw->board_type);
|
|
@@ -321,16 +392,10 @@ skip:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
+static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
|
|
|
+ struct ethtool_cmd *ecmd)
|
|
|
{
|
|
|
- u32 config = 0;
|
|
|
- u32 ret = 0;
|
|
|
- struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
-
|
|
|
- if (adapter->ahw->port_type != QLCNIC_GBE)
|
|
|
- return -EOPNOTSUPP;
|
|
|
-
|
|
|
+ u32 ret = 0, config = 0;
|
|
|
/* read which mode */
|
|
|
if (ecmd->duplex)
|
|
|
config |= 0x1;
|
|
@@ -358,6 +423,24 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
return -EOPNOTSUPP;
|
|
|
else if (ret)
|
|
|
return -EIO;
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
+{
|
|
|
+ u32 ret = 0;
|
|
|
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
+
|
|
|
+ if (adapter->ahw->port_type != QLCNIC_GBE)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ ret = qlcnic_83xx_set_settings(adapter, ecmd);
|
|
|
+ else
|
|
|
+ ret = qlcnic_set_port_config(adapter, ecmd);
|
|
|
+
|
|
|
+ if (!ret)
|
|
|
+ return ret;
|
|
|
|
|
|
adapter->ahw->link_speed = ethtool_cmd_speed(ecmd);
|
|
|
adapter->ahw->link_duplex = ecmd->duplex;
|
|
@@ -370,6 +453,19 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|
|
return dev->netdev_ops->ndo_open(dev);
|
|
|
}
|
|
|
|
|
|
+static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
|
|
|
+ u32 *regs_buff)
|
|
|
+{
|
|
|
+ int i, j = 0;
|
|
|
+
|
|
|
+ for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
|
|
|
+ regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
|
|
|
+ j = 0;
|
|
|
+ while (ext_diag_registers[j] != -1)
|
|
|
+ regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++]);
|
|
|
+ return i;
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
|
|
|
{
|
|
@@ -377,17 +473,20 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
|
|
|
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
|
|
|
struct qlcnic_host_sds_ring *sds_ring;
|
|
|
u32 *regs_buff = p;
|
|
|
- int ring, i = 0, j = 0;
|
|
|
+ int ring, i = 0;
|
|
|
|
|
|
memset(p, 0, qlcnic_get_regs_len(dev));
|
|
|
+
|
|
|
regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
|
|
|
(adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
|
|
|
|
|
|
regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
|
|
|
regs_buff[1] = QLCNIC_MGMT_API_VERSION;
|
|
|
|
|
|
- for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
|
|
|
- regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
|
|
|
+ if (qlcnic_82xx_check(adapter))
|
|
|
+ i = qlcnic_82xx_get_registers(adapter, regs_buff);
|
|
|
+ else
|
|
|
+ i = qlcnic_83xx_get_registers(adapter, regs_buff);
|
|
|
|
|
|
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
|
|
|
return;
|
|
@@ -415,6 +514,10 @@ static u32 qlcnic_test_link(struct net_device *dev)
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
u32 val;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ val = qlcnic_83xx_test_link(adapter);
|
|
|
+ return (val & 1) ? 0 : 1;
|
|
|
+ }
|
|
|
val = QLCRD32(adapter, CRB_XG_STATE_P3P);
|
|
|
val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
|
|
|
return (val == XG_LINK_UP_P3P) ? 0 : 1;
|
|
@@ -426,8 +529,10 @@ qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
|
|
|
{
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
int offset;
|
|
|
- int ret;
|
|
|
+ int ret = -1;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ return 0;
|
|
|
if (eeprom->len == 0)
|
|
|
return -EINVAL;
|
|
|
|
|
@@ -435,8 +540,9 @@ qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
|
|
|
((adapter->pdev)->device << 16);
|
|
|
offset = eeprom->offset;
|
|
|
|
|
|
- ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
|
|
|
- eeprom->len);
|
|
|
+ if (qlcnic_82xx_check(adapter))
|
|
|
+ ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
|
|
|
+ eeprom->len);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
@@ -547,6 +653,10 @@ qlcnic_get_pauseparam(struct net_device *netdev,
|
|
|
int port = adapter->ahw->physical_port;
|
|
|
__u32 val;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ qlcnic_83xx_get_pauseparam(adapter, pause);
|
|
|
+ return;
|
|
|
+ }
|
|
|
if (adapter->ahw->port_type == QLCNIC_GBE) {
|
|
|
if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
|
|
|
return;
|
|
@@ -592,6 +702,9 @@ qlcnic_set_pauseparam(struct net_device *netdev,
|
|
|
int port = adapter->ahw->physical_port;
|
|
|
__u32 val;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ return qlcnic_83xx_set_pauseparam(adapter, pause);
|
|
|
+
|
|
|
/* read mode */
|
|
|
if (adapter->ahw->port_type == QLCNIC_GBE) {
|
|
|
if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
|
|
@@ -606,6 +719,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
|
|
|
|
|
|
QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
|
|
|
val);
|
|
|
+ QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
|
|
|
/* set autoneg */
|
|
|
val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
|
|
|
switch (port) {
|
|
@@ -668,6 +782,9 @@ static int qlcnic_reg_test(struct net_device *dev)
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
u32 data_read;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ return qlcnic_83xx_reg_test(adapter);
|
|
|
+
|
|
|
data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
|
|
|
if ((data_read & 0xffff) != adapter->pdev->vendor)
|
|
|
return 1;
|
|
@@ -675,16 +792,30 @@ static int qlcnic_reg_test(struct net_device *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int qlcnic_eeprom_test(struct net_device *dev)
|
|
|
+{
|
|
|
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
+
|
|
|
+ if (qlcnic_82xx_check(adapter))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return qlcnic_83xx_flash_test(adapter);
|
|
|
+}
|
|
|
+
|
|
|
static int qlcnic_get_sset_count(struct net_device *dev, int sset)
|
|
|
{
|
|
|
+ int len;
|
|
|
+
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
switch (sset) {
|
|
|
case ETH_SS_TEST:
|
|
|
return QLCNIC_TEST_LEN;
|
|
|
case ETH_SS_STATS:
|
|
|
- if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
|
|
|
- return QLCNIC_TOTAL_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
|
|
|
- return QLCNIC_TOTAL_STATS_LEN;
|
|
|
+ len = qlcnic_dev_statistics_len(adapter) + QLCNIC_STATS_LEN;
|
|
|
+ if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
|
|
|
+ qlcnic_83xx_check(adapter))
|
|
|
+ return len;
|
|
|
+ return qlcnic_82xx_statistics();
|
|
|
default:
|
|
|
return -EOPNOTSUPP;
|
|
|
}
|
|
@@ -707,8 +838,12 @@ static int qlcnic_irq_test(struct net_device *netdev)
|
|
|
adapter->ahw->diag_cnt = 0;
|
|
|
qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
|
|
|
|
|
|
- cmd.req.arg[1] = adapter->ahw->pci_func;
|
|
|
- ret = qlcnic_issue_cmd(adapter, &cmd);
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ ret = qlcnic_83xx_interrupt_test(adapter, &cmd);
|
|
|
+ } else {
|
|
|
+ cmd.req.arg[1] = adapter->ahw->pci_func;
|
|
|
+ ret = qlcnic_issue_cmd(adapter, &cmd);
|
|
|
+ }
|
|
|
|
|
|
if (ret)
|
|
|
goto done;
|
|
@@ -760,11 +895,10 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
|
|
|
skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
|
|
|
qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
|
|
|
skb_put(skb, QLCNIC_ILB_PKT_SIZE);
|
|
|
-
|
|
|
adapter->ahw->diag_cnt = 0;
|
|
|
qlcnic_xmit_frame(skb, adapter->netdev);
|
|
|
-
|
|
|
loop = 0;
|
|
|
+
|
|
|
do {
|
|
|
msleep(1);
|
|
|
qlcnic_process_rcv_ring_diag(sds_ring);
|
|
@@ -775,18 +909,18 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
|
|
|
dev_kfree_skb_any(skb);
|
|
|
|
|
|
if (!adapter->ahw->diag_cnt)
|
|
|
- QLCDB(adapter, DRV,
|
|
|
- "LB Test: packet #%d was not received\n", i + 1);
|
|
|
+ dev_warn(&adapter->pdev->dev,
|
|
|
+ "LB Test: packet #%d was not received\n",
|
|
|
+ i + 1);
|
|
|
else
|
|
|
cnt++;
|
|
|
}
|
|
|
if (cnt != i) {
|
|
|
- dev_warn(&adapter->pdev->dev, "LB Test failed\n");
|
|
|
- if (mode != QLCNIC_ILB_MODE) {
|
|
|
+ dev_err(&adapter->pdev->dev,
|
|
|
+ "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
|
|
|
+ if (mode != QLCNIC_ILB_MODE)
|
|
|
dev_warn(&adapter->pdev->dev,
|
|
|
- "WARNING: Please make sure external"
|
|
|
- "loopback connector is plugged in\n");
|
|
|
- }
|
|
|
+ "WARNING: Please check loopback cable\n");
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
@@ -797,20 +931,23 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(netdev);
|
|
|
int max_sds_rings = adapter->max_sds_rings;
|
|
|
struct qlcnic_host_sds_ring *sds_ring;
|
|
|
+ struct qlcnic_hardware_context *ahw = adapter->ahw;
|
|
|
int loop = 0;
|
|
|
int ret;
|
|
|
|
|
|
- if (!(adapter->ahw->capabilities &
|
|
|
- QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
|
|
|
- netdev_info(netdev, "Firmware is not loopback test capable\n");
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ goto skip_cap;
|
|
|
+ if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
|
|
|
+ dev_info(&adapter->pdev->dev,
|
|
|
+ "Firmware do not support loopback test\n");
|
|
|
return -EOPNOTSUPP;
|
|
|
}
|
|
|
-
|
|
|
- QLCDB(adapter, DRV, "%s loopback test in progress\n",
|
|
|
- mode == QLCNIC_ILB_MODE ? "internal" : "external");
|
|
|
- if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
|
|
|
- netdev_warn(netdev, "Loopback test not supported for non "
|
|
|
- "privilege function\n");
|
|
|
+skip_cap:
|
|
|
+ dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
|
|
|
+ mode == QLCNIC_ILB_MODE ? "internal" : "external");
|
|
|
+ if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
|
|
|
+ dev_warn(&adapter->pdev->dev,
|
|
|
+ "Loopback test not supported in nonprivileged mode\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -822,12 +959,14 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
|
|
|
goto clear_it;
|
|
|
|
|
|
sds_ring = &adapter->recv_ctx->sds_rings[0];
|
|
|
-
|
|
|
ret = qlcnic_set_lb_mode(adapter, mode);
|
|
|
if (ret)
|
|
|
goto free_res;
|
|
|
|
|
|
- adapter->ahw->diag_cnt = 0;
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ goto skip_fw_msg;
|
|
|
+
|
|
|
+ ahw->diag_cnt = 0;
|
|
|
do {
|
|
|
msleep(500);
|
|
|
qlcnic_process_rcv_ring_diag(sds_ring);
|
|
@@ -840,10 +979,22 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
|
|
|
ret = adapter->ahw->diag_cnt;
|
|
|
goto free_res;
|
|
|
}
|
|
|
- } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
|
|
|
-
|
|
|
+ } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
|
|
|
+skip_fw_msg:
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ /* wait until firmware report link up before running traffic */
|
|
|
+ loop = 0;
|
|
|
+ do {
|
|
|
+ msleep(500);
|
|
|
+ if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
|
|
|
+ dev_info(&adapter->pdev->dev,
|
|
|
+ "No linkup event after LB req\n");
|
|
|
+ ret = -QLCNIC_FW_NOT_RESPOND;
|
|
|
+ goto free_res;
|
|
|
+ }
|
|
|
+ } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
|
|
|
+ }
|
|
|
ret = qlcnic_do_lb_test(adapter, mode);
|
|
|
-
|
|
|
qlcnic_clear_lb_mode(adapter, mode);
|
|
|
|
|
|
free_res:
|
|
@@ -877,20 +1028,18 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
|
|
|
data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
|
|
|
if (data[3])
|
|
|
eth_test->flags |= ETH_TEST_FL_FAILED;
|
|
|
- if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
|
|
|
- data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
|
|
|
- if (data[4])
|
|
|
- eth_test->flags |= ETH_TEST_FL_FAILED;
|
|
|
- eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
|
|
|
- }
|
|
|
+
|
|
|
+ data[4] = qlcnic_eeprom_test(dev);
|
|
|
+ if (data[4])
|
|
|
+ eth_test->flags |= ETH_TEST_FL_FAILED;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
|
|
|
+qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
|
|
{
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
- int index, i, j;
|
|
|
+ int index, i, num_stats;
|
|
|
|
|
|
switch (stringset) {
|
|
|
case ETH_SS_TEST:
|
|
@@ -903,14 +1052,34 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
|
|
|
qlcnic_gstrings_stats[index].stat_string,
|
|
|
ETH_GSTRING_LEN);
|
|
|
}
|
|
|
- for (j = 0; j < QLCNIC_MAC_STATS_LEN; index++, j++) {
|
|
|
- memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
- qlcnic_mac_stats_strings[j],
|
|
|
- ETH_GSTRING_LEN);
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
|
|
|
+ for (i = 0; i < num_stats; i++, index++)
|
|
|
+ memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
+ qlcnic_83xx_tx_stats_strings[i],
|
|
|
+ ETH_GSTRING_LEN);
|
|
|
+ num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
|
|
|
+ for (i = 0; i < num_stats; i++, index++)
|
|
|
+ memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
+ qlcnic_83xx_mac_stats_strings[i],
|
|
|
+ ETH_GSTRING_LEN);
|
|
|
+ num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
|
|
|
+ for (i = 0; i < num_stats; i++, index++)
|
|
|
+ memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
+ qlcnic_83xx_rx_stats_strings[i],
|
|
|
+ ETH_GSTRING_LEN);
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
|
|
|
+ for (i = 0; i < num_stats; i++, index++)
|
|
|
+ memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
+ qlcnic_83xx_mac_stats_strings[i],
|
|
|
+ ETH_GSTRING_LEN);
|
|
|
}
|
|
|
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
|
|
|
return;
|
|
|
- for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
|
|
|
+ num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
|
|
|
+ for (i = 0; i < num_stats; index++, i++) {
|
|
|
memcpy(data + index * ETH_GSTRING_LEN,
|
|
|
qlcnic_device_gstrings_stats[i],
|
|
|
ETH_GSTRING_LEN);
|
|
@@ -919,89 +1088,84 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-qlcnic_fill_stats(int *index, u64 *data, void *stats, int type)
|
|
|
+qlcnic_fill_stats(u64 *data, void *stats, int type)
|
|
|
{
|
|
|
- int ind = *index;
|
|
|
-
|
|
|
if (type == QLCNIC_MAC_STATS) {
|
|
|
struct qlcnic_mac_statistics *mac_stats =
|
|
|
(struct qlcnic_mac_statistics *)stats;
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
|
|
|
- data[ind++] =
|
|
|
- QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
|
|
|
} else if (type == QLCNIC_ESW_STATS) {
|
|
|
struct __qlcnic_esw_statistics *esw_stats =
|
|
|
(struct __qlcnic_esw_statistics *)stats;
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->errors);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->local_frames);
|
|
|
- data[ind++] = QLCNIC_FILL_STATS(esw_stats->numbytes);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
|
|
|
+ *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
|
|
|
}
|
|
|
-
|
|
|
- *index = ind;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-qlcnic_get_ethtool_stats(struct net_device *dev,
|
|
|
- struct ethtool_stats *stats, u64 * data)
|
|
|
+static void qlcnic_get_ethtool_stats(struct net_device *dev,
|
|
|
+ struct ethtool_stats *stats, u64 *data)
|
|
|
{
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
struct qlcnic_esw_statistics port_stats;
|
|
|
struct qlcnic_mac_statistics mac_stats;
|
|
|
- int index, ret;
|
|
|
-
|
|
|
- for (index = 0; index < QLCNIC_STATS_LEN; index++) {
|
|
|
- char *p =
|
|
|
- (char *)adapter +
|
|
|
- qlcnic_gstrings_stats[index].stat_offset;
|
|
|
- data[index] =
|
|
|
- (qlcnic_gstrings_stats[index].sizeof_stat ==
|
|
|
- sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
|
|
|
+ int index, ret, length, size;
|
|
|
+ char *p;
|
|
|
+
|
|
|
+ memset(data, 0, stats->n_stats * sizeof(u64));
|
|
|
+ length = QLCNIC_STATS_LEN;
|
|
|
+ for (index = 0; index < length; index++) {
|
|
|
+ p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
|
|
|
+ size = qlcnic_gstrings_stats[index].sizeof_stat;
|
|
|
+ *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
|
|
|
}
|
|
|
|
|
|
- /* Retrieve MAC statistics from firmware */
|
|
|
- memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
|
|
|
- qlcnic_get_mac_stats(adapter, &mac_stats);
|
|
|
- qlcnic_fill_stats(&index, data, &mac_stats, QLCNIC_MAC_STATS);
|
|
|
+ if (qlcnic_83xx_check(adapter)) {
|
|
|
+ if (adapter->ahw->linkup)
|
|
|
+ qlcnic_83xx_get_stats(adapter, data);
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ /* Retrieve MAC statistics from firmware */
|
|
|
+ memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
|
|
|
+ qlcnic_get_mac_stats(adapter, &mac_stats);
|
|
|
+ qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
|
|
|
+ }
|
|
|
|
|
|
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
|
|
|
return;
|
|
@@ -1012,14 +1176,13 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
|
|
|
if (ret)
|
|
|
return;
|
|
|
|
|
|
- qlcnic_fill_stats(&index, data, &port_stats.rx, QLCNIC_ESW_STATS);
|
|
|
-
|
|
|
+ qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
|
|
|
ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
|
|
|
QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
|
|
|
if (ret)
|
|
|
return;
|
|
|
|
|
|
- qlcnic_fill_stats(&index, data, &port_stats.tx, QLCNIC_ESW_STATS);
|
|
|
+ qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
|
|
|
}
|
|
|
|
|
|
static int qlcnic_set_led(struct net_device *dev,
|
|
@@ -1029,6 +1192,8 @@ static int qlcnic_set_led(struct net_device *dev,
|
|
|
int max_sds_rings = adapter->max_sds_rings;
|
|
|
int err = -EIO, active = 1;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
|
|
|
netdev_warn(dev, "LED test not supported for non "
|
|
|
"privilege function\n");
|
|
@@ -1095,6 +1260,8 @@ qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
u32 wol_cfg;
|
|
|
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
+ return;
|
|
|
wol->supported = 0;
|
|
|
wol->wolopts = 0;
|
|
|
|
|
@@ -1113,8 +1280,10 @@ qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|
|
struct qlcnic_adapter *adapter = netdev_priv(dev);
|
|
|
u32 wol_cfg;
|
|
|
|
|
|
- if (wol->wolopts & ~WAKE_MAGIC)
|
|
|
+ if (qlcnic_83xx_check(adapter))
|
|
|
return -EOPNOTSUPP;
|
|
|
+ if (wol->wolopts & ~WAKE_MAGIC)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
|
|
|
if (!(wol_cfg & (1 << adapter->portnum)))
|
|
@@ -1306,7 +1475,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
|
|
|
return 0;
|
|
|
}
|
|
|
netdev_info(netdev, "Forcing a FW dump\n");
|
|
|
- qlcnic_dev_request_reset(adapter, 0);
|
|
|
+ qlcnic_dev_request_reset(adapter, val->flag);
|
|
|
break;
|
|
|
case QLCNIC_DISABLE_FW_DUMP:
|
|
|
if (fw_dump->enable && fw_dump->tmpl_hdr) {
|
|
@@ -1326,7 +1495,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
|
|
|
return 0;
|
|
|
case QLCNIC_FORCE_FW_RESET:
|
|
|
netdev_info(netdev, "Forcing a FW reset\n");
|
|
|
- qlcnic_dev_request_reset(adapter, 0);
|
|
|
+ qlcnic_dev_request_reset(adapter, val->flag);
|
|
|
adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
|
|
|
return 0;
|
|
|
case QLCNIC_SET_QUIESCENT:
|
|
@@ -1340,8 +1509,8 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
|
|
|
netdev_err(netdev, "FW dump not supported\n");
|
|
|
return -ENOTSUPP;
|
|
|
}
|
|
|
- for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) {
|
|
|
- if (val->flag == FW_DUMP_LEVELS[i]) {
|
|
|
+ for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
|
|
|
+ if (val->flag == qlcnic_fw_dump_level[i]) {
|
|
|
fw_dump->tmpl_hdr->drv_cap_mask =
|
|
|
val->flag;
|
|
|
netdev_info(netdev, "Driver mask changed to: 0x%x\n",
|
|
@@ -1385,10 +1554,3 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
|
|
|
.get_dump_data = qlcnic_get_dump_data,
|
|
|
.set_dump = qlcnic_set_dump,
|
|
|
};
|
|
|
-
|
|
|
-const struct ethtool_ops qlcnic_ethtool_failed_ops = {
|
|
|
- .get_settings = qlcnic_get_settings,
|
|
|
- .get_drvinfo = qlcnic_get_drvinfo,
|
|
|
- .set_msglevel = qlcnic_set_msglevel,
|
|
|
- .get_msglevel = qlcnic_get_msglevel,
|
|
|
-};
|