📄 at_ethtool.c
字号:
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* There are a lot of defines in here that are unused and/or have cryptic
* names. Please leave them alone, as they're the closest thing we have
* to a spec from Atheros at present. *ahem* -- CHS
*/
/* ethtool support for at */
#include <linux/netdevice.h>
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#include "at.h"
#ifdef ETHTOOL_OPS_COMPAT
#include "kcompat_ethtool.c"
#endif
extern char at_driver_name[];
extern char at_driver_version[];
extern int at_up(struct at_adapter *adapter);
extern void at_down(struct at_adapter *adapter);
extern void at_reinit_locked(struct at_adapter *adapter);
extern s32 at_reset_hw(struct at_hw *hw);
static int
at_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct at_adapter *adapter = netdev_priv(netdev);
struct at_hw *hw = &adapter->hw;
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
if (hw->nic_type == athr_l1e) {
ecmd->supported |= SUPPORTED_1000baseT_Full;
}
ecmd->advertising = ADVERTISED_TP;
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->advertising |= hw->autoneg_advertised;
ecmd->port = PORT_TP;
ecmd->phy_address = 0;
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed;
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}
ecmd->autoneg = AUTONEG_ENABLE;
return 0;
}
static int
at_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct at_adapter *adapter = netdev_priv(netdev);
struct at_hw *hw = &adapter->hw;
while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
msleep(1);
if (ecmd->autoneg == AUTONEG_ENABLE)
hw->MediaType = MEDIA_TYPE_AUTO_SENSOR;
else {
if (ecmd->speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
printk(KERN_WARNING"1000M half is invalid\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
hw->MediaType = MEDIA_TYPE_1000M_FULL;
} else if (ecmd->speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
hw->MediaType = MEDIA_TYPE_100M_FULL;
else
hw->MediaType = MEDIA_TYPE_100M_HALF;
} else {
if (ecmd->duplex == DUPLEX_FULL)
hw->MediaType = MEDIA_TYPE_10M_FULL;
else
hw->MediaType = MEDIA_TYPE_10M_HALF;
}
}
hw->mii_autoneg_adv_reg = 0;
if (at_phy_setup_autoneg_adv(hw) != 0) {
printk(KERN_WARNING"invalid ethtool speed/duplex setting\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
if (at_restart_autoneg(hw) != 0) {
printk(KERN_WARNING"ethtool speed/duplex setting failed\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
clear_bit(__AT_RESETTING, &adapter->flags);
return 0;
}
static u32
at_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static u32
at_get_msglevel(struct net_device *netdev)
{
#if DBG
return 1;
#else
return 0;
#endif
}
static void
at_set_msglevel(struct net_device *netdev, u32 data)
{
}
static int
at_get_regs_len(struct net_device *netdev)
{
#define AT_REGS_LEN 75
return AT_REGS_LEN * sizeof(u32);
}
static void
at_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct at_adapter *adapter = netdev_priv(netdev);
struct at_hw *hw = &adapter->hw;
u32 *regs_buff = p;
u16 phy_data;
memset(p, 0, AT_REGS_LEN * sizeof(u32));
regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
regs_buff[0] = AT_READ_REG(hw, REG_VPD_CAP);
regs_buff[1] = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
regs_buff[2] = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
regs_buff[3] = AT_READ_REG(hw, REG_TWSI_CTRL);
regs_buff[4] = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
regs_buff[5] = AT_READ_REG(hw, REG_MASTER_CTRL);
regs_buff[6] = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
regs_buff[7] = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
regs_buff[8] = AT_READ_REG(hw, REG_GPHY_CTRL);
regs_buff[9] = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
regs_buff[20] = AT_READ_REG(hw, REG_MTU);
regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
/*
// description address
regs_buff[30] = AT_READ_REG(hw, REG_DESC_BASE_ADDR_HI);
regs_buff[31] = AT_READ_REG(hw, REG_TPD_BASE_ADDR_LO);
regs_buff[32] = AT_READ_REG(hw, REG_TPD_RING_SIZE);
regs_buff[33] = AT_READ_REG(hw, REG_HOST_RXF_HEAD);
regs_buff[34] = AT_READ_REG(hw, REG_HOST_RXF_TAIL);
regs_buff[35] = AT_READ_REG(hw, REG_HOST_RXRAM_SIZE);
regs_buff[36] = AT_READ_REG(hw, REG_HOST_RXF1_HEAD);
regs_buff[37] = AT_READ_REG(hw, REG_HOST_RXF1_TAIL);
regs_buff[38] = AT_READ_REG(hw, REG_HOST_RXF2_HEAD);
regs_buff[39] = AT_READ_REG(hw, REG_HOST_RXF2_TAIL);
regs_buff[40] = AT_READ_REG(hw, REG_HOST_RXF3_HEAD);
regs_buff[41] = AT_READ_REG(hw, REG_HOST_RXF3_TAIL);
// mail box
regs_buff[42] = AT_READ_REG(hw, REG_HOST_RXF0_WADDR);
regs_buff[43] = AT_READ_REG(hw, REG_HOST_RXF1_WADDR);
regs_buff[44] = AT_READ_REG(hw, REG_HOST_RXF2_WADDR);
regs_buff[45] = AT_READ_REG(hw, REG_HOST_RXF3_WADDR);
regs_buff[46] = AT_READ_REG(hw, REG_TPD_CONS_IDX);
regs_buff[47] = AT_READ_REG(hw, REG_MB_RXF0_RADDR);
regs_buff[48] = AT_READ_REG(hw, REG_MB_RXF1_RADDR);
regs_buff[49] = AT_READ_REG(hw, REG_MB_RXF2_RADDR);
regs_buff[50] = AT_READ_REG(hw, REG_MB_RXF3_RADDR);
regs_buff[51] = AT_READ_REG(hw, REG_MB_TPD_PROD_IDX);
// RSS
regs_buff[52] = AT_READ_REG(hw, REG_RSS_KEY0);
regs_buff[53] = AT_READ_REG(hw, REG_RSS_KEY1);
regs_buff[54] = AT_READ_REG(hw, REG_RSS_KEY2);
regs_buff[55] = AT_READ_REG(hw, REG_RSS_KEY3);
regs_buff[56] = AT_READ_REG(hw, REG_RSS_HASH_VALUE);
regs_buff[57] = AT_READ_REG(hw, REG_RSS_HASH_FLAG);
regs_buff[58] = AT_READ_REG(hw, REG_IDT_TABLE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -