一、网络设备的系统框图
MAC
:工作在网络模型的数据链路层,通过 RGMII
或 RMII
接口连接 PHY
,MAC
控制器中的 MDIO
控制器提供 MDIO
接口,用于访问 PHY
寄存器。
PHY
:工作在网络模型的物理层,是 IEEE802.3
规定的一个标准模块。IEEE802.3
规定了 地址 0~15
共 16
个通用寄存器,只要配置好这些通用寄存器就能保证 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 基础知识
PHY
是 IEEE 802.3
规定的一个标准模块。SOC
可以对 PHY
进行配置或者读取 PHY 相关状态,这个就需要 PHY
内部寄存器去实现了。 PHY
芯片寄存器地址空间为 5
位,地址 0~31
共 32
个寄存器, IEEE
定义了 0~15
这 16
个寄存器的功能, 16~31
这 16
个寄存器由厂商自行实现。 也就是说不管你用的哪个厂家的 PHY
芯片,其中 0~15
这 16
个寄存器是一模一样的。仅靠这 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
。