i.MX 6ULL 驱动开发 二十八:网络设备

news/2024/11/28 15:47:16/

一、网络设备的系统框图

在这里插入图片描述
MAC:工作在网络模型的数据链路层,通过 RGMIIRMII 接口连接 PHYMAC 控制器中的 MDIO 控制器提供 MDIO 接口,用于访问 PHY 寄存器

PHY:工作在网络模型的物理层,是 IEEE802.3 规定的一个标准模块。IEEE802.3 规定了 地址 0~1516 个通用寄存器,只要配置好这些通用寄存器就能保证 PHY 芯片正常工作。16~31 地址的寄存器有厂家自行定义

二、以太网MII接口

扫盲-以太网MII接口类型大全-MII、RMII、SMII、GMII、RGMII、SGMII、XGMII、XAUI、RXAUI_heat.huang的博客-CSDN博客_rmii接口中的参考时钟频率

三、RJ45 接口

网络RJ45接口详解_迎客松88的博客-CSDN博客_rj45接口定义

四、PHY 芯片

1、PHY 基础知识

PHYIEEE 802.3 规定的一个标准模块。SOC 可以对 PHY 进行配置或者读取 PHY 相关状态,这个就需要 PHY 内部寄存器去实现了。 PHY 芯片寄存器地址空间为 5 位,地址 0~3132 个寄存器, IEEE 定义了 0~1516 个寄存器的功能, 16~3116 个寄存器由厂商自行实现。 也就是说不管你用的哪个厂家的 PHY 芯片,其中 0~1516 个寄存器是一模一样的。仅靠这 16 个寄存器是完全可以驱动起 PHY 芯片的,至少能保证基本的网络数据通信,因此 Linux 内核有通用 PHY 驱动,按道理来讲,不管你使用的哪个厂家的 PHY 芯片,都可以使用 Linux 的这个通用 PHY 驱动来验证网络工作是否正常。

事实上在实际开发中可能会遇到一些其他的问题导致 Linux 内核的通用 PHY 驱动工作不正常,这个时候就需要驱动开发人员去调
试了。

2、PHY 芯片寄存器相关说明

phy基础知识总结 common register总结_hello-Will的博客-CSDN博客

五、LAN8720A

详细信息参考 LAN8720A 官方手册。

六、Linux 网络驱动框架

1、网络设备

/***	struct net_device - The DEVICE structure.*		Actually, this whole structure is a big mistake.  It mixes I/O*		data with strictly "high-level" data, and it has to know about*		almost every data structure used in the INET module.**	@name:	This is the first field of the "visible" part of this structure*		(i.e. as seen by users in the "Space.c" file).  It is the name*	 	of the interface.**	@name_hlist: 	Device name hash chain, please keep it close to name[]*	@ifalias:	SNMP alias*	@mem_end:	Shared memory end*	@mem_start:	Shared memory start*	@base_addr:	Device I/O address*	@irq:		Device IRQ number**	@carrier_changes:	Stats to monitor carrier on<->off transitions**	@state:		Generic network queuing layer state, see netdev_state_t*	@dev_list:	The global list of network devices*	@napi_list:	List entry, that is used for polling napi devices*	@unreg_list:	List entry, that is used, when we are unregistering the*			device, see the function unregister_netdev*	@close_list:	List entry, that is used, when we are closing the device**	@adj_list:	Directly linked devices, like slaves for bonding*	@all_adj_list:	All linked devices, *including* neighbours*	@features:	Currently active device features*	@hw_features:	User-changeable features**	@wanted_features:	User-requested features*	@vlan_features:		Mask of features inheritable by VLAN devices**	@hw_enc_features:	Mask of features inherited by encapsulating devices*				This field indicates what encapsulation*				offloads the hardware is capable of doing,*				and drivers will need to set them appropriately.**	@mpls_features:	Mask of features inheritable by MPLS**	@ifindex:	interface index*	@group:		The group, that the device belongs to**	@stats:		Statistics struct, which was left as a legacy, use*			rtnl_link_stats64 instead**	@rx_dropped:	Dropped packets by core network,*			do not use this in drivers*	@tx_dropped:	Dropped packets by core network,*			do not use this in drivers**	@wireless_handlers:	List of functions to handle Wireless Extensions,*				instead of ioctl,*				see <net/iw_handler.h> for details.*	@wireless_data:	Instance data managed by the core of wireless extensions**	@netdev_ops:	Includes several pointers to callbacks,*			if one wants to override the ndo_*() functions*	@ethtool_ops:	Management operations*	@header_ops:	Includes callbacks for creating,parsing,caching,etc*			of Layer 2 headers.**	@flags:		Interface flags (a la BSD)*	@priv_flags:	Like 'flags' but invisible to userspace,*			see if.h for the definitions*	@gflags:	Global flags ( kept as legacy )*	@padded:	How much padding added by alloc_netdev()*	@operstate:	RFC2863 operstate*	@link_mode:	Mapping policy to operstate*	@if_port:	Selectable AUI, TP, ...*	@dma:		DMA channel*	@mtu:		Interface MTU value*	@type:		Interface hardware type*	@hard_header_len: Hardware header length**	@needed_headroom: Extra headroom the hardware may need, but not in all*			  cases can this be guaranteed*	@needed_tailroom: Extra tailroom the hardware may need, but not in all*			  cases can this be guaranteed. Some cases also use*			  LL_MAX_HEADER instead to allocate the skb**	interface address info:** 	@perm_addr:		Permanent hw address* 	@addr_assign_type:	Hw address assignment type* 	@addr_len:		Hardware address length* 	@neigh_priv_len;	Used in neigh_alloc(),* 				initialized only in atm/clip.c* 	@dev_id:		Used to differentiate devices that share* 				the same link layer address* 	@dev_port:		Used to differentiate devices that share* 				the same function*	@addr_list_lock:	XXX: need comments on this one*	@uc_promisc:		Counter, that indicates, that promiscuous mode*				has been enabled due to the need to listen to*				additional unicast addresses in a device that*				does not implement ndo_set_rx_mode()*	@uc:			unicast mac addresses*	@mc:			multicast mac addresses*	@dev_addrs:		list of device hw addresses*	@queues_kset:		Group of all Kobjects in the Tx and RX queues*	@promiscuity:		Number of times, the NIC is told to work in*				Promiscuous mode, if it becomes 0 the NIC will*				exit from working in Promiscuous mode*	@allmulti:		Counter, enables or disables allmulticast mode**	@vlan_info:	VLAN info*	@dsa_ptr:	dsa specific data*	@tipc_ptr:	TIPC specific data*	@atalk_ptr:	AppleTalk link*	@ip_ptr:	IPv4 specific data*	@dn_ptr:	DECnet specific data*	@ip6_ptr:	IPv6 specific data*	@ax25_ptr:	AX.25 specific data*	@ieee80211_ptr:	IEEE 802.11 specific data, assign before registering**	@last_rx:	Time of last Rx*	@dev_addr:	Hw address (before bcast,*			because most packets are unicast)**	@_rx:			Array of RX queues*	@num_rx_queues:		Number of RX queues*				allocated at register_netdev() time*	@real_num_rx_queues: 	Number of RX queues currently active in device**	@rx_handler:		handler for received packets*	@rx_handler_data: 	XXX: need comments on this one*	@ingress_queue:		XXX: need comments on this one*	@broadcast:		hw bcast address**	@rx_cpu_rmap:	CPU reverse-mapping for RX completion interrupts,*			indexed by RX queue number. Assigned by driver.*			This must only be set if the ndo_rx_flow_steer*			operation is defined*	@index_hlist:		Device index hash chain**	@_tx:			Array of TX queues*	@num_tx_queues:		Number of TX queues allocated at alloc_netdev_mq() time*	@real_num_tx_queues: 	Number of TX queues currently active in device*	@qdisc:			Root qdisc from userspace point of view*	@tx_queue_len:		Max frames per queue allowed*	@tx_global_lock: 	XXX: need comments on this one**	@xps_maps:	XXX: need comments on this one**	@trans_start:		Time (in jiffies) of last Tx*	@watchdog_timeo:	Represents the timeout that is used by*				the watchdog ( see dev_watchdog() )*	@watchdog_timer:	List of timers**	@pcpu_refcnt:		Number of references to this device*	@todo_list:		Delayed register/unregister*	@link_watch_list:	XXX: need comments on this one**	@reg_state:		Register/unregister state machine*	@dismantle:		Device is going to be freed*	@rtnl_link_state:	This enum represents the phases of creating*				a new link**	@destructor:		Called from unregister,*				can be used to call free_netdev*	@npinfo:		XXX: need comments on this one* 	@nd_net:		Network namespace this network device is inside** 	@ml_priv:	Mid-layer private* 	@lstats:	Loopback statistics* 	@tstats:	Tunnel statistics* 	@dstats:	Dummy statistics* 	@vstats:	Virtual ethernet statistics**	@garp_port:	GARP*	@mrp_port:	MRP**	@dev:		Class/net/name entry*	@sysfs_groups:	Space for optional device, statistics and wireless*			sysfs groups**	@sysfs_rx_queue_group:	Space for optional per-rx queue attributes*	@rtnl_link_ops:	Rtnl_link_ops**	@gso_max_size:	Maximum size of generic segmentation offload*	@gso_max_segs:	Maximum number of segments that can be passed to the*			NIC for GSO*	@gso_min_segs:	Minimum number of segments that can be passed to the*			NIC for GSO**	@dcbnl_ops:	Data Center Bridging netlink ops*	@num_tc:	Number of traffic classes in the net device*	@tc_to_txq:	XXX: need comments on this one*	@prio_tc_map	XXX: need comments on this one**	@fcoe_ddp_xid:	Max exchange id for FCoE LRO by ddp**	@priomap:	XXX: need comments on this one*	@phydev:	Physical device may attach itself*			for hardware timestamping**	@qdisc_tx_busylock:	XXX: need comments on this one**	FIXME: cleanup struct net_device such that network protocol info*	moves out.*/struct net_device {char			name[IFNAMSIZ];struct hlist_node	name_hlist;char 			*ifalias;/**	I/O specific fields*	FIXME: Merge these and struct ifmap into one*/unsigned long		mem_end;unsigned long		mem_start;unsigned long		base_addr;int			irq;atomic_t		carrier_changes;/**	Some hardware also needs these fields (state,dev_list,*	napi_list,unreg_list,close_list) but they are not*	part of the usual set specified in Space.c.*/unsigned long		state;struct list_head	dev_list;struct list_head	napi_list;struct list_head	unreg_list;struct list_head	close_list;struct list_head	ptype_all;struct list_head	ptype_specific;struct {struct list_head upper;struct list_head lower;} adj_list;struct {struct list_head upper;struct list_head lower;} all_adj_list;netdev_features_t	features;netdev_features_t	hw_features;netdev_features_t	wanted_features;netdev_features_t	vlan_features;netdev_features_t	hw_enc_features;netdev_features_t	mpls_features;int			ifindex;int			group;struct net_device_stats	stats;atomic_long_t		rx_dropped;atomic_long_t		tx_dropped;#ifdef CONFIG_WIRELESS_EXTconst struct iw_handler_def *	wireless_handlers;struct iw_public_data *	wireless_data;
#endifconst struct net_device_ops *netdev_ops;const struct ethtool_ops *ethtool_ops;
#ifdef CONFIG_NET_SWITCHDEVconst struct swdev_ops *swdev_ops;
#endifconst struct header_ops *header_ops;unsigned int		flags;unsigned int		priv_flags;unsigned short		gflags;unsigned short		padded;unsigned char		operstate;unsigned char		link_mode;unsigned char		if_port;unsigned char		dma;unsigned int		mtu;unsigned short		type;unsigned short		hard_header_len;unsigned short		needed_headroom;unsigned short		needed_tailroom;/* Interface address info. */unsigned char		perm_addr[MAX_ADDR_LEN];unsigned char		addr_assign_type;unsigned char		addr_len;unsigned short		neigh_priv_len;unsigned short          dev_id;unsigned short          dev_port;spinlock_t		addr_list_lock;unsigned char		name_assign_type;bool			uc_promisc;struct netdev_hw_addr_list	uc;struct netdev_hw_addr_list	mc;struct netdev_hw_addr_list	dev_addrs;#ifdef CONFIG_SYSFSstruct kset		*queues_kset;
#endifunsigned int		promiscuity;unsigned int		allmulti;/* Protocol specific pointers */#if IS_ENABLED(CONFIG_VLAN_8021Q)struct vlan_info __rcu	*vlan_info;
#endif
#if IS_ENABLED(CONFIG_NET_DSA)struct dsa_switch_tree	*dsa_ptr;
#endif
#if IS_ENABLED(CONFIG_TIPC)struct tipc_bearer __rcu *tipc_ptr;
#endifvoid 			*atalk_ptr;struct in_device __rcu	*ip_ptr;struct dn_dev __rcu     *dn_ptr;struct inet6_dev __rcu	*ip6_ptr;void			*ax25_ptr;struct wireless_dev	*ieee80211_ptr;struct wpan_dev		*ieee802154_ptr;
#if IS_ENABLED(CONFIG_MPLS_ROUTING)struct mpls_dev __rcu	*mpls_ptr;
#endif/** Cache lines mostly used on receive path (including eth_type_trans())*/unsigned long		last_rx;/* Interface address info used in eth_type_trans() */unsigned char		*dev_addr;#ifdef CONFIG_SYSFSstruct netdev_rx_queue	*_rx;unsigned int		num_rx_queues;unsigned int		real_num_rx_queues;#endifunsigned long		gro_flush_timeout;rx_handler_func_t __rcu	*rx_handler;void __rcu		*rx_handler_data;struct netdev_queue __rcu *ingress_queue;unsigned char		broadcast[MAX_ADDR_LEN];
#ifdef CONFIG_RFS_ACCELstruct cpu_rmap		*rx_cpu_rmap;
#endifstruct hlist_node	index_hlist;/** Cache lines mostly used on transmit path*/struct netdev_queue	*_tx ____cacheline_aligned_in_smp;unsigned int		num_tx_queues;unsigned int		real_num_tx_queues;struct Qdisc		*qdisc;unsigned long		tx_queue_len;spinlock_t		tx_global_lock;int			watchdog_timeo;#ifdef CONFIG_XPSstruct xps_dev_maps __rcu *xps_maps;
#endif/* These may be needed for future network-power-down code. *//** trans_start here is expensive for high speed devices on SMP,* please use netdev_queue->trans_start instead.*/unsigned long		trans_start;struct timer_list	watchdog_timer;int __percpu		*pcpu_refcnt;struct list_head	todo_list;struct list_head	link_watch_list;enum { NETREG_UNINITIALIZED=0,NETREG_REGISTERED,	/* completed register_netdevice */NETREG_UNREGISTERING,	/* called unregister_netdevice */NETREG_UNREGISTERED,	/* completed unregister todo */NETREG_RELEASED,		/* called free_netdev */NETREG_DUMMY,		/* dummy device for NAPI poll */} reg_state:8;bool dismantle;enum {RTNL_LINK_INITIALIZED,RTNL_LINK_INITIALIZING,} rtnl_link_state:16;void (*destructor)(struct net_device *dev);#ifdef CONFIG_NETPOLLstruct netpoll_info __rcu	*npinfo;
#endifpossible_net_t			nd_net;/* mid-layer private */union {void					*ml_priv;struct pcpu_lstats __percpu		*lstats;struct pcpu_sw_netstats __percpu	*tstats;struct pcpu_dstats __percpu		*dstats;struct pcpu_vstats __percpu		*vstats;};struct garp_port __rcu	*garp_port;struct mrp_port __rcu	*mrp_port;struct device	dev;const struct attribute_group *sysfs_groups[4];const struct attribute_group *sysfs_rx_queue_group;const struct rtnl_link_ops *rtnl_link_ops;/* for setting kernel sock attribute on TCP connection setup */
#define GSO_MAX_SIZE		65536unsigned int		gso_max_size;
#define GSO_MAX_SEGS		65535u16			gso_max_segs;u16			gso_min_segs;
#ifdef CONFIG_DCBconst struct dcbnl_rtnl_ops *dcbnl_ops;
#endifu8 num_tc;struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];u8 prio_tc_map[TC_BITMASK + 1];#if IS_ENABLED(CONFIG_FCOE)unsigned int		fcoe_ddp_xid;
#endif
#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)struct netprio_map __rcu *priomap;
#endifstruct phy_device *phydev;struct lock_class_key *qdisc_tx_busylock;
};

2、网络操作集

/** This structure defines the management hooks for network devices.* The following hooks can be defined; unless noted otherwise, they are* optional and can be filled with a null pointer.** int (*ndo_init)(struct net_device *dev);*     This function is called once when network device is registered.*     The network device can use this to any late stage initializaton*     or semantic validattion. It can fail with an error code which will*     be propogated back to register_netdev** void (*ndo_uninit)(struct net_device *dev);*     This function is called when device is unregistered or when registration*     fails. It is not called if init fails.** int (*ndo_open)(struct net_device *dev);*     This function is called when network device transistions to the up*     state.** int (*ndo_stop)(struct net_device *dev);*     This function is called when network device transistions to the down*     state.** netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,*                               struct net_device *dev);*	Called when a packet needs to be transmitted.*	Returns NETDEV_TX_OK.  Can return NETDEV_TX_BUSY, but you should stop*	the queue before that can happen; it's for obsolete devices and weird*	corner cases, but the stack really does a non-trivial amount*	of useless work if you return NETDEV_TX_BUSY.*        (can also return NETDEV_TX_LOCKED iff NETIF_F_LLTX)*	Required can not be NULL.** u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb,*                         void *accel_priv, select_queue_fallback_t fallback);*	Called to decide which queue to when device supports multiple*	transmit queues.** void (*ndo_change_rx_flags)(struct net_device *dev, int flags);*	This function is called to allow device receiver to make*	changes to configuration when multicast or promiscious is enabled.** void (*ndo_set_rx_mode)(struct net_device *dev);*	This function is called device changes address list filtering.*	If driver handles unicast address filtering, it should set*	IFF_UNICAST_FLT to its priv_flags.** int (*ndo_set_mac_address)(struct net_device *dev, void *addr);*	This function  is called when the Media Access Control address*	needs to be changed. If this interface is not defined, the*	mac address can not be changed.** int (*ndo_validate_addr)(struct net_device *dev);*	Test if Media Access Control address is valid for the device.** int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);*	Called when a user request an ioctl which can't be handled by*	the generic interface code. If not defined ioctl's return*	not supported error code.** int (*ndo_set_config)(struct net_device *dev, struct ifmap *map);*	Used to set network devices bus interface parameters. This interface*	is retained for legacy reason, new devices should use the bus*	interface (PCI) for low level management.** int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);*	Called when a user wants to change the Maximum Transfer Unit*	of a device. If not defined, any request to change MTU will*	will return an error.** void (*ndo_tx_timeout)(struct net_device *dev);*	Callback uses when the transmitter has not made any progress*	for dev->watchdog ticks.** struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,*                      struct rtnl_link_stats64 *storage);* struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);*	Called when a user wants to get the network device usage*	statistics. Drivers must do one of the following:*	1. Define @ndo_get_stats64 to fill in a zero-initialised*	   rtnl_link_stats64 structure passed by the caller.*	2. Define @ndo_get_stats to update a net_device_stats structure*	   (which should normally be dev->stats) and return a pointer to*	   it. The structure may be changed asynchronously only if each*	   field is written atomically.*	3. Update dev->stats asynchronously and atomically, and define*	   neither operation.** int (*ndo_vlan_rx_add_vid)(struct net_device *dev, __be16 proto, u16 vid);*	If device support VLAN filtering this function is called when a*	VLAN id is registered.** int (*ndo_vlan_rx_kill_vid)(struct net_device *dev, __be16 proto, u16 vid);*	If device support VLAN filtering this function is called when a*	VLAN id is unregistered.** void (*ndo_poll_controller)(struct net_device *dev);**	SR-IOV management functions.* int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac);* int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos);* int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate,*			  int max_tx_rate);* int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);* int (*ndo_get_vf_config)(struct net_device *dev,*			    int vf, struct ifla_vf_info *ivf);* int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);* int (*ndo_set_vf_port)(struct net_device *dev, int vf,*			  struct nlattr *port[]);**      Enable or disable the VF ability to query its RSS Redirection Table and*      Hash Key. This is needed since on some devices VF share this information*      with PF and querying it may adduce a theoretical security risk.* int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);* int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);* int (*ndo_setup_tc)(struct net_device *dev, u8 tc)* 	Called to setup 'tc' number of traffic classes in the net device. This* 	is always called from the stack with the rtnl lock held and netif tx* 	queues stopped. This allows the netdevice to perform queue management* 	safely.**	Fiber Channel over Ethernet (FCoE) offload functions.* int (*ndo_fcoe_enable)(struct net_device *dev);*	Called when the FCoE protocol stack wants to start using LLD for FCoE*	so the underlying device can perform whatever needed configuration or*	initialization to support acceleration of FCoE traffic.** int (*ndo_fcoe_disable)(struct net_device *dev);*	Called when the FCoE protocol stack wants to stop using LLD for FCoE*	so the underlying device can perform whatever needed clean-ups to*	stop supporting acceleration of FCoE traffic.** int (*ndo_fcoe_ddp_setup)(struct net_device *dev, u16 xid,*			     struct scatterlist *sgl, unsigned int sgc);*	Called when the FCoE Initiator wants to initialize an I/O that*	is a possible candidate for Direct Data Placement (DDP). The LLD can*	perform necessary setup and returns 1 to indicate the device is set up*	successfully to perform DDP on this I/O, otherwise this returns 0.** int (*ndo_fcoe_ddp_done)(struct net_device *dev,  u16 xid);*	Called when the FCoE Initiator/Target is done with the DDPed I/O as*	indicated by the FC exchange id 'xid', so the underlying device can*	clean up and reuse resources for later DDP requests.** int (*ndo_fcoe_ddp_target)(struct net_device *dev, u16 xid,*			      struct scatterlist *sgl, unsigned int sgc);*	Called when the FCoE Target wants to initialize an I/O that*	is a possible candidate for Direct Data Placement (DDP). The LLD can*	perform necessary setup and returns 1 to indicate the device is set up*	successfully to perform DDP on this I/O, otherwise this returns 0.** int (*ndo_fcoe_get_hbainfo)(struct net_device *dev,*			       struct netdev_fcoe_hbainfo *hbainfo);*	Called when the FCoE Protocol stack wants information on the underlying*	device. This information is utilized by the FCoE protocol stack to*	register attributes with Fiber Channel management service as per the*	FC-GS Fabric Device Management Information(FDMI) specification.** int (*ndo_fcoe_get_wwn)(struct net_device *dev, u64 *wwn, int type);*	Called when the underlying device wants to override default World Wide*	Name (WWN) generation mechanism in FCoE protocol stack to pass its own*	World Wide Port Name (WWPN) or World Wide Node Name (WWNN) to the FCoE*	protocol stack to use.**	RFS acceleration.* int (*ndo_rx_flow_steer)(struct net_device *dev, const struct sk_buff *skb,*			    u16 rxq_index, u32 flow_id);*	Set hardware filter for RFS.  rxq_index is the target queue index;*	flow_id is a flow ID to be passed to rps_may_expire_flow() later.*	Return the filter ID on success, or a negative error code.**	Slave management functions (for bridge, bonding, etc).* int (*ndo_add_slave)(struct net_device *dev, struct net_device *slave_dev);*	Called to make another netdev an underling.** int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev);*	Called to release previously enslaved netdev.**      Feature/offload setting functions.* netdev_features_t (*ndo_fix_features)(struct net_device *dev,*		netdev_features_t features);*	Adjusts the requested feature flags according to device-specific*	constraints, and returns the resulting flags. Must not modify*	the device state.** int (*ndo_set_features)(struct net_device *dev, netdev_features_t features);*	Called to update device configuration to new features. Passed*	feature set might be less than what was returned by ndo_fix_features()).*	Must return >0 or -errno if it changed dev->features itself.** int (*ndo_fdb_add)(struct ndmsg *ndm, struct nlattr *tb[],*		      struct net_device *dev,*		      const unsigned char *addr, u16 vid, u16 flags)*	Adds an FDB entry to dev for addr.* int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[],*		      struct net_device *dev,*		      const unsigned char *addr, u16 vid)*	Deletes the FDB entry from dev coresponding to addr.* int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,*		       struct net_device *dev, struct net_device *filter_dev,*		       int idx)*	Used to add FDB entries to dump requests. Implementers should add*	entries to skb and update idx with the number of entries.** int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh,*			     u16 flags)* int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,*			     struct net_device *dev, u32 filter_mask,*			     int nlflags)* int (*ndo_bridge_dellink)(struct net_device *dev, struct nlmsghdr *nlh,*			     u16 flags);** int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier);*	Called to change device carrier. Soft-devices (like dummy, team, etc)*	which do not represent real hardware may define this to allow their*	userspace components to manage their virtual carrier state. Devices*	that determine carrier state from physical hardware properties (eg*	network cables) or protocol-dependent mechanisms (eg*	USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.** int (*ndo_get_phys_port_id)(struct net_device *dev,*			       struct netdev_phys_item_id *ppid);*	Called to get ID of physical port of this device. If driver does*	not implement this, it is assumed that the hw is not able to have*	multiple net devices on single physical port.** void (*ndo_add_vxlan_port)(struct  net_device *dev,*			      sa_family_t sa_family, __be16 port);*	Called by vxlan to notiy a driver about the UDP port and socket*	address family that vxlan is listnening to. It is called only when*	a new port starts listening. The operation is protected by the*	vxlan_net->sock_lock.** void (*ndo_del_vxlan_port)(struct  net_device *dev,*			      sa_family_t sa_family, __be16 port);*	Called by vxlan to notify the driver about a UDP port and socket*	address family that vxlan is not listening to anymore. The operation*	is protected by the vxlan_net->sock_lock.** void* (*ndo_dfwd_add_station)(struct net_device *pdev,*				 struct net_device *dev)*	Called by upper layer devices to accelerate switching or other*	station functionality into hardware. 'pdev is the lowerdev*	to use for the offload and 'dev' is the net device that will*	back the offload. Returns a pointer to the private structure*	the upper layer will maintain.* void (*ndo_dfwd_del_station)(struct net_device *pdev, void *priv)*	Called by upper layer device to delete the station created*	by 'ndo_dfwd_add_station'. 'pdev' is the net device backing*	the station and priv is the structure returned by the add*	operation.* netdev_tx_t (*ndo_dfwd_start_xmit)(struct sk_buff *skb,*				      struct net_device *dev,*				      void *priv);*	Callback to use for xmit over the accelerated station. This*	is used in place of ndo_start_xmit on accelerated net*	devices.* netdev_features_t (*ndo_features_check) (struct sk_buff *skb,*					    struct net_device *dev*					    netdev_features_t features);*	Called by core transmit path to determine if device is capable of*	performing offload operations on a given packet. This is to give*	the device an opportunity to implement any restrictions that cannot*	be otherwise expressed by feature flags. The check is called with*	the set of features that the stack has calculated and it returns*	those the driver believes to be appropriate.* int (*ndo_set_tx_maxrate)(struct net_device *dev,*			     int queue_index, u32 maxrate);*	Called when a user wants to set a max-rate limitation of specific*	TX queue.* int (*ndo_get_iflink)(const struct net_device *dev);*	Called to get the iflink value of this device.*/
struct net_device_ops {int			(*ndo_init)(struct net_device *dev);void			(*ndo_uninit)(struct net_device *dev);int			(*ndo_open)(struct net_device *dev);int			(*ndo_stop)(struct net_device *dev);netdev_tx_t		(*ndo_start_xmit) (struct sk_buff *skb,struct net_device *dev);u16			(*ndo_select_queue)(struct net_device *dev,struct sk_buff *skb,void *accel_priv,select_queue_fallback_t fallback);void			(*ndo_change_rx_flags)(struct net_device *dev,int flags);void			(*ndo_set_rx_mode)(struct net_device *dev);int			(*ndo_set_mac_address)(struct net_device *dev,void *addr);int			(*ndo_validate_addr)(struct net_device *dev);int			(*ndo_do_ioctl)(struct net_device *dev,struct ifreq *ifr, int cmd);int			(*ndo_set_config)(struct net_device *dev,struct ifmap *map);int			(*ndo_change_mtu)(struct net_device *dev,int new_mtu);int			(*ndo_neigh_setup)(struct net_device *dev,struct neigh_parms *);void			(*ndo_tx_timeout) (struct net_device *dev);struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,struct rtnl_link_stats64 *storage);struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);int			(*ndo_vlan_rx_add_vid)(struct net_device *dev,__be16 proto, u16 vid);int			(*ndo_vlan_rx_kill_vid)(struct net_device *dev,__be16 proto, u16 vid);
#ifdef CONFIG_NET_POLL_CONTROLLERvoid                    (*ndo_poll_controller)(struct net_device *dev);int			(*ndo_netpoll_setup)(struct net_device *dev,struct netpoll_info *info);void			(*ndo_netpoll_cleanup)(struct net_device *dev);
#endif
#ifdef CONFIG_NET_RX_BUSY_POLLint			(*ndo_busy_poll)(struct napi_struct *dev);
#endifint			(*ndo_set_vf_mac)(struct net_device *dev,int queue, u8 *mac);int			(*ndo_set_vf_vlan)(struct net_device *dev,int queue, u16 vlan, u8 qos);int			(*ndo_set_vf_rate)(struct net_device *dev,int vf, int min_tx_rate,int max_tx_rate);int			(*ndo_set_vf_spoofchk)(struct net_device *dev,int vf, bool setting);int			(*ndo_get_vf_config)(struct net_device *dev,int vf,struct ifla_vf_info *ivf);int			(*ndo_set_vf_link_state)(struct net_device *dev,int vf, int link_state);int			(*ndo_set_vf_port)(struct net_device *dev,int vf,struct nlattr *port[]);int			(*ndo_get_vf_port)(struct net_device *dev,int vf, struct sk_buff *skb);int			(*ndo_set_vf_rss_query_en)(struct net_device *dev,int vf, bool setting);int			(*ndo_setup_tc)(struct net_device *dev, u8 tc);
#if IS_ENABLED(CONFIG_FCOE)int			(*ndo_fcoe_enable)(struct net_device *dev);int			(*ndo_fcoe_disable)(struct net_device *dev);int			(*ndo_fcoe_ddp_setup)(struct net_device *dev,u16 xid,struct scatterlist *sgl,unsigned int sgc);int			(*ndo_fcoe_ddp_done)(struct net_device *dev,u16 xid);int			(*ndo_fcoe_ddp_target)(struct net_device *dev,u16 xid,struct scatterlist *sgl,unsigned int sgc);int			(*ndo_fcoe_get_hbainfo)(struct net_device *dev,struct netdev_fcoe_hbainfo *hbainfo);
#endif#if IS_ENABLED(CONFIG_LIBFCOE)
#define NETDEV_FCOE_WWNN 0
#define NETDEV_FCOE_WWPN 1int			(*ndo_fcoe_get_wwn)(struct net_device *dev,u64 *wwn, int type);
#endif#ifdef CONFIG_RFS_ACCELint			(*ndo_rx_flow_steer)(struct net_device *dev,const struct sk_buff *skb,u16 rxq_index,u32 flow_id);
#endifint			(*ndo_add_slave)(struct net_device *dev,struct net_device *slave_dev);int			(*ndo_del_slave)(struct net_device *dev,struct net_device *slave_dev);netdev_features_t	(*ndo_fix_features)(struct net_device *dev,netdev_features_t features);int			(*ndo_set_features)(struct net_device *dev,netdev_features_t features);int			(*ndo_neigh_construct)(struct neighbour *n);void			(*ndo_neigh_destroy)(struct neighbour *n);int			(*ndo_fdb_add)(struct ndmsg *ndm,struct nlattr *tb[],struct net_device *dev,const unsigned char *addr,u16 vid,u16 flags);int			(*ndo_fdb_del)(struct ndmsg *ndm,struct nlattr *tb[],struct net_device *dev,const unsigned char *addr,u16 vid);int			(*ndo_fdb_dump)(struct sk_buff *skb,struct netlink_callback *cb,struct net_device *dev,struct net_device *filter_dev,int idx);int			(*ndo_bridge_setlink)(struct net_device *dev,struct nlmsghdr *nlh,u16 flags);int			(*ndo_bridge_getlink)(struct sk_buff *skb,u32 pid, u32 seq,struct net_device *dev,u32 filter_mask,int nlflags);int			(*ndo_bridge_dellink)(struct net_device *dev,struct nlmsghdr *nlh,u16 flags);int			(*ndo_change_carrier)(struct net_device *dev,bool new_carrier);int			(*ndo_get_phys_port_id)(struct net_device *dev,struct netdev_phys_item_id *ppid);int			(*ndo_get_phys_port_name)(struct net_device *dev,char *name, size_t len);void			(*ndo_add_vxlan_port)(struct  net_device *dev,sa_family_t sa_family,__be16 port);void			(*ndo_del_vxlan_port)(struct  net_device *dev,sa_family_t sa_family,__be16 port);void*			(*ndo_dfwd_add_station)(struct net_device *pdev,struct net_device *dev);void			(*ndo_dfwd_del_station)(struct net_device *pdev,void *priv);netdev_tx_t		(*ndo_dfwd_start_xmit) (struct sk_buff *skb,struct net_device *dev,void *priv);int			(*ndo_get_lock_subclass)(struct net_device *dev);netdev_features_t	(*ndo_features_check) (struct sk_buff *skb,struct net_device *dev,netdev_features_t features);int			(*ndo_set_tx_maxrate)(struct net_device *dev,int queue_index,u32 maxrate);int			(*ndo_get_iflink)(const struct net_device *dev);
};

3、信息的载体

/** *	struct sk_buff - socket buffer*	@next: Next buffer in list*	@prev: Previous buffer in list*	@tstamp: Time we arrived/left*	@rbnode: RB tree node, alternative to next/prev for netem/tcp*	@sk: Socket we are owned by*	@dev: Device we arrived on/are leaving by*	@cb: Control buffer. Free for use by every layer. Put private vars here*	@_skb_refdst: destination entry (with norefcount bit)*	@sp: the security path, used for xfrm*	@len: Length of actual data*	@data_len: Data length*	@mac_len: Length of link layer header*	@hdr_len: writable header length of cloned skb*	@csum: Checksum (must include start/offset pair)*	@csum_start: Offset from skb->head where checksumming should start*	@csum_offset: Offset from csum_start where checksum should be stored*	@priority: Packet queueing priority*	@ignore_df: allow local fragmentation*	@cloned: Head may be cloned (check refcnt to be sure)*	@ip_summed: Driver fed us an IP checksum*	@nohdr: Payload reference only, must not modify header*	@nfctinfo: Relationship of this skb to the connection*	@pkt_type: Packet class*	@fclone: skbuff clone status*	@ipvs_property: skbuff is owned by ipvs*	@peeked: this packet has been seen already, so stats have been*		done for it, don't do them again*	@nf_trace: netfilter packet trace flag*	@protocol: Packet protocol from driver*	@destructor: Destruct function*	@nfct: Associated connection, if any*	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c*	@skb_iif: ifindex of device we arrived on*	@tc_index: Traffic control index*	@tc_verd: traffic control verdict*	@hash: the packet hash*	@queue_mapping: Queue mapping for multiqueue devices*	@xmit_more: More SKBs are pending for this queue*	@ndisc_nodetype: router type (from link layer)*	@ooo_okay: allow the mapping of a socket to a queue to be changed*	@l4_hash: indicate hash is a canonical 4-tuple hash over transport*		ports.*	@sw_hash: indicates hash was computed in software stack*	@wifi_acked_valid: wifi_acked was set*	@wifi_acked: whether frame was acked on wifi or not*	@no_fcs:  Request NIC to treat last 4 bytes as Ethernet FCS*	@napi_id: id of the NAPI struct this skb came from*	@secmark: security marking*	@mark: Generic packet mark*	@vlan_proto: vlan encapsulation protocol*	@vlan_tci: vlan tag control information*	@inner_protocol: Protocol (encapsulation)*	@inner_transport_header: Inner transport layer header (encapsulation)*	@inner_network_header: Network layer header (encapsulation)*	@inner_mac_header: Link layer header (encapsulation)*	@transport_header: Transport layer header*	@network_header: Network layer header*	@mac_header: Link layer header*	@tail: Tail pointer*	@end: End pointer*	@head: Head of buffer*	@data: Data head pointer*	@truesize: Buffer size*	@users: User count - see {datagram,tcp}.c*/struct sk_buff {union {struct {/* These two members must be first. */struct sk_buff		*next;struct sk_buff		*prev;union {ktime_t		tstamp;struct skb_mstamp skb_mstamp;};};struct rb_node	rbnode; /* used in netem & tcp stack */};struct sock		*sk;struct net_device	*dev;/** This is the control buffer. It is free to use for every* layer. Please put your private variables there. If you* want to keep them across layers you have to do a skb_clone()* first. This is owned by whoever has the skb queued ATM.*/char			cb[48] __aligned(8);unsigned long		_skb_refdst;void			(*destructor)(struct sk_buff *skb);
#ifdef CONFIG_XFRMstruct	sec_path	*sp;
#endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)struct nf_conntrack	*nfct;
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)struct nf_bridge_info	*nf_bridge;
#endifunsigned int		len,data_len;__u16			mac_len,hdr_len;/* Following fields are _not_ copied in __copy_skb_header()* Note that queue_mapping is here mostly to fill a hole.*/kmemcheck_bitfield_begin(flags1);__u16			queue_mapping;__u8			cloned:1,nohdr:1,fclone:2,peeked:1,head_frag:1,xmit_more:1;/* one bit hole */kmemcheck_bitfield_end(flags1);/* fields enclosed in headers_start/headers_end are copied* using a single memcpy() in __copy_skb_header()*//* private: */__u32			headers_start[0];/* public: *//* if you move pkt_type around you also must adapt those constants */
#ifdef __BIG_ENDIAN_BITFIELD
#define PKT_TYPE_MAX	(7 << 5)
#else
#define PKT_TYPE_MAX	7
#endif
#define PKT_TYPE_OFFSET()	offsetof(struct sk_buff, __pkt_type_offset)__u8			__pkt_type_offset[0];__u8			pkt_type:3;__u8			pfmemalloc:1;__u8			ignore_df:1;__u8			nfctinfo:3;__u8			nf_trace:1;__u8			ip_summed:2;__u8			ooo_okay:1;__u8			l4_hash:1;__u8			sw_hash:1;__u8			wifi_acked_valid:1;__u8			wifi_acked:1;__u8			no_fcs:1;/* Indicates the inner headers are valid in the skbuff. */__u8			encapsulation:1;__u8			encap_hdr_csum:1;__u8			csum_valid:1;__u8			csum_complete_sw:1;__u8			csum_level:2;__u8			csum_bad:1;#ifdef CONFIG_IPV6_NDISC_NODETYPE__u8			ndisc_nodetype:2;
#endif__u8			ipvs_property:1;__u8			inner_protocol_type:1;__u8			remcsum_offload:1;/* 3 or 5 bit hole */#ifdef CONFIG_NET_SCHED__u16			tc_index;	/* traffic control index */
#ifdef CONFIG_NET_CLS_ACT__u16			tc_verd;	/* traffic control verdict */
#endif
#endifunion {__wsum		csum;struct {__u16	csum_start;__u16	csum_offset;};};__u32			priority;int			skb_iif;__u32			hash;__be16			vlan_proto;__u16			vlan_tci;
#if defined(CONFIG_NET_RX_BUSY_POLL) || defined(CONFIG_XPS)union {unsigned int	napi_id;unsigned int	sender_cpu;};
#endif
#ifdef CONFIG_NETWORK_SECMARK__u32			secmark;
#endifunion {__u32		mark;__u32		reserved_tailroom;};union {__be16		inner_protocol;__u8		inner_ipproto;};__u16			inner_transport_header;__u16			inner_network_header;__u16			inner_mac_header;__be16			protocol;__u16			transport_header;__u16			network_header;__u16			mac_header;/* private: */__u32			headers_end[0];/* public: *//* These elements must be at the end, see alloc_skb() for details.  */sk_buff_data_t		tail;sk_buff_data_t		end;unsigned char		*head,*data;unsigned int		truesize;atomic_t		users;
};

七、NAPI 处理机制

Linux网络协议栈:NAPI机制与处理流程分析(图解)_rtoax的博客-CSDN博客_netif_napi_add

八、imx6ull 网络设备树说明

参考:Documentation/devicetree/bindings/net/fsl-fec.txt

九、imx6ull 网络驱动

源码见:drivers\net\ethernet\freescale\fec_main.c

十、通用 PHY 驱动

源码见:drivers\net\phy\phy_device.c

十一、LAN8720A 驱动

源码见:drivers\net\phy\smsc.c


http://www.ppmy.cn/news/1660.html

相关文章

OpenCV入门(C++/Python)- 使用OpenCV调整尺寸大小(三)

使用OpenCV调整图像大小。要调整图像的大小&#xff0c;可以根据每个轴&#xff08;高度和宽度&#xff09;进行缩放&#xff0c;考虑指定的缩放因素&#xff0c;或者只需设置所需的高度和宽度。 调整图像大小时&#xff1a; 如果想在调整后的图像中保持相同的宽高比&#xf…

【HTML期末作业】大学生抗疫感动专题网页设计作业 抗疫最美逆行者网页 致敬疫情感动人物网页设计制作

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

深度学习 RNN循环神经网络原理与Pytorch正余弦值预测

深度学习 RNN循环神经网络原理与Pytorch正余弦值预测一、前言二、序列模型三、不含序列关联的神经网络四、包含隐藏状态的卷积神经网络五、正余弦预测实战六、参考资料一、前言 前面我们学习了前馈神经网络、卷积神经网络&#xff0c;它们有一个特点&#xff0c;就是每次输出跟…

做了8年前端,感谢那些优秀的后端,陪伴我工作,教会我成长

☆ 前段时间由于一时的头脑发热&#xff0c;写了一篇《做了8年前端&#xff0c;细说那些曾经让你浴霸不能的后端》的博客&#xff0c;虽然每个细节也都属实吧&#xff0c;但始终是一些负能量的东西&#xff0c;建议大家不要去看了&#xff0c;今年互联网情况已经这样了&#xf…

Python学习小组课程P6-Python办公(3)邮件与钉钉消息通知

Python办公&#xff08;3&#xff09;邮件与钉钉消息通知一、前言二、知识点1 发送邮件2 钉钉机器人消息通知一、前言 注意&#xff1a;此为内部小组学习资料&#xff0c;非售卖品&#xff0c;仅供学习参考。 本系列课程&#xff1a; Python学习小组课程-课程大纲与Python开发…

Java实现 LeetCode 500.键盘行

500.键盘行 给你一个字符串数组 words &#xff0c;只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 美式键盘 中&#xff1a; 第一行由字符 “qwertyuiop” 组成。第二行由字符 “asdfghjkl” 组成。第三行由字符 “zxcvbnm” 组成。 示例 1&…

工业物联网关-modbus数据采集程序(1-程序设计)

写代码之前 最近代码写慢了&#xff0c;磨了好久都没开始动手写代码。考虑的东西越多越多&#xff0c;甚至自己都认为过虑了。就像这个程序&#xff0c;写代码之前估计花了大半天或者一天在思考怎么写&#xff0c;不知道是好事还是年纪大了。所以专门写篇文章&#xff0c;把自…

Android请求应用权限

文章目录前言参考一、请求应用权限基本原则二、请求权限的流程&#xff08;官网摘抄&#xff09;三、请求权限编码1.允许系统管理权限请求代码2.自行管理权限请求代码总结前言 学习Android为什么需要动态申请危险权限 学会Android应用危险权限申请的方式 参考 Android官方文档…