📄 at_ethtool.c
字号:
regs_buff[59] = AT_READ_REG(hw, REG_BASE_CPU_NUMBER);
// TXQ
regs_buff[60] = AT_READ_REG(hw, REG_TXQ_CTRL);
regs_buff[61] = AT_READ_REG(hw, REG_TX_JUMBO_TASK_TH);
// RXQ
regs_buff[62] = AT_READ_REG(hw, REG_RXQ_CTRL);
regs_buff[63] = AT_READ_REG(hw, REG_RXQ_JMBOSZ_RRDTIM);
regs_buff[64] = AT_READ_REG(hw, REG_RXQ_RXF_PAUSE_THRESH);
// DMA
regs_buff[65] = AT_READ_REG(hw, REG_DMA_CTRL);
// misc
regs_buff[66] = AT_READ_REG(hw, REG_SMB_STAT_TIMER);
regs_buff[67] = AT_READ_REGW(hw, REG_TRIG_RRD_THRESH);
regs_buff[68] = AT_READ_REGW(hw, REG_TRIG_TPD_THRESH);
regs_buff[69] = AT_READ_REGW(hw, REG_TRIG_RXTIMER);
regs_buff[70] = AT_READ_REGW(hw, REG_TRIG_TXTIMER);
regs_buff[71] = AT_READ_REG(hw, REG_ISR);
regs_buff[72] = AT_READ_REG(hw, REG_IMR);
*/
at_read_phy_reg(hw, MII_BMCR, &phy_data);
regs_buff[73] = (u32)phy_data;
at_read_phy_reg(hw, MII_BMSR, &phy_data);
regs_buff[74] = (u32)phy_data;
}
static int
at_get_eeprom_len(struct net_device *netdev)
{
struct at_adapter *adapter = netdev_priv(netdev);
if (!check_eeprom_exist(&adapter->hw)) {
return 512;
} else
return 0;
}
static int
at_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct at_adapter *adapter = netdev_priv(netdev);
struct at_hw *hw = &adapter->hw;
u32 *eeprom_buff;
int first_dword, last_dword;
int ret_val = 0;
int i;
if (eeprom->len == 0)
return -EINVAL;
if (check_eeprom_exist(hw)) {
return -EINVAL;
}
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(sizeof(u32) *
(last_dword - first_dword + 1), GFP_KERNEL);
if (!eeprom_buff)
return -ENOMEM;
for (i=first_dword; i < last_dword; i++) {
if (!read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword])))
return -EIO;
}
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
eeprom->len);
kfree(eeprom_buff);
return ret_val;
}
static int
at_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct at_adapter *adapter = netdev_priv(netdev);
struct at_hw *hw = &adapter->hw;
u32 *eeprom_buff;
u32 *ptr;
int max_len, first_dword, last_dword, ret_val = 0;
int i;
if (eeprom->len == 0)
return -EOPNOTSUPP;
if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
max_len = 512;
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
if (!eeprom_buff)
return -ENOMEM;
ptr = (u32 *)eeprom_buff;
if (eeprom->offset & 3) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
if (!read_eeprom(hw, first_dword*4, &(eeprom_buff[0])))
return -EIO;
ptr++;
}
if (((eeprom->offset + eeprom->len) & 3) ) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
if (!read_eeprom(hw, last_dword*4, &(eeprom_buff[last_dword - first_dword])))
return -EIO;
}
/* Device's eeprom is always little-endian, word addressable */
memcpy(ptr, bytes, eeprom->len);
for (i = 0; i < last_dword - first_dword + 1; i++) {
if (!write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i]))
return -EIO;
}
kfree(eeprom_buff);
return ret_val;
}
static void
at_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct at_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, at_driver_name, 32);
strncpy(drvinfo->version, at_driver_version, 32);
strncpy(drvinfo->fw_version, "L1e", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = at_get_regs_len(netdev);
drvinfo->eedump_len = at_get_eeprom_len(netdev);
}
static void
at_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct at_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_MAGIC|WAKE_PHY;
wol->wolopts = 0;
if (adapter->wol & AT_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & AT_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & AT_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & AT_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & AT_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
return;
}
static int
at_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct at_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;
if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) {
AT_DBG("Interface does not support broadcast/multicast frame wake-up packets\n");
return -EOPNOTSUPP;
}
/* these settings will always override what we currently have */
adapter->wol = 0;
if (wol->wolopts & WAKE_MAGIC) {
adapter->wol |= AT_WUFC_MAG;
DEBUGOUT("magic WOL enable");
}
if (wol->wolopts & WAKE_PHY) {
adapter->wol |= AT_WUFC_LNKC;
DEBUGOUT("linkchg WOL enable");
}
return 0;
}
static int
at_nway_reset(struct net_device *netdev)
{
struct at_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
at_reinit_locked(adapter);
return 0;
}
static struct ethtool_ops at_ethtool_ops = {
.get_settings = at_get_settings,
.set_settings = at_set_settings,
.get_drvinfo = at_get_drvinfo,
.get_regs_len = at_get_regs_len,
.get_regs = at_get_regs,
.get_wol = at_get_wol,
.set_wol = at_set_wol,
.get_msglevel = at_get_msglevel,
.set_msglevel = at_set_msglevel,
.nway_reset = at_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = at_get_eeprom_len,
.get_eeprom = at_get_eeprom,
.set_eeprom = at_set_eeprom,
.get_tx_csum = at_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO
.get_tso = ethtool_op_get_tso,
#endif
#ifdef ETHTOOL_GPERMADDR
.get_perm_addr = ethtool_op_get_perm_addr,
#endif
};
void at_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &at_ethtool_ops);
}
#endif /* SIOCETHTOOL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -