国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)

這篇具有很好參考價值的文章主要介紹了linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

  • 網(wǎng)絡(luò)驅(qū)動的核心:
    1、就是初始化 net_device 結(jié)構(gòu)體中的各個成員變量,
    2、然后將初始化完成以后的 net_device 注冊到 Linux 內(nèi)核中

1、網(wǎng)絡(luò)設(shè)備(用net_device結(jié)構(gòu)體)

/*
@	net_device 結(jié)構(gòu)體 
*/
  struct net_device { 
      char                  name[IFNAMSIZ]; /*網(wǎng)絡(luò)設(shè)備名字*/
      struct hlist_node     name_hlist; 
      char                  *ifalias; 
      
      unsigned long        mem_end;/*共享內(nèi)存結(jié)束地址*/
      unsigned long       mem_start;/*共享內(nèi)存起始地址*/
      unsigned long         base_addr; /*網(wǎng)絡(luò)設(shè)備IO地址*/
      int               irq; /*網(wǎng)絡(luò)設(shè)備的中斷號*/
   
      atomic_t            carrier_changes; 
     unsigned long         state; 
  
     struct list_head      dev_list; /*全局網(wǎng)絡(luò)設(shè)備列表*/
     struct list_head      napi_list;/*napi機制==napi設(shè)備的列表入口*/ 
     struct list_head      unreg_list;/*注銷網(wǎng)絡(luò)設(shè)備的列表入口*/ 
     struct list_head      close_list; /*關(guān)閉的網(wǎng)絡(luò)設(shè)備列表入口*/
... 
     const struct net_device_ops *netdev_ops; /*網(wǎng)絡(luò)設(shè)備的操作集函數(shù)*/
     const struct ethtool_ops   *ethtool_ops; /*網(wǎng)絡(luò)管理工具相關(guān)函數(shù)集*/
 #ifdef CONFIG_NET_SWITCHDEV 
     const struct swdev_ops     *swdev_ops; 
 #endif 
  
     const struct header_ops     *header_ops; /*頭部的相關(guān)操作函數(shù)集,比如創(chuàng)建、解析、緩沖等*/
  
     unsigned int          flags; /*網(wǎng)絡(luò)接口標志*/
...  
     unsigned char         if_port; /*指定接口的端口類型*/
     unsigned char         dma; /*網(wǎng)絡(luò)設(shè)備所使用的DMA通道*/
  
     unsigned int          mtu; /*網(wǎng)絡(luò)最大傳輸單元*/
     unsigned short        type;/*指定 ARP模塊的類型*/ 
     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; /*硬件地址長度。*/
... 
 /* 
  * Cache lines mostly used on receive path (including  
eth_type_trans()) 
  */ 
     unsigned long         last_rx; /*最后接收的數(shù)據(jù)包時間戳,記錄的是jiffies*/
  
     /* Interface address info used in eth_type_trans() */ 
     unsigned char         *dev_addr; /*硬件地址,是當前分配的MAC 地址*/
 
 #ifdef CONFIG_SYSFS 
      struct netdev_rx_queue  *_rx; /*接收隊列*/
  
     unsigned int          num_rx_queues; /*接收隊列數(shù)量*/
     unsigned int          real_num_rx_queues; /*當前活動的隊列數(shù)量*/
  
 #endif 
... 
 /* 
  * Cache lines mostly used on transmit path 
  */ 
     struct netdev_queue  *_tx  /*發(fā)送隊列*/ ____cacheline_aligned_in_smp; 
     unsigned int          num_tx_queues; /*發(fā)送隊列數(shù)量*/
     unsigned int          real_num_tx_queues; /*當前有效的發(fā)送隊列數(shù)量。*/
     struct Qdisc          *qdisc; 
     unsigned long         tx_queue_len; 
     spinlock_t          tx_global_lock; 
     int               watchdog_timeo; 
... 
     /* These may be needed for future network-power-down code. *
  
     /* 
      * trans_start here is expensive for high speed devices on S
      * please use netdev_queue->trans_start instead. 
      */ 
     unsigned long         trans_start; /*最后的數(shù)據(jù)包發(fā)送的時間戳,記錄的是jiffies*/
... 
     struct phy_device   *phydev; /*對應(yīng)的PHY 設(shè)備*/
     struct lock_class_key *qdisc_tx_busylock; 
 }; 


/*
@	申請net_device ===11111111111111111111111111111111
*/
#define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \ 
   alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1) 

/*可以看出alloc_netdev的本質(zhì)是alloc_netdev_mqs函數(shù)*/

/*
@	sizeof_priv:私有數(shù)據(jù)塊大小。 
@	name:設(shè)備名字
@	setup:回調(diào)函數(shù),初始化設(shè)備的設(shè)備后調(diào)用此函數(shù)
@	txqs:分配的發(fā)送隊列數(shù)量
@	rxqs:分配的接收隊列數(shù)量
@	如果申請成功的話就返回申請到的 net_device指針,失敗的話就返回NULL。
*/
struct net_device  * alloc_netdev_mqs ( int      sizeof_priv,   const char    *name,   
                  void      (*setup) (struct net_device *)) 
                  unsigned int    txqs,   
                  unsigned int    rxqs); 

/*事實上網(wǎng)絡(luò)設(shè)備有多種,大家不要以為就只有以太網(wǎng)一種,比如光纖分布式數(shù)據(jù)接口(FDDI)、以太網(wǎng)設(shè)備(Ethernet)、紅外數(shù)據(jù)接口(InDA)、高性能并行接口(HPPI)、CAN 網(wǎng)絡(luò)等*/


/*
@	本章講解的以太網(wǎng),針對以太網(wǎng)封裝的net_device申請函數(shù)是alloc_etherdev,這也是一個宏
@	alloc_etherdev 最終依靠的是 alloc_etherdev_mqs 函數(shù)
*/
 #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) 
 #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) 

/*
@	alloc_etherdev 最終依靠的是 alloc_etherdev_mqs 函數(shù)
*/
 struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs) 
 { 
	return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN,ether_setup, txqs, rxqs); /*申請net_device,*/
 } 

/*
@	對是申請的設(shè)備進行初始化
@	ether_setup函數(shù)會對 net_device做初步的初始化
*/
 void ether_setup(struct net_device *dev) 
 { 
    dev->header_ops       = &eth_header_ops; 
    dev->type           = ARPHRD_ETHER; 
    dev->hard_header_len = ETH_HLEN; 
    dev->mtu              = ETH_DATA_LEN; 
    dev->addr_len         = ETH_ALEN; 
    dev->tx_queue_len     = 1000; /* Ethernet wants good queues *
    dev->flags          = IFF_BROADCAST|IFF_MULTICAST; 
    dev->priv_flags       |= IFF_TX_SKB_SHARING; 
  
    eth_broadcast_addr(dev->broadcast); 
 } 


/*
@	刪除net_device(net_device)=====22222222222222222222222222222222222222222
@	注銷網(wǎng)絡(luò)驅(qū)動的時候需要釋放掉前面已經(jīng)申請到的 net_device
@	dev:要釋放掉的net_device指針。 
@	返回值:無
*/
void free_netdev(struct net_device *dev) 


/*
@	注冊net_device ==33333333333333333333333333333333333333
@	net_device申請并初始化完成以后就需要向內(nèi)核注冊net_device,要用到函數(shù)register_netdev
@	dev:要注冊的net_device指針
@	返回值:0 注冊成功,負值 注冊失敗。
*/
int register_netdev(struct net_device *dev) 


/*
@	注銷net_device ==44444444444444444444444444444444444
@	dev:要注銷的net_device指針
@	返回值:無
*/
void unregister_netdev(struct net_device *dev) 

2、網(wǎng)絡(luò)設(shè)備的操作集( net_device_ops結(jié)構(gòu)體 )

/*
@	定義在 include/linux/netdevice.h 文件中
@	net_device_ops結(jié)構(gòu)體里面都是一些以“ndo_”開頭的函數(shù),這些函數(shù)就需要網(wǎng)絡(luò)驅(qū)動編寫人員去實現(xiàn)
@	net_device_ops 結(jié)構(gòu)體 
*/
  struct net_device_ops { 
      int         (*ndo_init)(struct net_device *dev); /*當?shù)谝淮巫跃W(wǎng)絡(luò)設(shè)備的時候此函數(shù)會執(zhí)行*/
      void        (*ndo_uninit)(struct net_device *dev); /*卸載網(wǎng)絡(luò)設(shè)備的時候此函數(shù)會執(zhí)行*/
      int         (*ndo_open)(struct net_device *dev); /*打開網(wǎng)絡(luò)設(shè)備的時候此函數(shù)會執(zhí)行,網(wǎng)絡(luò)驅(qū)動程序需要實現(xiàn)此函數(shù),非常重要*/
      int         (*ndo_stop)(struct net_device *dev); 
      netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, 
                             struct net_device *dev); /*當需要發(fā)送數(shù)據(jù)的時候此函數(shù)就會執(zhí)行,此函數(shù)有一個參數(shù)為 sk_buff結(jié)構(gòu)體指針,sk_buff結(jié)構(gòu)體在Linux的網(wǎng)絡(luò)驅(qū)動中非常重要,sk_buff保存了上層傳遞給網(wǎng)絡(luò)驅(qū)動層的數(shù)據(jù)。也就是說,要發(fā)送出去的數(shù)據(jù)都存在了sk_buff中*/
      u16         (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, void *accel_priv,select_queue_fallback_t fallback); /*設(shè)備支持多傳輸隊列的時候選擇使用哪個隊列*/
      void       (*ndo_change_rx_flags)(struct net_device *dev, 
                                 int flags); 
      void        (*ndo_set_rx_mode)(struct net_device *dev);/*此函數(shù)用于改變地址過濾列表*/ 
      int         (*ndo_set_mac_address)(struct net_device *dev,  void *addr); /*此函數(shù)用于修改網(wǎng)卡的 MAC 地址*/
      int         (*ndo_validate_addr)(struct net_device *dev); /*驗證 MAC 地址是否合法,*/
      int         (*ndo_do_ioctl)(struct net_device *dev, 
                              struct ifreq *ifr, int cmd); /*用戶程序調(diào)用 ioctl 的時候此函數(shù)就會執(zhí)行,*/
      int         (*ndo_set_config)(struct net_device *dev, 
                                struct ifmap *map); 
      int         (*ndo_change_mtu)(struct net_device *dev, 
                            int new_mtu); /*更改MTU大小。*/
      int         (*ndo_neigh_setup)(struct net_device *dev, 
                                  struct neigh_parms *); 
     void       (*ndo_tx_timeout) (struct net_device *dev); /*當發(fā)送超時的時候產(chǎn)生會執(zhí)行,一般都是網(wǎng)絡(luò)出問題了導
致發(fā)送超*/
... 
 #ifdef CONFIG_NET_POLL_CONTROLLER 
     void       (*ndo_poll_controller)(struct net_device *dev); /*使用查詢方式來處理網(wǎng)卡數(shù)據(jù)的收發(fā)。*/
     int         (*ndo_netpoll_setup)(struct net_device *dev, 
                              struct netpoll_info *info); 
     void       (*ndo_netpoll_cleanup)(struct net_device *dev); 
 #endif 
... 
     int         (*ndo_set_features)(struct net_device *dev, etdev_features_t features); /*修改net_device的 features屬性,設(shè)置相應(yīng)的硬件屬性*/
... 
 }; 

/*
@	:ndo_open 函數(shù),:ndo_stop 函數(shù)==以NXP的I.MX 系列SOC 網(wǎng)絡(luò)驅(qū)動為例,會在此函數(shù)中做如下工作
*/
·使能網(wǎng)絡(luò)外設(shè)時鐘。 
·申請網(wǎng)絡(luò)所使用的環(huán)形緩沖區(qū)。 
·初始化MAC 外設(shè)。 
·綁定接口對應(yīng)的 PHY。 
·如果使用NAPI 的話要使能NAPI模塊,通過 napi_enable函數(shù)來使能。 
·開啟PHY。 
·調(diào)用netif_tx_start_all_queues來使能傳輸隊列,也可能調(diào)用netif_start_queue函數(shù)。 
·…… 

do_stop 函數(shù),關(guān)閉網(wǎng)絡(luò)設(shè)備的時候此函數(shù)會執(zhí)行,網(wǎng)絡(luò)驅(qū)動程序也需要實現(xiàn)此
函數(shù)。以NXP的I.MX 系列SOC 網(wǎng)絡(luò)驅(qū)動為例,會在此函數(shù)中做如下工作: 
·停止PHY。 
·停止NAPI功能。 
·停止發(fā)送功能。 
·關(guān)閉MAC。 
·斷開PHY 連接。 
·關(guān)閉網(wǎng)絡(luò)時鐘。 
·釋放數(shù)據(jù)緩沖區(qū)。 
  ·…… 

3、sk_buff結(jié)構(gòu)體

  • 網(wǎng)絡(luò)是分層的,對于應(yīng)用層而言不用關(guān)系具體的底層是如何工作的,只需要按照協(xié)議將要發(fā)送或接收的數(shù)據(jù)打包好即可
  • 打包好以后都通過dev_queue_xmit函數(shù)將數(shù)據(jù)發(fā)送出去,接收數(shù)據(jù)的話使用netif_rx函數(shù)即可
/*
@	定義在 include/linux/netdevice.h 中
@	函數(shù)用于將網(wǎng)絡(luò)數(shù)據(jù)發(fā)送出去
@	skb:	要發(fā)送的數(shù)據(jù),這是一個sk_buff結(jié)構(gòu)體指針,sk_buff是Linux網(wǎng)絡(luò)驅(qū)動中一個非常重要的結(jié)構(gòu)體,網(wǎng)絡(luò)數(shù)據(jù)就是以 sk_buff 保存的,各個協(xié)議層在 sk_buff 中添加自己的協(xié)議頭,最終由底層驅(qū)動講sk_buff中的數(shù)據(jù)發(fā)送出去
@			網(wǎng)絡(luò)數(shù)據(jù)的接收過程恰好相反,網(wǎng)絡(luò)底層驅(qū)動將接收到的原始數(shù)據(jù)打包成 sk_buff,然后發(fā)送給上層協(xié)議,上層會取掉相應(yīng)的頭部,然后將最終的數(shù)據(jù)發(fā)送給用戶
@	返回值:0 發(fā)送成功,負值 發(fā)送失敗。   
*/
static inline int dev_queue_xmit(struct sk_buff    *skb) 


/*
@	上層接收數(shù)據(jù)的話使用netif_rx函數(shù).但是最原始的網(wǎng)絡(luò)數(shù)據(jù)一般是通過輪詢、中斷或NAPI的方式來接收
@	skb:保存接收數(shù)據(jù)的 sk_buff
@	返回值:NET_RX_SUCCESS 成功,NET_RX_DROP 數(shù)據(jù)包丟棄。   
*/
int netif_rx(struct sk_buff *skb) 

  • sk_buff 是 Linux 網(wǎng)絡(luò)重要的數(shù)據(jù)結(jié)構(gòu),用于管理接收或發(fā)送數(shù)據(jù)包
/*
@	定義在 include/linux/skbuff.h 中
@	 sk_buff 結(jié)構(gòu)體 
*/
  struct sk_buff { 
      union { 
          struct { 
              /* These two members must be first. */ 
              struct sk_buff        *next; 
              struct sk_buff        *prev; /*構(gòu)成一個雙向鏈表*/
   
              union { 
                  ktime_t         tstamp; /*數(shù)據(jù)包接收時或準備發(fā)送時的時間戳*/
                  struct skb_mstamp skb_mstamp; 
              }; 
          }; 
          struct rb_node  rbnode; /* used in netem & tcp stack */ 
      }; 
      struct sock         *sk; /*當前 sk_buff所屬的Socket*/
      struct net_device     *dev; /*當前 sk_buff從哪個設(shè)備接收到或者發(fā)出的*/
   
      char                cb[48] __aligned(8); /*cb 為控制緩沖區(qū),不管哪個層都可以自由使用此緩沖區(qū),用于放置私有數(shù)據(jù)。 */
   
      unsigned long         _skb_refdst; 
      void                (*destructor)(struct sk_buff *skb); /*當釋放緩沖區(qū)的時候可以在此函數(shù)里面完成某些動作*/
.... 
      unsigned int          len, data_len; /*:len為實際的數(shù)據(jù)長度*/
      __u16               mac_len, hdr_len; /*:mac_len 為連接層頭部長度,也就是 MAC 頭的長度*/
.... 
     __be16              protocol; /*protocol協(xié)議*/
     __u16               transport_header; /*傳輸層頭部*/
     __u16               network_header; /*網(wǎng)絡(luò)層頭部*/
     __u16               mac_header; /*鏈接層頭部*/
  
     /* private: */ 
     __u32               headers_end[0]; /*緩沖區(qū)的尾部*/
     /* public: */ 
  
     /* These elements must be at the end, see alloc_skb() for 
details.  */ 
     sk_buff_data_t      tail; /*實際數(shù)據(jù)的尾部*/
     sk_buff_data_t        end; /*緩沖區(qū)的尾部*/
     unsigned char         *head, *data; /*:head 指向緩沖區(qū)的頭部,data 指向?qū)嶋H數(shù)據(jù)的頭部*/
     unsigned int          truesize; 
     atomic_t            users; 
 }; 
  • 再上述結(jié)構(gòu)體中的緩沖區(qū)的head、end和實際數(shù)據(jù)區(qū)的data、tail
    linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)
/*===11111111111111111111111111111111111111111111111111
@	分配sk_buff 
@	定義在include/linux/skbuff.h中
@	size:要分配的大小,也就是skb數(shù)據(jù)段大小
@	priority:為GFP MASK宏,比如GFP_KERNEL、GFP_ATOMIC 等
@	返回值:分配成功的話就返回申請到的 sk_buff首地址,失敗的話就返回 NULL
*/
static inline struct sk_buff *alloc_skb(unsigned int    size, gfp_t      priority) 
/*
@	定義在include/linux/skbuff.h中
@	在網(wǎng)絡(luò)設(shè)備驅(qū)動中常常使用 netdev_alloc_skb 來為某個設(shè)備申請一個用于接收的 skb_buff,
@	dev:要給哪個設(shè)備分配 sk_buff。 
@	length:要分配的大小。 
@	返回值:分配成功的話就返回申請到的 sk_buff首地址,失敗的話就返回 NULL
*/
static inline struct sk_buff *netdev_alloc_skb(struct net_device   *dev, unsigned int      length) 

/*=======222222222222222222222222222222222222222222222222
@	釋放sk_buff 
@	定義在include/linux/skbuff.c中
@	skb:要釋放的sk_buff。
@	返回值:無
*/
void kfree_skb(struct sk_buff *skb) 

/*=======33333333333333333333333333333333333333333333333
@	skb_put、skb_push、sbk_pull和 skb_reserve 四個函數(shù)用于變更 sk_buff
*/
/*函數(shù)用于在尾部擴展 skb_buff的數(shù)據(jù)區(qū),也就將 skb_buff 的 tail 后移 n 個字節(jié),從而導致 skb_buff 的 len 增加 n 個字節(jié)
@	skb:要操作的sk_buff
@	len:要增加多少個字節(jié)。
@	返回值:擴展出來的那一段數(shù)據(jù)區(qū)首地址
*/
unsigned char *skb_put(struct sk_buff   *skb, unsigned int   len)   
/*	skb_push函數(shù)用于在頭部擴展 skb_buff的數(shù)據(jù)區(qū)
@	skb:要操作的sk_buff
@	要增加多少個字節(jié)
@	返回值:擴展完成以后新的數(shù)據(jù)區(qū)首地址。
*/
unsigned char *skb_push(struct sk_buff    *skb, unsigned int   len) 
/*	sbk_pull函數(shù)用于從 sk_buff的數(shù)據(jù)區(qū)起始位置刪除數(shù)據(jù)
@	skb:要操作的sk_buff
@	len:要刪除的字節(jié)數(shù)。
@	  返回值:刪除以后新的數(shù)據(jù)區(qū)首地址
*/
unsigned char *skb_pull(struct sk_buff    *skb, unsigned int   len
/*	sbk_reserve函數(shù)用于調(diào)整緩沖區(qū)的頭部大小
@	skb:要操作的sk_buff
@	len:要增加的緩沖區(qū)頭部大小
@	返回值:無。 
*/
static inline void skb_reserve(struct sk_buff    *skb, int    len) 
  • 為了更好的解釋上面四個函數(shù),下面是結(jié)構(gòu)示意圖:
    linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)
    linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)
    linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)
    4、網(wǎng)絡(luò)NAPI處理機制 =====很重要的

  • Linux 里面的網(wǎng)絡(luò)數(shù)據(jù)接收也輪詢和中斷兩種,
    1、中斷的好處就是響應(yīng)快,數(shù)據(jù)量小的時候處理及時,速度、快,但是一旦當數(shù)據(jù)量大,而且都是短幀的時候會導致中斷頻繁發(fā)生,消耗大量的CPU處理時間在中斷自身處理上

    2、輪詢恰好相反,響應(yīng)沒有中斷及時,但是在處理大量數(shù)據(jù)的時候不需要消耗過多的CPU 處理時間。

  • linux在這兩個處理方式的基礎(chǔ)上,提出了另外一種網(wǎng)絡(luò)數(shù)據(jù)接收的處理方法:NAPI(New API),NAPI 是一種高效的網(wǎng)絡(luò)處理技術(shù).

  • 核心思想:中斷(用來喚醒數(shù)據(jù)接收服務(wù)程序)+ 輪詢(在接受服務(wù)程序中采用POLL的方法來輪詢處理數(shù)據(jù))

  • 目前 NAPI 已經(jīng)在 Linux 的網(wǎng)絡(luò)驅(qū)動中得到了大量的
    應(yīng)用

  • 如何在驅(qū)動中使用 NAPI處理機制文章來源地址http://www.zghlxwxcb.cn/news/detail-404142.html

/*初始化NAPI==1111111111111111111111111111111111111111111111
@	定義在 net/core/dev.c中
@	初始化一個 napi_struct實例
@	dev:每個NAPI 必須關(guān)聯(lián)一個網(wǎng)絡(luò)設(shè)備,此參數(shù)指定NAPI要關(guān)聯(lián)的網(wǎng)絡(luò)設(shè)備。
@	napi:要初始化的 NAPI實例
@	poll: NAPI所使用的輪詢函數(shù),非常重要,一般在此輪詢函數(shù)中完成網(wǎng)絡(luò)數(shù)據(jù)接收的工作。
@	weight:NAPI默認權(quán)重(weight),一般為NAPI_POLL_WEIGHT。 
@	返回值:無。
*/
void netif_napi_add(struct net_device   *dev,   struct napi_struct    *napi, int (*poll)(struct napi_struct *int        weight) 
 
 /*  刪除NAPI ==2222222222222222222222222222222222222222222222
 @	napi:要刪除的NAPI
 @	返回值:無。 
 */
 void netif_napi_del(struct napi_struct    *napi) 
 
 /*  使能NAPI ==333333333333333333333333333333333333333333333
 @	n:要使能的NAPI
 @	返回值:無。 
 */
inline void napi_enable(struct napi_struct    *n) 

/*關(guān)閉NAPI ===444444444444444444444444444444444444444444444444
@	n:要關(guān)閉的NAPI。 
@	返回值:無。 
*/
void napi_disable(struct napi_struct *n) 

 /* 檢查NAPI是否可以進行調(diào)度 ==555555555555555555555555555555555
 @	n:要檢查的NAPI
 @	返回值:如果可以調(diào)度就返回真,如果不可調(diào)度就返回假。 
 */
inline bool napi_schedule_prep(struct napi_struct *n) 

/*NAPI調(diào)度 ===6666666666666666666666666666666666666666666666666
@	n:要調(diào)度的NAPI。 
@	返回值:無。 
*/
void __napi_schedule(struct napi_struct *n) 

/*是否可以調(diào)度+調(diào)度 ===5555555555555555+666666666666666666666
@	n:要調(diào)度的NAPI。 
*/
 static inline void napi_schedule(struct napi_struct *n) 
 { 
     if (napi_schedule_prep(n)) 
         __napi_schedule(n); 
 } 

/*NAPI處理完成 ===77777777777777777777777777777777777777777777777
@	n:處理完成的NAPI。
@	返回值:無。 
*/
inline void napi_complete(struct napi_struct *n) 

到了這里,關(guān)于linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Linux內(nèi)核驅(qū)動開發(fā)(一)

    Linux內(nèi)核驅(qū)動開發(fā)(一)

    linux操作系統(tǒng)歷史 開發(fā)模式 git 分布式管理 git clone 獲取 git push 提交 git pull 更新 郵件組 mailing list patch 內(nèi)核代碼組成 Makfile arch 體系系統(tǒng)架構(gòu)相關(guān) block 塊設(shè)備 crypto 加密算法 drivers 驅(qū)動(85%) atm 通信 bluetooth 藍牙 firmware:外設(shè) fs 文件系統(tǒng) include 頭文件 init 啟動代碼 ipc 進程通

    2023年04月11日
    瀏覽(23)
  • linux-2.6.22.6內(nèi)核i2c驅(qū)動框架源碼分析

    linux-2.6.22.6內(nèi)核i2c驅(qū)動框架源碼分析

    i2c是常見的通信協(xié)議,協(xié)議比較簡單,只有數(shù)據(jù)和時鐘兩條線(SDA和SCL),i2c的通信分為主機和從機,主機一般占主導地位,從機可以有多個。 i2c通信的數(shù)據(jù)格式為(SDA上的數(shù)據(jù)):開始的7位里面指定了設(shè)備地址(因為有多個從機),第8位是讀或?qū)懶盘?,表示此次傳輸是讀還

    2024年02月11日
    瀏覽(13)
  • linux驅(qū)動開發(fā):Linux 內(nèi)核的一些函數(shù)

    1 、 MKDEV ( ma, mi ) 構(gòu)造設(shè)備號,將主設(shè)備號和次設(shè)備號轉(zhuǎn)換為設(shè)備號類型(dev_t)。 MKDEV 宏將主設(shè)備號( ma )左移 20 位,然后與次設(shè)備號( mi )相與,得到設(shè)備號。 dev_t 結(jié)構(gòu) 主設(shè)備號 12 位

    2024年02月17日
    瀏覽(20)
  • linux驅(qū)動開發(fā)--day1(驅(qū)動、內(nèi)核模塊及相關(guān)命令、內(nèi)核模塊傳參)
  • 怎么降低Linux內(nèi)核驅(qū)動開發(fā)的風險?

    降低Linux內(nèi)核驅(qū)動開發(fā)的風險是一個重要的目標,因為內(nèi)核驅(qū)動開發(fā)可能會對系統(tǒng)的穩(wěn)定性和安全性產(chǎn)生重要影響。以下是一些降低風險的建議: 1. 深入了解Linux內(nèi)核:在開始內(nèi)核驅(qū)動開發(fā)之前,建議深入學習Linux內(nèi)核的工作原理和架構(gòu),包括內(nèi)核模塊、設(shè)備模型、調(diào)度機制等

    2024年02月08日
    瀏覽(19)
  • Linux驅(qū)動開發(fā)(十五)---如何使用內(nèi)核現(xiàn)有驅(qū)動(顯示屏)

    Linux驅(qū)動開發(fā)(十五)---如何使用內(nèi)核現(xiàn)有驅(qū)動(顯示屏)

    《Linux驅(qū)動開發(fā)(一)—環(huán)境搭建與hello world》 《Linux驅(qū)動開發(fā)(二)—驅(qū)動與設(shè)備的分離設(shè)計》 《Linux驅(qū)動開發(fā)(三)—設(shè)備樹》 《Linux驅(qū)動開發(fā)(四)—樹莓派內(nèi)核編譯》 《Linux驅(qū)動開發(fā)(五)—樹莓派設(shè)備樹配合驅(qū)動開發(fā)》 《Linux驅(qū)動開發(fā)(六)—樹莓派配合硬件進行字

    2024年02月15日
    瀏覽(20)
  • <Linux開發(fā)>驅(qū)動開發(fā) -之-內(nèi)核定時器與中斷

    <Linux開發(fā)>驅(qū)動開發(fā) -之-內(nèi)核定時器與中斷

    <Linux開發(fā)>驅(qū)動開發(fā) -之-內(nèi)核定時器與中斷 交叉編譯環(huán)境搭建: <Linux開發(fā)> linux開發(fā)工具-之-交叉編譯環(huán)境搭建 uboot移植可參考以下: <Linux開發(fā)> -之-系統(tǒng)移植 uboot移植過程詳細記錄(第一部分) <Linux開發(fā)> -之-系統(tǒng)移植 uboot移植過程詳細記錄(第二部分) <Linux開

    2024年02月08日
    瀏覽(26)
  • linux驅(qū)動開發(fā) - 08_內(nèi)核定時器

    linux驅(qū)動開發(fā) - 08_內(nèi)核定時器

    鏈接: C/C++Linux服務(wù)器開發(fā)/后臺架構(gòu)師【零聲教育】-學習視頻教程-騰訊課堂 1.1 內(nèi)核時間管理簡介 Linux 內(nèi)核中有大量的函數(shù)需要時間管理,比如周期性的調(diào)度程序、延時程序、對于驅(qū)動編寫者來說最常用的定時器。 硬件定時器提供時鐘源,時鐘源的頻率可以設(shè)置, 設(shè)置好以

    2024年02月02日
    瀏覽(22)
  • 嵌入式Linux驅(qū)動開發(fā) 02:將驅(qū)動程序添加到內(nèi)核中

    嵌入式Linux驅(qū)動開發(fā) 02:將驅(qū)動程序添加到內(nèi)核中

    在上一篇文章 《嵌入式Linux驅(qū)動開發(fā) 01:基礎(chǔ)開發(fā)與使用》 中我們已經(jīng)實現(xiàn)了最基礎(chǔ)的驅(qū)動功能。在那篇文章中我們的驅(qū)動代碼是獨立于內(nèi)核代碼存放的,并且我們的驅(qū)動編譯后也是一個獨立的模塊。在實際使用中將驅(qū)動代碼放在內(nèi)核代碼中,并將驅(qū)動編譯到內(nèi)核中也是比較

    2023年04月09日
    瀏覽(51)
  • [驅(qū)動開發(fā)]Linux內(nèi)核定時器與中斷的簡單應(yīng)用

    首先介紹一下定時器原理。 在linux系統(tǒng)中定時器有分為軟定時和硬件定時器。 以海思某款芯片為例,定時器模塊又稱為Timer模塊,主要實現(xiàn)定時、計數(shù)功能。 Timer 具有以下特點: 帶可編程 8 位預分頻器的 32bit/16bit 減法定時器/計數(shù)器。 Timer 的計數(shù)時鐘為 3MHz 時鐘。 支持 3 種

    2024年02月20日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包