dm9000a linux 驱动框架 分析

裸机操作

dm9000的裸机操作

这里 讲了如何对dm9000 访问
本文主要讲解dm9000 在linux下的驱动

文件解析

dm9000 linux 相关文件
drivers/net$ tree
.
├── ethernet
│   ├── davicom
│   │   ├── dm9000.c
│   │   ├── dm9000.h
│   │   ├── Kconfig
│   │   └── Makefile
│   ├── Kconfig
│   └── Makefile
├── Kconfig
├── loopback.c // 回环设备的驱动
├── Makefile
└── mii.c   // mii 协议的代码描述,这里面EXPORT_SYMBOL出来的符号都被dm9000.c 用了
dm9000 mm.c 解析
  • mii.c 中 EXPORT_SYMBOL 出来的符号
mii_link_ok
mii_nway_restart
mii_ethtool_gset
mii_ethtool_get_link_ksettings
mii_ethtool_sset
mii_ethtool_set_link_ksettings
mii_check_link
mii_check_media
mii_check_gmii_support
generic_mii_ioctl
dm9000 dm9000.c 解析
  • dm9000.c 框架
dm9000.c 中 没有 EXPORT_SYMBOL 出来符号,且全部都是static 的
	probe 做了一些 net_device_ops-> ndo_init 中需要做到的事情,所以把 ndo_init 直接留空了
dm9000.c 中 写了17951413 - 1707 是probe
	1429 - 1442 给dm9000 上电
	1444 - 1460 给dm9000 复位
	1462 - 1466 从设备树中获取信息,是不是用了ext phy,是不是no-eeprom,mac地址
	1469 - 1683 行
		申请 struct net_device , 并填充成员
		申请 struct board_info , 并填充成员
		1. dev.parent
		2. struct board_info *db
			2.1 lock
			2.2 addr_lock
			2.3 phy_poll
			2.4 addr_res
			2.5 data_res
			2.6 addr_req
			2.7 io_addr
			2.8 data_req
			2.9 io_data
			2.10 dumpblk
			2.11 outblk
			2.12 inblk
			2.13 flags
			2.14 msg_enable
			2.15 mii.phy_id_mask / mii.reg_num_mask/ mii.force_media/mii.full_duplex/mii.dev/
			2.16 mii.mdio_read/mii.mdio_write
		3. irq
		4. irq_wake
		5. base_addr
		期间,reset 了 dm9000,读了id,知道dm9000的具体型号
		6. hw_features
		7. features
		8. netdev_ops
		9. watchdog_timeo
		10.ethtool_ops
		期间 读了 eeprom, 获取了 mac地址,并校验是否有效
		期间,platform_set_drvdata(pdev, ndev);
		register_netdev(ndev);

1760 - 1770 是 remove
	unregister_netdev(ndev);
	dm9000_release_board(pdev, netdev_priv(ndev));
	free_netdev(ndev);

1710 - 1729 是 suspend
	经过层层判断,然后dm9000_shutdown(包括 Power-Down PHY,Disable RX)
	// 这个动作 也会在 dm9000_netdev_ops->ndo_open 即 dm9000_stop 中做


1732 - 1752 是 resume
	对应suspend后 resume 的动作
	做了 dm9000_init_dm9000 和 dm9000_unmask_interrupts
	// 这2个动作 也会在 dm9000_netdev_ops->ndo_open 即 dm9000_open 中做

接口分析

实现了哪些ops
底层ops
对下,实现了这些ops
mdio_read
mdio_write

dm9000_get_eeprom
dm9000_set_eeprom

dm9000_get_link_ksettings
dm9000_set_link_ksettings

ior
iow

dumpblk
inblk
outblk
上层ops
对上,实现了这些ops
struct net_device_ops netdev_ops
struct ethtool_ops    ethtool_ops
	http://lnmp.ailinux.net/ethtool
	https://zhuanlan.zhihu.com/p/55131870
1367 static const struct net_device_ops dm9000_netdev_ops = {                         
1368     .ndo_open       = dm9000_open,                                               
1369     .ndo_stop       = dm9000_stop,                                               
1370     .ndo_start_xmit     = dm9000_start_xmit,                                     
1371     .ndo_tx_timeout     = dm9000_timeout,                                        
1372     .ndo_set_rx_mode    = dm9000_hash_table,                                     
1373     .ndo_do_ioctl       = dm9000_ioctl,                                          
1374     .ndo_set_features   = dm9000_set_features,                                   
1375     .ndo_validate_addr  = eth_validate_addr,                                     
1376     .ndo_set_mac_address    = eth_mac_addr,                                      
1377 #ifdef CONFIG_NET_POLL_CONTROLLER                                                
1378     .ndo_poll_controller    = dm9000_poll_controller,                            
1379 #endif                                                                           
1380 };
 731 static const struct ethtool_ops dm9000_ethtool_ops = {                           
 732     .get_drvinfo        = dm9000_get_drvinfo,                                    
 733     .get_msglevel       = dm9000_get_msglevel,                                   
 734     .set_msglevel       = dm9000_set_msglevel,                                   
 735     .nway_reset     = dm9000_nway_reset,                                         
 736     .get_link       = dm9000_get_link,                                           
 737     .get_wol        = dm9000_get_wol,                                            
 738     .set_wol        = dm9000_set_wol,                                            
 739     .get_eeprom_len     = dm9000_get_eeprom_len,                                 
 740     .get_eeprom     = dm9000_get_eeprom,                                         
 741     .set_eeprom     = dm9000_set_eeprom,                                         
 742     .get_link_ksettings = dm9000_get_link_ksettings,                             
 743     .set_link_ksettings = dm9000_set_link_ksettings,                             
 744 }; 
还有哪些接口
工作任务
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);

dm9000_poll_work
	...
	注意,如果不是 TYPE_DM9000E , 则 不会 循环调用

dm9000_interrupt // 中断调用
	schedule_delayed_work(&db->phy_poll, 1);
dm9000_open
	schedule_delayed_work(&db->phy_poll, 1);

盲猜是中断或者ifconfig eth0 up开启了这个循环调用
中断
dm9000_interrupt
dm9000_wol_interrupt
dm9000 驱动的 接口层次划分

在这里插入图片描述

dev_queue_xmit
	__dev_xmit_skb
		sch_direct_xmit
			dev_hard_start_xmit
				xmit_one
					netdev_start_xmit
						__netdev_start_xmit
							ops->ndo_start_xmit

static irqreturn_t dm9000_interrupt
	dm9000_tx_done
static irqreturn_t dm9000_interrupt
	dm9000_rx
		netif_rx
接口调用流程
发送数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接收数据

在这里插入图片描述

控制 TODO
其他ops接口什么时候会调用到 TODO

实例探索

用ftrace 抓取发送和接收过程
一个最少的网卡驱动要实现什么接口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值