📄 cxgb2.c
字号:
strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); strcpy(info->fw_version, "N/A"); strcpy(info->bus_info, pci_name(adapter->pdev));}static int get_stats_count(struct net_device *dev){ return ARRAY_SIZE(stats_strings);}static void get_strings(struct net_device *dev, u32 stringset, u8 *data){ if (stringset == ETH_SS_STATS) memcpy(data, stats_strings, sizeof(stats_strings));}static void get_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data){ struct adapter *adapter = dev->priv; struct cmac *mac = adapter->port[dev->if_port].mac; const struct cmac_statistics *s; const struct sge_port_stats *ss; const struct sge_intr_counts *t; s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); ss = t1_sge_get_port_stats(adapter->sge, dev->if_port); t = t1_sge_get_intr_counts(adapter->sge); *data++ = s->TxOctetsOK; *data++ = s->TxOctetsBad; *data++ = s->TxUnicastFramesOK; *data++ = s->TxMulticastFramesOK; *data++ = s->TxBroadcastFramesOK; *data++ = s->TxPauseFrames; *data++ = s->TxFramesWithDeferredXmissions; *data++ = s->TxLateCollisions; *data++ = s->TxTotalCollisions; *data++ = s->TxFramesAbortedDueToXSCollisions; *data++ = s->TxUnderrun; *data++ = s->TxLengthErrors; *data++ = s->TxInternalMACXmitError; *data++ = s->TxFramesWithExcessiveDeferral; *data++ = s->TxFCSErrors; *data++ = s->RxOctetsOK; *data++ = s->RxOctetsBad; *data++ = s->RxUnicastFramesOK; *data++ = s->RxMulticastFramesOK; *data++ = s->RxBroadcastFramesOK; *data++ = s->RxPauseFrames; *data++ = s->RxFCSErrors; *data++ = s->RxAlignErrors; *data++ = s->RxSymbolErrors; *data++ = s->RxDataErrors; *data++ = s->RxSequenceErrors; *data++ = s->RxRuntErrors; *data++ = s->RxJabberErrors; *data++ = s->RxInternalMACRcvError; *data++ = s->RxInRangeLengthErrors; *data++ = s->RxOutOfRangeLengthField; *data++ = s->RxFrameTooLongErrors; *data++ = ss->tso; *data++ = ss->vlan_xtract; *data++ = ss->vlan_insert; *data++ = ss->rx_cso_good; *data++ = ss->tx_cso; *data++ = ss->rx_drops; *data++ = (u64)t->respQ_empty; *data++ = (u64)t->respQ_overflow; *data++ = (u64)t->freelistQ_empty; *data++ = (u64)t->pkt_too_big; *data++ = (u64)t->pkt_mismatch; *data++ = (u64)t->cmdQ_full[0]; *data++ = (u64)t->cmdQ_full[1]; *data++ = (u64)t->tx_ipfrags; *data++ = (u64)t->tx_reg_pkts; *data++ = (u64)t->tx_lso_pkts; *data++ = (u64)t->tx_do_cksum;}static inline void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, unsigned int end){ u32 *p = buf + start; for ( ; start <= end; start += sizeof(u32)) *p++ = readl(ap->regs + start);}static void get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf){ struct adapter *ap = dev->priv; /* * Version scheme: bits 0..9: chip version, bits 10..15: chip revision */ regs->version = 2; memset(buf, 0, T2_REGMAP_SIZE); reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);}static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd){ struct adapter *adapter = dev->priv; struct port_info *p = &adapter->port[dev->if_port]; cmd->supported = p->link_config.supported; cmd->advertising = p->link_config.advertising; if (netif_carrier_ok(dev)) { cmd->speed = p->link_config.speed; cmd->duplex = p->link_config.duplex; } else { cmd->speed = -1; cmd->duplex = -1; } cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; cmd->phy_address = p->phy->addr; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = p->link_config.autoneg; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0;}static int speed_duplex_to_caps(int speed, int duplex){ int cap = 0; switch (speed) { case SPEED_10: if (duplex == DUPLEX_FULL) cap = SUPPORTED_10baseT_Full; else cap = SUPPORTED_10baseT_Half; break; case SPEED_100: if (duplex == DUPLEX_FULL) cap = SUPPORTED_100baseT_Full; else cap = SUPPORTED_100baseT_Half; break; case SPEED_1000: if (duplex == DUPLEX_FULL) cap = SUPPORTED_1000baseT_Full; else cap = SUPPORTED_1000baseT_Half; break; case SPEED_10000: if (duplex == DUPLEX_FULL) cap = SUPPORTED_10000baseT_Full; } return cap;}#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \ ADVERTISED_10000baseT_Full)static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd){ struct adapter *adapter = dev->priv; struct port_info *p = &adapter->port[dev->if_port]; struct link_config *lc = &p->link_config; if (!(lc->supported & SUPPORTED_Autoneg)) return -EOPNOTSUPP; /* can't change speed/duplex */ if (cmd->autoneg == AUTONEG_DISABLE) { int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex); if (!(lc->supported & cap) || cmd->speed == SPEED_1000) return -EINVAL; lc->requested_speed = cmd->speed; lc->requested_duplex = cmd->duplex; lc->advertising = 0; } else { cmd->advertising &= ADVERTISED_MASK; if (cmd->advertising & (cmd->advertising - 1)) cmd->advertising = lc->supported; cmd->advertising &= lc->supported; if (!cmd->advertising) return -EINVAL; lc->requested_speed = SPEED_INVALID; lc->requested_duplex = DUPLEX_INVALID; lc->advertising = cmd->advertising | ADVERTISED_Autoneg; } lc->autoneg = cmd->autoneg; if (netif_running(dev)) t1_link_start(p->phy, p->mac, lc); return 0;}static void get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause){ struct adapter *adapter = dev->priv; struct port_info *p = &adapter->port[dev->if_port]; epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0; epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0; epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;}static int set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause){ struct adapter *adapter = dev->priv; struct port_info *p = &adapter->port[dev->if_port]; struct link_config *lc = &p->link_config; if (epause->autoneg == AUTONEG_DISABLE) lc->requested_fc = 0; else if (lc->supported & SUPPORTED_Autoneg) lc->requested_fc = PAUSE_AUTONEG; else return -EINVAL; if (epause->rx_pause) lc->requested_fc |= PAUSE_RX; if (epause->tx_pause) lc->requested_fc |= PAUSE_TX; if (lc->autoneg == AUTONEG_ENABLE) { if (netif_running(dev)) t1_link_start(p->phy, p->mac, lc); } else { lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); if (netif_running(dev)) p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1, lc->fc); } return 0;}static u32 get_rx_csum(struct net_device *dev){ struct adapter *adapter = dev->priv; return (adapter->flags & RX_CSUM_ENABLED) != 0;}static int set_rx_csum(struct net_device *dev, u32 data){ struct adapter *adapter = dev->priv; if (data) adapter->flags |= RX_CSUM_ENABLED; else adapter->flags &= ~RX_CSUM_ENABLED; return 0;}static int set_tso(struct net_device *dev, u32 value){ struct adapter *adapter = dev->priv; if (!(adapter->flags & TSO_CAPABLE)) return value ? -EOPNOTSUPP : 0; return ethtool_op_set_tso(dev, value);}static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e){ struct adapter *adapter = dev->priv; int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; e->rx_max_pending = MAX_RX_BUFFERS; e->rx_mini_max_pending = 0; e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; e->tx_max_pending = MAX_CMDQ_ENTRIES; e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl]; e->rx_mini_pending = 0; e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl]; e->tx_pending = adapter->params.sge.cmdQ_size[0];}static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e){ struct adapter *adapter = dev->priv; int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending || e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || e->tx_pending > MAX_CMDQ_ENTRIES || e->rx_pending < MIN_FL_ENTRIES || e->rx_jumbo_pending < MIN_FL_ENTRIES || e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1)) return -EINVAL; if (adapter->flags & FULL_INIT_DONE) return -EBUSY; adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; adapter->params.sge.cmdQ_size[0] = e->tx_pending; adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ? MAX_CMDQ1_ENTRIES : e->tx_pending; return 0;}static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c){ struct adapter *adapter = dev->priv; /* * If RX coalescing is requested we use NAPI, otherwise interrupts. * This choice can be made only when all ports and the TOE are off. */ if (adapter->open_device_map == 0) adapter->params.sge.polling = c->use_adaptive_rx_coalesce; if (adapter->params.sge.polling) { adapter->params.sge.rx_coalesce_usecs = 0; } else { adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; } adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); return 0;}static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c){ struct adapter *adapter = dev->priv; c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs; c->rate_sample_interval = adapter->params.sge.sample_interval_usecs; c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable; return 0;}static int get_eeprom_len(struct net_device *dev){ return EEPROM_SIZE;}#define EEPROM_MAGIC(ap) \ (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, u8 *data){ int i; u8 buf[EEPROM_SIZE] __attribute__((aligned(4))); struct adapter *adapter = dev->priv; e->magic = EEPROM_MAGIC(adapter); for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32)) t1_seeprom_read(adapter, i, (u32 *)&buf[i]); memcpy(data, buf + e->offset, e->len); return 0;}static struct ethtool_ops t1_ethtool_ops = { .get_settings = get_settings, .set_settings = set_settings, .get_drvinfo = get_drvinfo, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, .get_ringparam = get_sge_param, .set_ringparam = set_sge_param, .get_coalesce = get_coalesce, .set_coalesce = set_coalesce, .get_eeprom_len = get_eeprom_len, .get_eeprom = get_eeprom, .get_pauseparam = get_pauseparam, .set_pauseparam = set_pauseparam, .get_rx_csum = get_rx_csum, .set_rx_csum = set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, .get_stats_count = get_stats_count, .get_ethtool_stats = get_stats, .get_regs_len = get_regs_len, .get_regs = get_regs, .get_tso = ethtool_op_get_tso, .set_tso = set_tso,};static void cxgb_proc_cleanup(struct adapter *adapter, struct proc_dir_entry *dir){ const char *name; name = adapter->name; remove_proc_entry(name, dir);}//#define chtoe_setup_toedev(adapter) NULL#define update_mtu_tab(adapter)#define write_smt_entry(adapter, idx)static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd){ struct adapter *adapter = dev->priv; struct mii_ioctl_data *data = if_mii(req); switch (cmd) { case SIOCGMIIPHY: data->phy_id = adapter->port[dev->if_port].phy->addr; /* FALLTHRU */ case SIOCGMIIREG: { struct cphy *phy = adapter->port[dev->if_port].phy; u32 val; if (!phy->mdio_read) return -EOPNOTSUPP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -