📄 r8168_n.c
字号:
static int rtl8168_rx_vlan_skb(struct rtl8168_private *tp, struct RxDesc *desc, struct sk_buff *skb){ return -1;}#endifstatic void rtl8168_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd){ struct rtl8168_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; u8 status; cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP; cmd->autoneg = (mdio_read(ioaddr, MII_BMCR) & BMCR_ANENABLE) ? 1 : 0; cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) cmd->advertising |= ADVERTISED_10baseT_Half; if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) cmd->advertising |= ADVERTISED_10baseT_Full; if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) cmd->advertising |= ADVERTISED_100baseT_Half; if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) cmd->advertising |= ADVERTISED_100baseT_Full; if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) cmd->advertising |= ADVERTISED_1000baseT_Full; status = RTL_R8(PHYstatus); if (status & _1000bpsF) cmd->speed = SPEED_1000; else if (status & _100bps) cmd->speed = SPEED_100; else if (status & _10bps) cmd->speed = SPEED_10; if (status & TxFlowCtrl) cmd->advertising |= ADVERTISED_Asym_Pause; if (status & RxFlowCtrl) cmd->advertising |= ADVERTISED_Pause; cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ? DUPLEX_FULL : DUPLEX_HALF; tp->autoneg = cmd->autoneg; tp->speed = cmd->speed; tp->duplex = cmd->duplex; }static int rtl8168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd){ struct rtl8168_private *tp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&tp->lock, flags); tp->get_settings(dev, cmd); spin_unlock_irqrestore(&tp->lock, flags); return 0;}static void rtl8168_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p){ struct rtl8168_private *tp = netdev_priv(dev); unsigned long flags; if (regs->len > R8168_REGS_SIZE) regs->len = R8168_REGS_SIZE; spin_lock_irqsave(&tp->lock, flags); memcpy_fromio(p, tp->mmio_addr, regs->len); spin_unlock_irqrestore(&tp->lock, flags);}static u32 rtl8168_get_msglevel(struct net_device *dev){ struct rtl8168_private *tp = netdev_priv(dev); return tp->msg_enable;}static void rtl8168_set_msglevel(struct net_device *dev, u32 value){ struct rtl8168_private *tp = netdev_priv(dev); tp->msg_enable = value;}static const char rtl8168_gstrings[][ETH_GSTRING_LEN] = { "tx_packets", "rx_packets", "tx_errors", "rx_errors", "rx_missed", "align_errors", "tx_single_collisions", "tx_multi_collisions", "unicast", "broadcast", "multicast", "tx_aborted", "tx_underrun",};struct rtl8168_counters { u64 tx_packets; u64 rx_packets; u64 tx_errors; u32 rx_errors; u16 rx_missed; u16 align_errors; u32 tx_one_collision; u32 tx_multi_collision; u64 rx_unicast; u64 rx_broadcast; u32 rx_multicast; u16 tx_aborted; u16 tx_underun;};static int rtl8168_get_stats_count(struct net_device *dev){ return ARRAY_SIZE(rtl8168_gstrings);}static void rtl8168_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data){ struct rtl8168_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; struct rtl8168_counters *counters; dma_addr_t paddr; u32 cmd; ASSERT_RTNL(); counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); if (!counters) return; RTL_W32(CounterAddrHigh, (u64)paddr >> 32); cmd = (u64)paddr & DMA_32BIT_MASK; RTL_W32(CounterAddrLow, cmd); RTL_W32(CounterAddrLow, cmd | CounterDump); while (RTL_R32(CounterAddrLow) & CounterDump) { if (msleep_interruptible(1)) break; } RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrHigh, 0); data[0] = le64_to_cpu(counters->tx_packets); data[1] = le64_to_cpu(counters->rx_packets); data[2] = le64_to_cpu(counters->tx_errors); data[3] = le32_to_cpu(counters->rx_errors); data[4] = le16_to_cpu(counters->rx_missed); data[5] = le16_to_cpu(counters->align_errors); data[6] = le32_to_cpu(counters->tx_one_collision); data[7] = le32_to_cpu(counters->tx_multi_collision); data[8] = le64_to_cpu(counters->rx_unicast); data[9] = le64_to_cpu(counters->rx_broadcast); data[10] = le32_to_cpu(counters->rx_multicast); data[11] = le16_to_cpu(counters->tx_aborted); data[12] = le16_to_cpu(counters->tx_underun);pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);}static void rtl8168_get_strings(struct net_device *dev, u32 stringset, u8 *data){ switch(stringset) { case ETH_SS_STATS: memcpy(data, *rtl8168_gstrings, sizeof(rtl8168_gstrings)); break; }}#undef ethtool_op_get_link#define ethtool_op_get_link _kc_ethtool_op_get_linku32 _kc_ethtool_op_get_link(struct net_device *dev){ return netif_carrier_ok(dev) ? 1 : 0;}#undef ethtool_op_get_sg#define ethtool_op_get_sg _kc_ethtool_op_get_sgu32 _kc_ethtool_op_get_sg(struct net_device *dev){#ifdef NETIF_F_SG return (dev->features & NETIF_F_SG) != 0;#else return 0;#endif}#undef ethtool_op_set_sg#define ethtool_op_set_sg _kc_ethtool_op_set_sgint _kc_ethtool_op_set_sg(struct net_device *dev, u32 data){#ifdef NETIF_F_SG if (data) dev->features |= NETIF_F_SG; else dev->features &= ~NETIF_F_SG;#endif return 0;}static struct ethtool_ops rtl8168_ethtool_ops = { .get_drvinfo = rtl8168_get_drvinfo, .get_regs_len = rtl8168_get_regs_len, .get_link = ethtool_op_get_link, .get_settings = rtl8168_get_settings, .set_settings = rtl8168_set_settings, .get_msglevel = rtl8168_get_msglevel, .set_msglevel = rtl8168_set_msglevel, .get_rx_csum = rtl8168_get_rx_csum, .set_rx_csum = rtl8168_set_rx_csum, .get_tx_csum = rtl8168_get_tx_csum, .set_tx_csum = rtl8168_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg,#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso,#endif .get_regs = rtl8168_get_regs, .get_wol = rtl8168_get_wol, .set_wol = rtl8168_set_wol, .get_strings = rtl8168_get_strings, .get_stats_count = rtl8168_get_stats_count, .get_ethtool_stats = rtl8168_get_ethtool_stats,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)#ifdef ETHTOOL_GPERMADDR .get_perm_addr = ethtool_op_get_perm_addr,#endif#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)};static void rtl8168_get_mac_version(struct rtl8168_private *tp, void __iomem *ioaddr){ u32 reg,val32; u32 ICVerID; val32 = RTL_R32(TxConfig) ; reg = val32 & 0x7c800000; ICVerID = val32 & 0x00700000; switch(reg) { case 0x30000000: tp->mcfg = CFG_METHOD_1; break; case 0x38000000: if(ICVerID == 0x00000000) { tp->mcfg = CFG_METHOD_2; } else if(ICVerID == 0x00500000) { tp->mcfg = CFG_METHOD_3; } else { tp->mcfg = CFG_METHOD_3; } break; case 0x3C000000: if(ICVerID == 0x00000000) { tp->mcfg = CFG_METHOD_4; } else if(ICVerID == 0x00200000) { tp->mcfg = CFG_METHOD_5; } else if(ICVerID == 0x00400000) { tp->mcfg = CFG_METHOD_6; } else { tp->mcfg = CFG_METHOD_6; } break; case 0x3C800000: if (ICVerID == 0x00100000){ tp->mcfg = CFG_METHOD_7; } else if (ICVerID == 0x00300000){ tp->mcfg = CFG_METHOD_8; } else { tp->mcfg = CFG_METHOD_8; } break; case 0x28000000: if(ICVerID == 0x00100000) { tp->mcfg = CFG_METHOD_9; } else if(ICVerID == 0x00200000) { tp->mcfg = CFG_METHOD_10; } else { tp->mcfg = CFG_METHOD_10; } break; default: tp->mcfg = 0xFFFFFFFF; printk("unknown chip version (%x)\n",reg); break; }}static void rtl8168_print_mac_version(struct rtl8168_private *tp){ int i; for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { if (tp->mcfg == rtl_chip_info[i].mcfg){ dprintk("mcfg == %s (%04d)\n", rtl_chip_info[i].name, rtl_chip_info[i].mcfg); return; } } dprintk("mac_version == Unknown\n");}static void rtl8168_hw_phy_config(struct net_device *dev){ struct rtl8168_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; int data; spin_lock_irqsave(&tp->phy_lock, flags); if (tp->mcfg == CFG_METHOD_1) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x16, mdio_read(ioaddr, 0x16) | (1 << 0)); mdio_write(ioaddr, 0x10, 0xF41B); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_2) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x10, 0xF41B); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_3) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x10, 0xF41B); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_4) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x12, 0x2300); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x00, 0x88DE); mdio_write(ioaddr, 0x01, 0x82B1); mdio_write(ioaddr, 0x03, 0x7002); mdio_write(ioaddr, 0x08, 0x9E30); mdio_write(ioaddr, 0x09, 0x01F0); mdio_write(ioaddr, 0x0A, 0x5500); mdio_write(ioaddr, 0x0C, 0x00C8); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x12, 0xC096); mdio_write(ioaddr, 0x16, 0x000A); mdio_write(ioaddr, 0x1F, 0x0000); mdio_write(ioaddr, 0x14, mdio_read(ioaddr, 0x14) | (1 << 5)); mdio_write(ioaddr, 0x0D, mdio_read(ioaddr, 0x0D) | (1 << 5)); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_5) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x12, 0x2300); mdio_write(ioaddr, 0x03, 0x802F); mdio_write(ioaddr, 0x02, 0x4F02); mdio_write(ioaddr, 0x01, 0x0409); mdio_write(ioaddr, 0x00, 0xF099); mdio_write(ioaddr, 0x04, 0x9800); mdio_write(ioaddr, 0x04, 0x9000); mdio_write(ioaddr, 0x1D, 0x3D98); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x00, 0x88DE); mdio_write(ioaddr, 0x01, 0x82B1); mdio_write(ioaddr, 0x06, 0x0761); mdio_write(ioaddr, 0x0C, 0x7EB8); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x16, 0x0F0A); mdio_write(ioaddr, 0x1F, 0x0000); mdio_write(ioaddr, 0x16, mdio_read(ioaddr, 0x16) | (1 << 0)); mdio_write(ioaddr, 0x14, mdio_read(ioaddr, 0x14) | (1 << 5)); mdio_write(ioaddr, 0x0D, mdio_read(ioaddr, 0x0D) | (1 << 5)); mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x14, 0xCAA3); mdio_write(ioaddr, 0x1C, 0x000A); mdio_write(ioaddr, 0x18, 0x65D0); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x17, 0xB580); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x0D, 0x310C); mdio_write(ioaddr, 0x0E, 0x310C); mdio_write(ioaddr, 0x0F, 0x311C); mdio_write(ioaddr, 0x06, 0x0761); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x18, 0xFF55); mdio_write(ioaddr, 0x19, 0x3955); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1f, 0x0001); mdio_write(ioaddr, 0x17, 0x0CC0); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_6) { mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x12, 0x2300); mdio_write(ioaddr, 0x1D, 0x3D98); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x00, 0x88DE); mdio_write(ioaddr, 0x01, 0x82B1); mdio_write(ioaddr, 0x06, 0x0761); mdio_write(ioaddr, 0x0C, 0x7EB8); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x16, 0x0F0A); mdio_write(ioaddr, 0x1F, 0x0000); mdio_write(ioaddr, 0x16, mdio_read(ioaddr, 0x16) | (1 << 0)); mdio_write(ioaddr, 0x14, mdio_read(ioaddr, 0x14) | (1 << 5)); mdio_write(ioaddr, 0x0D, mdio_read(ioaddr, 0x0D) | (1 << 5)); mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x14, 0xCAA3); mdio_write(ioaddr, 0x1C, 0x000A); mdio_write(ioaddr, 0x18, 0x65D0); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x17, 0xB580); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x0D, 0x310C); mdio_write(ioaddr, 0x0E, 0x310C); mdio_write(ioaddr, 0x0F, 0x311C); mdio_write(ioaddr, 0x06, 0x0761); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x18, 0xFF55); mdio_write(ioaddr, 0x19, 0x3955); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1f, 0x0001); mdio_write(ioaddr, 0x17, 0x0CC0); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_7) { mdio_write(ioaddr, 0x1F, 0x0000); mdio_write(ioaddr, 0x14, mdio_read(ioaddr, 0x14) | (1 << 5)); mdio_write(ioaddr, 0x0D, mdio_read(ioaddr, 0x0D) | (1 << 5)); mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x1D, 0x3D98); mdio_write(ioaddr, 0x1F, 0x0001); mdio_write(ioaddr, 0x14, 0xCAA3); mdio_write(ioaddr, 0x1C, 0x000A); mdio_write(ioaddr, 0x18, 0x65D0); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x17, 0xB580); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1F, 0x0002); mdio_write(ioaddr, 0x0D, 0x310C); mdio_write(ioaddr, 0x0E, 0x310C); mdio_write(ioaddr, 0x0F, 0x311C); mdio_write(ioaddr, 0x06, 0x0761); mdio_write(ioaddr, 0x1F, 0x0003); mdio_write(ioaddr, 0x18, 0xFF55); mdio_write(ioaddr, 0x19, 0x3955); mdio_write(ioaddr, 0x18, 0xFF54); mdio_write(ioaddr, 0x19, 0x3954); mdio_write(ioaddr, 0x1f, 0x0001); mdio_write(ioaddr, 0x17, 0x0CC0); mdio_write(ioaddr, 0x1F, 0x0000); } else if (tp->mcfg == CFG_METHOD_8) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -