OK335xS 网络连接打印信息 hacking
/***********************************************************************
* OK335xS 网络连接打印信息 hacking
* 说明:
* 当我们插入网线的时候,经常会看到对应的网卡已连接,当前属于10M、
* 100M网卡工作状态等等信息,那么这些信息是如何被输出的,工作机制是什么,
* 网卡的速度是由phy决定的还是由mac决定的,是不是在phy对应的中断里处理,
* 等等,这些内容都需要去确认。
*
* 2016-2-2 深圳 南山平山村 曾剑锋
**********************************************************************/ /**
* 参考文章:
* Linux PHY几个状态的跟踪
* http://www.latelee.org/programming-under-linux/linux-phy-state.html
*/ static const struct dev_pm_ops cpsw_pm_ops = { <------+
.suspend = cpsw_suspend, |
.resume = cpsw_resume, -----------+
}; | |
| |
static struct platform_driver cpsw_driver = { <---|-+ |
.driver = { | | |
.name = "cpsw", | | |
.owner = THIS_MODULE, | | |
.pm = &cpsw_pm_ops, ----------+ | |
}, | |
.probe = cpsw_probe, | |
.remove = __devexit_p(cpsw_remove), | |
}; | |
| |
static int __init cpsw_init(void) | |
{ | |
return platform_driver_register(&cpsw_driver); -----+ |
} |
late_initcall(cpsw_init); |
|
static void __exit cpsw_exit(void) |
{ |
platform_driver_unregister(&cpsw_driver); |
} |
module_exit(cpsw_exit); |
|
MODULE_LICENSE("GPL"); |
MODULE_DESCRIPTION("TI CPSW Ethernet driver"); |
|
|
|
static int cpsw_resume(struct device *dev) <----------+
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev); pm_runtime_get_sync(&pdev->dev);
cpsw_start_slaves_interface(ndev); ----+
|
return ; |
} |
|
V
static inline void cpsw_start_slaves_interface(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
u32 i = ; for (i = ; i < priv->data.slaves; i++) {
ndev = cpsw_get_slave_ndev(priv, i);
if (netif_running(ndev))
cpsw_ndo_open(ndev); ----------+
} |
} |
|
|
static int cpsw_ndo_open(struct net_device *ndev) <--+
{
struct cpsw_priv *priv = netdev_priv(ndev);
int i, ret;
u32 reg; if (!cpsw_common_res_usage_state(priv))
cpsw_intr_disable(priv);
netif_carrier_off(ndev); if (priv->data.phy_control)
(*priv->data.phy_control)(true); reg = __raw_readl(&priv->regs->id_ver);
priv->version = reg; msg(info, ifup, "initializing cpsw version %d.%d (%d)\n",
(reg >> & 0x7), reg & 0xff, (reg >> ) & 0x1f); /* initialize host and slave ports */
if (!cpsw_common_res_usage_state(priv))
cpsw_init_host_port(priv);
for_each_slave(priv, cpsw_slave_open, priv); -----------+
|
/* Add default VLAN */ |
cpsw_add_default_vlan(priv); |
|
if (!cpsw_common_res_usage_state(priv)) { |
ret = device_create_file(&ndev->dev, &dev_attr_hw_stats); |
if (ret < ) { |
dev_err(priv->dev, "unable to add device attr\n"); |
return ret; |
} |
|
/* setup tx dma to fixed prio and zero offset */ |
cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, ); |
cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, ); |
|
/* disable priority elevation and enable statistics */ |
/* on all ports */ |
writel(, &priv->regs->ptype); |
writel(0x7, &priv->regs->stat_port_en); |
|
if (WARN_ON(!priv->data.rx_descs)) |
priv->data.rx_descs = ; |
|
for (i = ; i < priv->data.rx_descs; i++) { |
struct sk_buff *skb; |
|
ret = -ENOMEM; |
skb = netdev_alloc_skb_ip_align(priv->ndev, |
priv->rx_packet_max); |
if (!skb) |
break; |
ret = cpdma_chan_submit(priv->rxch, skb, skb->data, |
skb_tailroom(skb), , GFP_KERNEL); |
if (WARN_ON(ret < )) { |
dev_kfree_skb_any(skb); |
break; |
} |
} |
/* |
* continue even if we didn't manage to submit all |
* receive descs |
*/ |
msg(info, ifup, "submitted %d rx descriptors\n", i); |
|
if (cpts_register(&priv->pdev->dev, priv->cpts, |
priv->data.cpts_clock_mult, |
priv->data.cpts_clock_shift)) |
dev_err(priv->dev, "error registering cpts device\n"); |
} |
|
/* Enable Interrupt pacing if configured */ |
if (priv->coal_intvl != ) { |
struct ethtool_coalesce coal; |
|
coal.rx_coalesce_usecs = (priv->coal_intvl << ); |
cpsw_set_coalesce(ndev, &coal); |
} |
|
/* Enable Timer for capturing cpsw rx interrupts */ |
omap_dm_timer_set_int_enable(dmtimer_rx, OMAP_TIMER_INT_CAPTURE);|
omap_dm_timer_set_capture(dmtimer_rx, , , ); |
omap_dm_timer_enable(dmtimer_rx); |
|
/* Enable Timer for capturing cpsw tx interrupts */ |
omap_dm_timer_set_int_enable(dmtimer_tx, OMAP_TIMER_INT_CAPTURE);|
omap_dm_timer_set_capture(dmtimer_tx, , , ); |
omap_dm_timer_enable(dmtimer_tx); |
|
cpdma_ctlr_start(priv->dma); |
cpsw_intr_enable(priv); |
napi_enable(&priv->napi); |
cpdma_ctlr_eoi(priv->dma); |
|
cpsw_update_slave_open_state(priv, true) |
|
return ; +-----------------------------------------------+
} |
|
V
static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
char name[];
u32 slave_port; sprintf(name, "slave-%d", slave->slave_num); soft_reset(name, &slave->sliver->soft_reset); /* setup priority mapping */
writel(0x76543210, &slave->sliver->rx_pri_map);
if (priv->version == CPSW_VERSION1)
slave_write(slave, 0x33221100, CPSW1_TX_PRI_MAP);
else
slave_write(slave, 0x33221100, CPSW2_TX_PRI_MAP); /* setup max packet size, and mac address */
__raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen);
cpsw_set_slave_mac(slave, priv); slave->mac_control = ; /* no link yet */ slave_port = cpsw_get_slave_port(priv, slave->slave_num); cpsw_add_dual_emac_mode_default_ale_entries(priv, slave, slave_port);
cpsw_add_switch_mode_bcast_ale_entries(priv, slave_port);
priv->port_state[slave_port] = ALE_PORT_STATE_FORWARD; slave->phy = phy_connect(priv->ndev, slave->data->phy_id, ------+
&cpsw_adjust_link, , slave->data->phy_if); ------*--------+
if (IS_ERR(slave->phy)) { | |
msg(err, ifup, "phy %s not found on slave %d\n", | |
slave->data->phy_id, slave->slave_num); | |
slave->phy = NULL; | |
} else { | |
dev_info(priv->dev, "CPSW phy found : id is : 0x%x\n", | |
slave->phy->phy_id); | |
cpsw_set_phy_config(priv, slave->phy); | |
phy_start(slave->phy); | |
} +-------------------------------------------+ |
} | |
| |
V |
struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, |
void (*handler)(struct net_device *), u32 flags, |
phy_interface_t interface) |
{ |
struct phy_device *phydev; |
struct device *d; |
int rc; |
|
/* Search the list of PHY devices on the mdio bus for the |
* PHY with the requested name */ |
d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); |
if (!d) { |
pr_err("PHY %s not found\n", bus_id); |
return ERR_PTR(-ENODEV); |
} |
phydev = to_phy_device(d); |
|
rc = phy_connect_direct(dev, phydev, handler, flags, interface); ----+ |
if (rc) | |
return ERR_PTR(rc); | |
| |
return phydev; | |
} | |
EXPORT_SYMBOL(phy_connect); | |
+----------------------------------------------------------+ |
V |
int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, |
void (*handler)(struct net_device *), u32 flags, |
phy_interface_t interface) |
{ |
int rc; |
|
rc = phy_attach_direct(dev, phydev, flags, interface); |
if (rc) |
return rc; |
|
phy_prepare_link(phydev, handler); ----------------+ |
phy_start_machine(phydev, NULL); ---------------------*--------+ |
if (phydev->irq > ) | | |
phy_start_interrupts(phydev); | | |
| | |
return ; | | |
} | | |
EXPORT_SYMBOL(phy_connect_direct); | | |
| | |
| | |
static void phy_prepare_link(struct phy_device *phydev, <-----+ | |
void (*handler)(struct net_device *)) | |
{ | |
phydev->adjust_link = handler; | |
} | |
| |
| |
/** | |
* phy_start_machine - start PHY state machine tracking | |
* @phydev: the phy_device struct | |
* @handler: callback function for state change notifications | |
* | |
* Description: The PHY infrastructure can run a state machine | |
* which tracks whether the PHY is starting up, negotiating, | |
* etc. This function starts the timer which tracks the state | |
* of the PHY. If you want to be notified when the state changes, | |
* pass in the callback @handler, otherwise, pass NULL. If you | |
* want to maintain your own state machine, do not call this | |
* function. | |
*/ | |
void phy_start_machine(struct phy_device *phydev, <--------------+ |
void (*handler)(struct net_device *)) |
{ |
phydev->adjust_state = handler; |
|
schedule_delayed_work(&phydev->state_queue, HZ); |
} |
|
|
static void cpsw_adjust_link(struct net_device *ndev) <------------------+
{
struct cpsw_priv *priv = netdev_priv(ndev);
bool link = false; for_each_slave(priv, _cpsw_adjust_link, priv, &link); ----------+
|
if (link) { |
netif_carrier_on(ndev); |
if (netif_running(ndev)) |
netif_wake_queue(ndev); |
} else { |
netif_carrier_off(ndev); |
netif_stop_queue(ndev); |
} |
} |
|
|
static void _cpsw_adjust_link(struct cpsw_slave *slave, <--------+
struct cpsw_priv *priv, bool *link)
{
struct phy_device *phy = slave->phy;
u32 mac_control = ;
u32 slave_port; if (!phy)
return; slave_port = cpsw_get_slave_port(priv, slave->slave_num); if (phy->link) {
/* enable forwarding */
cpsw_ale_control_set(priv->ale, slave_port,
ALE_PORT_STATE, priv->port_state[slave_port]); mac_control = priv->data.mac_control;
if (phy->speed == )
mac_control |= BIT(); /* In Band mode */
if (phy->speed == ) {
mac_control |= BIT(); /* Enable gigabit mode */
}
if (phy->speed == )
mac_control |= BIT();
if (phy->duplex)
mac_control |= BIT(); /* FULLDUPLEXEN */
if (phy->interface == PHY_INTERFACE_MODE_RGMII) /* RGMII */
mac_control |= (BIT()|BIT());
*link = true;
} else {
cpsw_ale_control_set(priv->ale, slave_port,
ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
mac_control = ;
} if (mac_control != slave->mac_control) {
phy_print_status(phy); ---------------+
__raw_writel(mac_control, &slave->sliver->mac_control); |
} |
|
slave->mac_control = mac_control; |
} |
|
/** |
* phy_print_status - Convenience function to print out the current phy status |
* @phydev: the phy_device struct |
*/ |
void phy_print_status(struct phy_device *phydev) <-------------+
{
pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev),
phydev->link ? "Up" : "Down");
if (phydev->link)
printk(KERN_CONT " - %d/%s", phydev->speed,
DUPLEX_FULL == phydev->duplex ?
"Full" : "Half"); printk(KERN_CONT "\n");
}
EXPORT_SYMBOL(phy_print_status); /*
* 1. LAN8710A/LAN8710Ai datasheet
* 1. http://ww1.microchip.com/downloads/en/DeviceDoc/8710a.pdf
* 2. 1.2 General Description
* ......
* The LAN8710A/LAN8710Ai supports communication with an Ethernet MAC via a standard MII (IEEE 802.3u)/RMII interface. It contains a full-duplex 10-BASE-T/100BASE-TX transceiver and supports 10Mbps (10BASE-T) and 100Mbps (100BASE-TX) operation. The LAN8710A/LAN8710Ai implements auto-negotiation to automatically determine the best possible speed and duplex mode of operation. HP Auto-MDIX support allows the use of direct connect or cross-over LAN cables.
* ......
* 2. 由上面可知,决定网卡的工作速度的是phy自动决定。
*/
OK335xS 网络连接打印信息 hacking的更多相关文章
- 网络连接详细信息出现两个自动配置ipv4地址
问题:网络连接详细信息出现两个自动配置ipv4地址,一个是有效地址,一个是无效地址. 解决办法:先将本地连接ip设置成自动获取,然后点击开始——>运行——>输入cmd,回车,进入命令行界面 ...
- 网络连接详细信息出现两个自动配置ipv4地址的解决办法
问题描述:网络连接详细信息出现两个自动配置ipv4地址,一个是有效地址,一个是无效地址. 解决办法: 先将本地连接ip设置成自动获取 点击开始——>运行——>输入cmd,回车,进入命令行界 ...
- 负载均衡服务TCP端口健康检查成功,为什么在后端业务日志中出现网络连接异常信息?
负载均衡服务TCP端口健康检查成功,为什么在后端业务日志中出现网络连接异常信息? 原文: https://help.aliyun.com/document_detail/127193.html?spm ...
- 【Linux 运维】查看网络连接状态信息之netstat和ss命令详解
一.netstat 常用命令详解 通过man netstat可以查看netstat的帮助信息: netstat 命令:用于显示各种网络相关信息,如网络连接,路由表,接口状态,无效连接,组播成员 等等. ...
- C# 通过扩展WebBrowser捕获网络连接错误信息
想捕获WebBrowser连接指定网站过程中发生的错误信息,包括网络无法连接.404找不到网页等等错误!经过网上的搜集,找到了以下解决方案,该解决方案不会在网站连接前发出多余的测试请求. 向Webbr ...
- C#获得网络连接信息 IPGlobalProperties
IPGlobalProperties 提供有关本地计算机的网络连接的信息. 此类提供有关本地计算机的网络接口和网络连接的配置和统计信息 可以获取本机TCP UDP 丢包 发包等数据. 此类提供的信息与 ...
- C# 获取电脑的网络连接状态
判断连网的方法介绍 1. InternetGetConnectedState 此函数获取网络状态有延时,且对网卡伤害较大 MSDN官方自己推荐不建议使用,不管是连网状态下还是断网情况下,获取的网络状态 ...
- C# WMI通过网络连接名称获取IP掩码网关
/// <summary> /// 读取IP,掩码,网关地址 /// </summary> /// <param name="netConnectorName& ...
- netstat - 显示网络连接,路由表,接口状态,伪装连接,网络链路信息和组播成员组。
总览 SYNOPSIS netstat [address_family_options] [--tcp|-t] [--udp|-u] [--raw|-w] [--listening|-l] [--al ...
随机推荐
- Java7 新特性 数值文本表示法
今天和大家分享下 java7中新特性-数值文本表示法 首先,在原来jdk1.6中 如果需要将一个二进制的数值转换成十进制的话,一般情况下都会以下面的代码方式去实现. public static voi ...
- HDOJ 3547 DIY Cube 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3547 题目大意:求用$C$种颜色给立方体的8个顶点染色的本质不同的方法.两种方法本质不同即不能通过旋转 ...
- 01-01-01【Nhibernate (版本3.3.1.4000) 出入江湖】配置文件
默认配置文件名称是:hibernate.cfg.xml 放置在应用程序集的根目录下 <?xml version="1.0" encoding="utf-8" ...
- C++中的const关键字
http://blog.csdn.net/eric_jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...
- Even Fibonacci numbers
--Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting ...
- **PHP随机数算法
<?php $tmp = range(1,30);print_r(array_rand($tmp,10));?> 输出: Array( [0] => 6 [1] => 8 [2 ...
- 一个很好的php分词类库
PHPAnalysis源程序下载与演示: PHP分词系统 V2.0 版下载 | PHP分词系统演示 | PHPAnalysis类API文档 原文连接地址:http://www.phpbone.co ...
- Linux Versus Windows, Ubuntu/Mint V XP/Vista/7
原文:http://petermoulding.com/linux_versus_windows_ubuntu_mint_v_xp_vista_7 Linux Versus Windows, Ubun ...
- [SharePoint 2013 入门教程 3 ] 排版第一个网站集,网站
我们创建了一个TEST网站集,如果你觉得太丑,怎么办,我们一起来给它整整容吧. 点击页面--> 编辑页面 我们现在就可以在页面上添加各种部件,进行布局排版.
- VirtualUI - Convert your Windows App to HTML5
http://www.cybelesoft.com/thinfinity/virtualui/