0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/types.h>
0009 #include <linux/delay.h>
0010 #include <linux/pci.h>
0011 #include <asm/io.h>
0012 #include <linux/netdevice.h>
0013 #include <linux/ethtool.h>
0014
0015 #include "netxen_nic.h"
0016 #include "netxen_nic_hw.h"
0017
0018 struct netxen_nic_stats {
0019 char stat_string[ETH_GSTRING_LEN];
0020 int sizeof_stat;
0021 int stat_offset;
0022 };
0023
0024 #define NETXEN_NIC_STAT(m) sizeof(((struct netxen_adapter *)0)->m), \
0025 offsetof(struct netxen_adapter, m)
0026
0027 #define NETXEN_NIC_PORT_WINDOW 0x10000
0028 #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
0029
0030 static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
0031 {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
0032 {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
0033 {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
0034 {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
0035 {"csummed", NETXEN_NIC_STAT(stats.csummed)},
0036 {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
0037 {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
0038 {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
0039 {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
0040 };
0041
0042 #define NETXEN_NIC_STATS_LEN ARRAY_SIZE(netxen_nic_gstrings_stats)
0043
0044 static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
0045 "Register_Test_on_offline",
0046 "Link_Test_on_offline"
0047 };
0048
0049 #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test)
0050
0051 #define NETXEN_NIC_REGS_COUNT 30
0052 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
0053 #define NETXEN_MAX_EEPROM_LEN 1024
0054
0055 static int netxen_nic_get_eeprom_len(struct net_device *dev)
0056 {
0057 return NETXEN_FLASH_TOTAL_SIZE;
0058 }
0059
0060 static void
0061 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
0062 {
0063 struct netxen_adapter *adapter = netdev_priv(dev);
0064 u32 fw_major = 0;
0065 u32 fw_minor = 0;
0066 u32 fw_build = 0;
0067
0068 strlcpy(drvinfo->driver, netxen_nic_driver_name,
0069 sizeof(drvinfo->driver));
0070 strlcpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID,
0071 sizeof(drvinfo->version));
0072 fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
0073 fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
0074 fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
0075 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
0076 "%d.%d.%d", fw_major, fw_minor, fw_build);
0077
0078 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
0079 sizeof(drvinfo->bus_info));
0080 }
0081
0082 static int
0083 netxen_nic_get_link_ksettings(struct net_device *dev,
0084 struct ethtool_link_ksettings *cmd)
0085 {
0086 struct netxen_adapter *adapter = netdev_priv(dev);
0087 int check_sfp_module = 0;
0088 u32 supported, advertising;
0089
0090
0091 if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
0092 supported = (SUPPORTED_10baseT_Half |
0093 SUPPORTED_10baseT_Full |
0094 SUPPORTED_100baseT_Half |
0095 SUPPORTED_100baseT_Full |
0096 SUPPORTED_1000baseT_Half |
0097 SUPPORTED_1000baseT_Full);
0098
0099 advertising = (ADVERTISED_100baseT_Half |
0100 ADVERTISED_100baseT_Full |
0101 ADVERTISED_1000baseT_Half |
0102 ADVERTISED_1000baseT_Full);
0103
0104 cmd->base.port = PORT_TP;
0105
0106 cmd->base.speed = adapter->link_speed;
0107 cmd->base.duplex = adapter->link_duplex;
0108 cmd->base.autoneg = adapter->link_autoneg;
0109
0110 } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
0111 u32 val;
0112
0113 val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
0114 if (val == NETXEN_PORT_MODE_802_3_AP) {
0115 supported = SUPPORTED_1000baseT_Full;
0116 advertising = ADVERTISED_1000baseT_Full;
0117 } else {
0118 supported = SUPPORTED_10000baseT_Full;
0119 advertising = ADVERTISED_10000baseT_Full;
0120 }
0121
0122 if (netif_running(dev) && adapter->has_link_events) {
0123 cmd->base.speed = adapter->link_speed;
0124 cmd->base.autoneg = adapter->link_autoneg;
0125 cmd->base.duplex = adapter->link_duplex;
0126 goto skip;
0127 }
0128
0129 cmd->base.port = PORT_TP;
0130
0131 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
0132 u16 pcifn = adapter->ahw.pci_func;
0133
0134 val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
0135 cmd->base.speed = P3_LINK_SPEED_MHZ *
0136 P3_LINK_SPEED_VAL(pcifn, val);
0137 } else
0138 cmd->base.speed = SPEED_10000;
0139
0140 cmd->base.duplex = DUPLEX_FULL;
0141 cmd->base.autoneg = AUTONEG_DISABLE;
0142 } else
0143 return -EIO;
0144
0145 skip:
0146 cmd->base.phy_address = adapter->physical_port;
0147
0148 switch (adapter->ahw.board_type) {
0149 case NETXEN_BRDTYPE_P2_SB35_4G:
0150 case NETXEN_BRDTYPE_P2_SB31_2G:
0151 case NETXEN_BRDTYPE_P3_REF_QG:
0152 case NETXEN_BRDTYPE_P3_4_GB:
0153 case NETXEN_BRDTYPE_P3_4_GB_MM:
0154 supported |= SUPPORTED_Autoneg;
0155 advertising |= ADVERTISED_Autoneg;
0156 fallthrough;
0157 case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
0158 case NETXEN_BRDTYPE_P3_10G_CX4:
0159 case NETXEN_BRDTYPE_P3_10G_CX4_LP:
0160 case NETXEN_BRDTYPE_P3_10000_BASE_T:
0161 supported |= SUPPORTED_TP;
0162 advertising |= ADVERTISED_TP;
0163 cmd->base.port = PORT_TP;
0164 cmd->base.autoneg = (adapter->ahw.board_type ==
0165 NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
0166 (AUTONEG_DISABLE) : (adapter->link_autoneg);
0167 break;
0168 case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
0169 case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
0170 case NETXEN_BRDTYPE_P3_IMEZ:
0171 case NETXEN_BRDTYPE_P3_XG_LOM:
0172 case NETXEN_BRDTYPE_P3_HMEZ:
0173 supported |= SUPPORTED_MII;
0174 advertising |= ADVERTISED_MII;
0175 cmd->base.port = PORT_MII;
0176 cmd->base.autoneg = AUTONEG_DISABLE;
0177 break;
0178 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
0179 case NETXEN_BRDTYPE_P3_10G_SFP_CT:
0180 case NETXEN_BRDTYPE_P3_10G_SFP_QT:
0181 advertising |= ADVERTISED_TP;
0182 supported |= SUPPORTED_TP;
0183 check_sfp_module = netif_running(dev) &&
0184 adapter->has_link_events;
0185 fallthrough;
0186 case NETXEN_BRDTYPE_P2_SB31_10G:
0187 case NETXEN_BRDTYPE_P3_10G_XFP:
0188 supported |= SUPPORTED_FIBRE;
0189 advertising |= ADVERTISED_FIBRE;
0190 cmd->base.port = PORT_FIBRE;
0191 cmd->base.autoneg = AUTONEG_DISABLE;
0192 break;
0193 case NETXEN_BRDTYPE_P3_10G_TP:
0194 if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
0195 cmd->base.autoneg = AUTONEG_DISABLE;
0196 supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
0197 advertising |=
0198 (ADVERTISED_FIBRE | ADVERTISED_TP);
0199 cmd->base.port = PORT_FIBRE;
0200 check_sfp_module = netif_running(dev) &&
0201 adapter->has_link_events;
0202 } else {
0203 supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
0204 advertising |=
0205 (ADVERTISED_TP | ADVERTISED_Autoneg);
0206 cmd->base.port = PORT_TP;
0207 }
0208 break;
0209 default:
0210 printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
0211 adapter->ahw.board_type);
0212 return -EIO;
0213 }
0214
0215 if (check_sfp_module) {
0216 switch (adapter->module_type) {
0217 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
0218 case LINKEVENT_MODULE_OPTICAL_SRLR:
0219 case LINKEVENT_MODULE_OPTICAL_LRM:
0220 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
0221 cmd->base.port = PORT_FIBRE;
0222 break;
0223 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
0224 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
0225 case LINKEVENT_MODULE_TWINAX:
0226 cmd->base.port = PORT_TP;
0227 break;
0228 default:
0229 cmd->base.port = -1;
0230 }
0231 }
0232
0233 if (!netif_running(dev) || !adapter->ahw.linkup) {
0234 cmd->base.duplex = DUPLEX_UNKNOWN;
0235 cmd->base.speed = SPEED_UNKNOWN;
0236 }
0237
0238 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
0239 supported);
0240 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
0241 advertising);
0242
0243 return 0;
0244 }
0245
0246 static int
0247 netxen_nic_set_link_ksettings(struct net_device *dev,
0248 const struct ethtool_link_ksettings *cmd)
0249 {
0250 struct netxen_adapter *adapter = netdev_priv(dev);
0251 u32 speed = cmd->base.speed;
0252 int ret;
0253
0254 if (adapter->ahw.port_type != NETXEN_NIC_GBE)
0255 return -EOPNOTSUPP;
0256
0257 if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
0258 return -EOPNOTSUPP;
0259
0260 ret = nx_fw_cmd_set_gbe_port(adapter, speed, cmd->base.duplex,
0261 cmd->base.autoneg);
0262 if (ret == NX_RCODE_NOT_SUPPORTED)
0263 return -EOPNOTSUPP;
0264 else if (ret)
0265 return -EIO;
0266
0267 adapter->link_speed = speed;
0268 adapter->link_duplex = cmd->base.duplex;
0269 adapter->link_autoneg = cmd->base.autoneg;
0270
0271 if (!netif_running(dev))
0272 return 0;
0273
0274 dev->netdev_ops->ndo_stop(dev);
0275 return dev->netdev_ops->ndo_open(dev);
0276 }
0277
0278 static int netxen_nic_get_regs_len(struct net_device *dev)
0279 {
0280 return NETXEN_NIC_REGS_LEN;
0281 }
0282
0283 static void
0284 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
0285 {
0286 struct netxen_adapter *adapter = netdev_priv(dev);
0287 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
0288 struct nx_host_sds_ring *sds_ring;
0289 u32 *regs_buff = p;
0290 int ring, i = 0;
0291 int port = adapter->physical_port;
0292
0293 memset(p, 0, NETXEN_NIC_REGS_LEN);
0294
0295 regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
0296 (adapter->pdev)->device;
0297
0298 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
0299 return;
0300
0301 regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
0302 regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
0303 regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
0304 regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
0305 regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
0306 regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
0307 regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
0308 regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
0309 regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
0310
0311 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
0312 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
0313 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
0314 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
0315
0316 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
0317
0318 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
0319 i += 2;
0320
0321 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
0322 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
0323
0324 } else {
0325 i++;
0326
0327 regs_buff[i++] = NXRD32(adapter,
0328 NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
0329 regs_buff[i++] = NXRD32(adapter,
0330 NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
0331
0332 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
0333 regs_buff[i++] = NXRDIO(adapter,
0334 adapter->tx_ring->crb_cmd_consumer);
0335 }
0336
0337 regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
0338
0339 regs_buff[i++] = NXRDIO(adapter,
0340 recv_ctx->rds_rings[0].crb_rcv_producer);
0341 regs_buff[i++] = NXRDIO(adapter,
0342 recv_ctx->rds_rings[1].crb_rcv_producer);
0343
0344 regs_buff[i++] = adapter->max_sds_rings;
0345
0346 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
0347 sds_ring = &(recv_ctx->sds_rings[ring]);
0348 regs_buff[i++] = NXRDIO(adapter,
0349 sds_ring->crb_sts_consumer);
0350 }
0351 }
0352
0353 static u32 netxen_nic_test_link(struct net_device *dev)
0354 {
0355 struct netxen_adapter *adapter = netdev_priv(dev);
0356 u32 val, port;
0357
0358 port = adapter->physical_port;
0359 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
0360 val = NXRD32(adapter, CRB_XG_STATE_P3);
0361 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
0362 return (val == XG_LINK_UP_P3) ? 0 : 1;
0363 } else {
0364 val = NXRD32(adapter, CRB_XG_STATE);
0365 val = (val >> port*8) & 0xff;
0366 return (val == XG_LINK_UP) ? 0 : 1;
0367 }
0368 }
0369
0370 static int
0371 netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
0372 u8 *bytes)
0373 {
0374 struct netxen_adapter *adapter = netdev_priv(dev);
0375 int offset;
0376 int ret;
0377
0378 if (eeprom->len == 0)
0379 return -EINVAL;
0380
0381 eeprom->magic = (adapter->pdev)->vendor |
0382 ((adapter->pdev)->device << 16);
0383 offset = eeprom->offset;
0384
0385 ret = netxen_rom_fast_read_words(adapter, offset, bytes,
0386 eeprom->len);
0387 if (ret < 0)
0388 return ret;
0389
0390 return 0;
0391 }
0392
0393 static void
0394 netxen_nic_get_ringparam(struct net_device *dev,
0395 struct ethtool_ringparam *ring,
0396 struct kernel_ethtool_ringparam *kernel_ring,
0397 struct netlink_ext_ack *extack)
0398 {
0399 struct netxen_adapter *adapter = netdev_priv(dev);
0400
0401 ring->rx_pending = adapter->num_rxd;
0402 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
0403 ring->rx_jumbo_pending += adapter->num_lro_rxd;
0404 ring->tx_pending = adapter->num_txd;
0405
0406 if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
0407 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
0408 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
0409 } else {
0410 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
0411 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
0412 }
0413
0414 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
0415 }
0416
0417 static u32
0418 netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
0419 {
0420 u32 num_desc;
0421 num_desc = max(val, min);
0422 num_desc = min(num_desc, max);
0423 num_desc = roundup_pow_of_two(num_desc);
0424
0425 if (val != num_desc) {
0426 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
0427 netxen_nic_driver_name, r_name, num_desc, val);
0428 }
0429
0430 return num_desc;
0431 }
0432
0433 static int
0434 netxen_nic_set_ringparam(struct net_device *dev,
0435 struct ethtool_ringparam *ring,
0436 struct kernel_ethtool_ringparam *kernel_ring,
0437 struct netlink_ext_ack *extack)
0438 {
0439 struct netxen_adapter *adapter = netdev_priv(dev);
0440 u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
0441 u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
0442 u16 num_rxd, num_jumbo_rxd, num_txd;
0443
0444 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
0445 return -EOPNOTSUPP;
0446
0447 if (ring->rx_mini_pending)
0448 return -EOPNOTSUPP;
0449
0450 if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
0451 max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
0452 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
0453 }
0454
0455 num_rxd = netxen_validate_ringparam(ring->rx_pending,
0456 MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
0457
0458 num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
0459 MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
0460
0461 num_txd = netxen_validate_ringparam(ring->tx_pending,
0462 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
0463
0464 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
0465 num_jumbo_rxd == adapter->num_jumbo_rxd)
0466 return 0;
0467
0468 adapter->num_rxd = num_rxd;
0469 adapter->num_jumbo_rxd = num_jumbo_rxd;
0470 adapter->num_txd = num_txd;
0471
0472 return netxen_nic_reset_context(adapter);
0473 }
0474
0475 static void
0476 netxen_nic_get_pauseparam(struct net_device *dev,
0477 struct ethtool_pauseparam *pause)
0478 {
0479 struct netxen_adapter *adapter = netdev_priv(dev);
0480 __u32 val;
0481 int port = adapter->physical_port;
0482
0483 pause->autoneg = 0;
0484
0485 if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
0486 if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
0487 return;
0488
0489 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
0490 pause->rx_pause = netxen_gb_get_rx_flowctl(val);
0491 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
0492 switch (port) {
0493 case 0:
0494 pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
0495 break;
0496 case 1:
0497 pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
0498 break;
0499 case 2:
0500 pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
0501 break;
0502 case 3:
0503 default:
0504 pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
0505 break;
0506 }
0507 } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
0508 if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))
0509 return;
0510 pause->rx_pause = 1;
0511 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
0512 if (port == 0)
0513 pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
0514 else
0515 pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
0516 } else {
0517 printk(KERN_ERR"%s: Unknown board type: %x\n",
0518 netxen_nic_driver_name, adapter->ahw.port_type);
0519 }
0520 }
0521
0522 static int
0523 netxen_nic_set_pauseparam(struct net_device *dev,
0524 struct ethtool_pauseparam *pause)
0525 {
0526 struct netxen_adapter *adapter = netdev_priv(dev);
0527 __u32 val;
0528 int port = adapter->physical_port;
0529
0530
0531 if (pause->autoneg)
0532 return -EINVAL;
0533
0534
0535 if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
0536 if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
0537 return -EIO;
0538
0539 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
0540
0541 if (pause->rx_pause)
0542 netxen_gb_rx_flowctl(val);
0543 else
0544 netxen_gb_unset_rx_flowctl(val);
0545
0546 NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
0547 val);
0548
0549 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
0550 switch (port) {
0551 case 0:
0552 if (pause->tx_pause)
0553 netxen_gb_unset_gb0_mask(val);
0554 else
0555 netxen_gb_set_gb0_mask(val);
0556 break;
0557 case 1:
0558 if (pause->tx_pause)
0559 netxen_gb_unset_gb1_mask(val);
0560 else
0561 netxen_gb_set_gb1_mask(val);
0562 break;
0563 case 2:
0564 if (pause->tx_pause)
0565 netxen_gb_unset_gb2_mask(val);
0566 else
0567 netxen_gb_set_gb2_mask(val);
0568 break;
0569 case 3:
0570 default:
0571 if (pause->tx_pause)
0572 netxen_gb_unset_gb3_mask(val);
0573 else
0574 netxen_gb_set_gb3_mask(val);
0575 break;
0576 }
0577 NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
0578 } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
0579 if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))
0580 return -EIO;
0581 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
0582 if (port == 0) {
0583 if (pause->tx_pause)
0584 netxen_xg_unset_xg0_mask(val);
0585 else
0586 netxen_xg_set_xg0_mask(val);
0587 } else {
0588 if (pause->tx_pause)
0589 netxen_xg_unset_xg1_mask(val);
0590 else
0591 netxen_xg_set_xg1_mask(val);
0592 }
0593 NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
0594 } else {
0595 printk(KERN_ERR "%s: Unknown board type: %x\n",
0596 netxen_nic_driver_name,
0597 adapter->ahw.port_type);
0598 }
0599 return 0;
0600 }
0601
0602 static int netxen_nic_reg_test(struct net_device *dev)
0603 {
0604 struct netxen_adapter *adapter = netdev_priv(dev);
0605 u32 data_read, data_written;
0606
0607 data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
0608 if ((data_read & 0xffff) != adapter->pdev->vendor)
0609 return 1;
0610
0611 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
0612 return 0;
0613
0614 data_written = (u32)0xa5a5a5a5;
0615
0616 NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
0617 data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
0618 if (data_written != data_read)
0619 return 1;
0620
0621 return 0;
0622 }
0623
0624 static int netxen_get_sset_count(struct net_device *dev, int sset)
0625 {
0626 switch (sset) {
0627 case ETH_SS_TEST:
0628 return NETXEN_NIC_TEST_LEN;
0629 case ETH_SS_STATS:
0630 return NETXEN_NIC_STATS_LEN;
0631 default:
0632 return -EOPNOTSUPP;
0633 }
0634 }
0635
0636 static void
0637 netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
0638 u64 *data)
0639 {
0640 memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
0641 if ((data[0] = netxen_nic_reg_test(dev)))
0642 eth_test->flags |= ETH_TEST_FL_FAILED;
0643
0644 if ((data[1] = (u64) netxen_nic_test_link(dev)))
0645 eth_test->flags |= ETH_TEST_FL_FAILED;
0646 }
0647
0648 static void
0649 netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
0650 {
0651 int index;
0652
0653 switch (stringset) {
0654 case ETH_SS_TEST:
0655 memcpy(data, *netxen_nic_gstrings_test,
0656 NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
0657 break;
0658 case ETH_SS_STATS:
0659 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
0660 memcpy(data + index * ETH_GSTRING_LEN,
0661 netxen_nic_gstrings_stats[index].stat_string,
0662 ETH_GSTRING_LEN);
0663 }
0664 break;
0665 }
0666 }
0667
0668 static void
0669 netxen_nic_get_ethtool_stats(struct net_device *dev,
0670 struct ethtool_stats *stats, u64 *data)
0671 {
0672 struct netxen_adapter *adapter = netdev_priv(dev);
0673 int index;
0674
0675 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
0676 char *p =
0677 (char *)adapter +
0678 netxen_nic_gstrings_stats[index].stat_offset;
0679 data[index] =
0680 (netxen_nic_gstrings_stats[index].sizeof_stat ==
0681 sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
0682 }
0683 }
0684
0685 static void
0686 netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
0687 {
0688 struct netxen_adapter *adapter = netdev_priv(dev);
0689 u32 wol_cfg = 0;
0690
0691 wol->supported = 0;
0692 wol->wolopts = 0;
0693
0694 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
0695 return;
0696
0697 wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
0698 if (wol_cfg & (1UL << adapter->portnum))
0699 wol->supported |= WAKE_MAGIC;
0700
0701 wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
0702 if (wol_cfg & (1UL << adapter->portnum))
0703 wol->wolopts |= WAKE_MAGIC;
0704 }
0705
0706 static int
0707 netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
0708 {
0709 struct netxen_adapter *adapter = netdev_priv(dev);
0710 u32 wol_cfg = 0;
0711
0712 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
0713 return -EOPNOTSUPP;
0714
0715 if (wol->wolopts & ~WAKE_MAGIC)
0716 return -EOPNOTSUPP;
0717
0718 wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
0719 if (!(wol_cfg & (1 << adapter->portnum)))
0720 return -EOPNOTSUPP;
0721
0722 wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
0723 if (wol->wolopts & WAKE_MAGIC)
0724 wol_cfg |= 1UL << adapter->portnum;
0725 else
0726 wol_cfg &= ~(1UL << adapter->portnum);
0727 NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
0728
0729 return 0;
0730 }
0731
0732
0733
0734
0735
0736
0737 static int netxen_set_intr_coalesce(struct net_device *netdev,
0738 struct ethtool_coalesce *ethcoal,
0739 struct kernel_ethtool_coalesce *kernel_coal,
0740 struct netlink_ext_ack *extack)
0741 {
0742 struct netxen_adapter *adapter = netdev_priv(netdev);
0743
0744 if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
0745 return -EINVAL;
0746
0747 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
0748 return -EINVAL;
0749
0750
0751
0752
0753
0754 if (ethcoal->rx_coalesce_usecs > 0xffff ||
0755 ethcoal->rx_max_coalesced_frames > 0xffff ||
0756 ethcoal->tx_coalesce_usecs > 0xffff ||
0757 ethcoal->tx_max_coalesced_frames > 0xffff)
0758 return -EINVAL;
0759
0760 if (!ethcoal->rx_coalesce_usecs ||
0761 !ethcoal->rx_max_coalesced_frames) {
0762 adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
0763 adapter->coal.normal.data.rx_time_us =
0764 NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
0765 adapter->coal.normal.data.rx_packets =
0766 NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
0767 } else {
0768 adapter->coal.flags = 0;
0769 adapter->coal.normal.data.rx_time_us =
0770 ethcoal->rx_coalesce_usecs;
0771 adapter->coal.normal.data.rx_packets =
0772 ethcoal->rx_max_coalesced_frames;
0773 }
0774 adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
0775 adapter->coal.normal.data.tx_packets =
0776 ethcoal->tx_max_coalesced_frames;
0777
0778 netxen_config_intr_coalesce(adapter);
0779
0780 return 0;
0781 }
0782
0783 static int netxen_get_intr_coalesce(struct net_device *netdev,
0784 struct ethtool_coalesce *ethcoal,
0785 struct kernel_ethtool_coalesce *kernel_coal,
0786 struct netlink_ext_ack *extack)
0787 {
0788 struct netxen_adapter *adapter = netdev_priv(netdev);
0789
0790 if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
0791 return -EINVAL;
0792
0793 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
0794 return -EINVAL;
0795
0796 ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
0797 ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
0798 ethcoal->rx_max_coalesced_frames =
0799 adapter->coal.normal.data.rx_packets;
0800 ethcoal->tx_max_coalesced_frames =
0801 adapter->coal.normal.data.tx_packets;
0802
0803 return 0;
0804 }
0805
0806 static int
0807 netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
0808 {
0809 struct netxen_adapter *adapter = netdev_priv(netdev);
0810 struct netxen_minidump *mdump = &adapter->mdump;
0811 if (adapter->fw_mdump_rdy)
0812 dump->len = mdump->md_dump_size;
0813 else
0814 dump->len = 0;
0815
0816 if (!mdump->md_enabled)
0817 dump->flag = ETH_FW_DUMP_DISABLE;
0818 else
0819 dump->flag = mdump->md_capture_mask;
0820
0821 dump->version = adapter->fw_version;
0822 return 0;
0823 }
0824
0825
0826 static const u32 FW_DUMP_LEVELS[] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
0827
0828 static int
0829 netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
0830 {
0831 int i;
0832 struct netxen_adapter *adapter = netdev_priv(netdev);
0833 struct netxen_minidump *mdump = &adapter->mdump;
0834
0835 switch (val->flag) {
0836 case NX_FORCE_FW_DUMP_KEY:
0837 if (!mdump->md_enabled) {
0838 netdev_info(netdev, "FW dump not enabled\n");
0839 return 0;
0840 }
0841 if (adapter->fw_mdump_rdy) {
0842 netdev_info(netdev, "Previous dump not cleared, not forcing dump\n");
0843 return 0;
0844 }
0845 netdev_info(netdev, "Forcing a fw dump\n");
0846 nx_dev_request_reset(adapter);
0847 break;
0848 case NX_DISABLE_FW_DUMP:
0849 if (mdump->md_enabled) {
0850 netdev_info(netdev, "Disabling FW Dump\n");
0851 mdump->md_enabled = 0;
0852 }
0853 break;
0854 case NX_ENABLE_FW_DUMP:
0855 if (!mdump->md_enabled) {
0856 netdev_info(netdev, "Enabling FW dump\n");
0857 mdump->md_enabled = 1;
0858 }
0859 break;
0860 case NX_FORCE_FW_RESET:
0861 netdev_info(netdev, "Forcing FW reset\n");
0862 nx_dev_request_reset(adapter);
0863 adapter->flags &= ~NETXEN_FW_RESET_OWNER;
0864 break;
0865 default:
0866 for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) {
0867 if (val->flag == FW_DUMP_LEVELS[i]) {
0868 mdump->md_capture_mask = val->flag;
0869 netdev_info(netdev,
0870 "Driver mask changed to: 0x%x\n",
0871 mdump->md_capture_mask);
0872 return 0;
0873 }
0874 }
0875 netdev_info(netdev,
0876 "Invalid dump level: 0x%x\n", val->flag);
0877 return -EINVAL;
0878 }
0879
0880 return 0;
0881 }
0882
0883 static int
0884 netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
0885 void *buffer)
0886 {
0887 int i, copy_sz;
0888 u32 *hdr_ptr, *data;
0889 struct netxen_adapter *adapter = netdev_priv(netdev);
0890 struct netxen_minidump *mdump = &adapter->mdump;
0891
0892
0893 if (!adapter->fw_mdump_rdy) {
0894 netdev_info(netdev, "Dump not available\n");
0895 return -EINVAL;
0896 }
0897
0898 copy_sz = mdump->md_template_size;
0899 hdr_ptr = (u32 *) mdump->md_template;
0900 data = buffer;
0901 for (i = 0; i < copy_sz/sizeof(u32); i++)
0902 *data++ = cpu_to_le32(*hdr_ptr++);
0903
0904
0905 memcpy(buffer + copy_sz,
0906 mdump->md_capture_buff + mdump->md_template_size,
0907 mdump->md_capture_size);
0908 dump->len = copy_sz + mdump->md_capture_size;
0909 dump->flag = mdump->md_capture_mask;
0910
0911
0912 vfree(mdump->md_capture_buff);
0913 mdump->md_capture_buff = NULL;
0914 adapter->fw_mdump_rdy = 0;
0915 netdev_info(netdev, "extracted the fw dump Successfully\n");
0916 return 0;
0917 }
0918
0919 const struct ethtool_ops netxen_nic_ethtool_ops = {
0920 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
0921 ETHTOOL_COALESCE_MAX_FRAMES,
0922 .get_drvinfo = netxen_nic_get_drvinfo,
0923 .get_regs_len = netxen_nic_get_regs_len,
0924 .get_regs = netxen_nic_get_regs,
0925 .get_link = ethtool_op_get_link,
0926 .get_eeprom_len = netxen_nic_get_eeprom_len,
0927 .get_eeprom = netxen_nic_get_eeprom,
0928 .get_ringparam = netxen_nic_get_ringparam,
0929 .set_ringparam = netxen_nic_set_ringparam,
0930 .get_pauseparam = netxen_nic_get_pauseparam,
0931 .set_pauseparam = netxen_nic_set_pauseparam,
0932 .get_wol = netxen_nic_get_wol,
0933 .set_wol = netxen_nic_set_wol,
0934 .self_test = netxen_nic_diag_test,
0935 .get_strings = netxen_nic_get_strings,
0936 .get_ethtool_stats = netxen_nic_get_ethtool_stats,
0937 .get_sset_count = netxen_get_sset_count,
0938 .get_coalesce = netxen_get_intr_coalesce,
0939 .set_coalesce = netxen_set_intr_coalesce,
0940 .get_dump_flag = netxen_get_dump_flag,
0941 .get_dump_data = netxen_get_dump_data,
0942 .set_dump = netxen_set_dump,
0943 .get_link_ksettings = netxen_nic_get_link_ksettings,
0944 .set_link_ksettings = netxen_nic_set_link_ksettings,
0945 };