1. 程式人生 > >網絡設備之分配net_device結構

網絡設備之分配net_device結構

unsigned ethernet 默認 eem def 填充 init callback char

註冊網絡設備時,會調用pci_driver->probe函數,以e100為例,最終會調用alloc_netdev_mqs來分配內存,並且在分配內存後調用setup函數(以太網為ether_setup)初始化二層地址等信息,這裏主要分析alloc_netdev_mqs函數,以及ether_setup函數:

e100_probe----->alloc_etherdev----->alloc_netdev_mqs

|

|---->ether_setup

  1 /**
  2  * alloc_netdev_mqs - allocate network device
  3  * @sizeof_priv: size of private data to allocate space for
  4  * @name: device name format string
  5  * @name_assign_type: origin of device name
  6  * @setup: callback to initialize device
  7  * @txqs: the number of TX subqueues to allocate
8 * @rxqs: the number of RX subqueues to allocate 9 * 10 * Allocates a struct net_device with private data area for driver use 11 * and performs basic initialization. Also allocates subqueue structs 12 * for each queue on the device. 13 */ 14 struct net_device *alloc_netdev_mqs(int
sizeof_priv, const char *name, 15 unsigned char name_assign_type, 16 void (*setup)(struct net_device *), 17 unsigned int txqs, unsigned int rxqs) 18 { 19 struct net_device *dev; 20 size_t alloc_size; 21 struct net_device *p; 22 23 BUG_ON(strlen(name) >= sizeof(dev->name)); 24 25 /* 檢查發送隊列數 */ 26 if (txqs < 1) { 27 pr_err("alloc_netdev: Unable to allocate device with zero queues\n"); 28 return NULL; 29 } 30 31 /* 檢查接收隊列數 */ 32 #ifdef CONFIG_SYSFS 33 if (rxqs < 1) { 34 pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n"); 35 return NULL; 36 } 37 #endif 38 39 /* 計算net_device結構大小 */ 40 alloc_size = sizeof(struct net_device); 41 /* 加上私有數據大小 */ 42 if (sizeof_priv) { 43 /* ensure 32-byte alignment of private area */ 44 alloc_size = ALIGN(alloc_size, NETDEV_ALIGN); 45 alloc_size += sizeof_priv; 46 } 47 /* ensure 32-byte alignment of whole construct */ 48 /* 整個空間做對齊後的大小 */ 49 alloc_size += NETDEV_ALIGN - 1; 50 51 /* 分配內存 */ 52 p = kvzalloc(alloc_size, GFP_KERNEL | __GFP_REPEAT); 53 if (!p) 54 return NULL; 55 56 /* 內存對齊 */ 57 dev = PTR_ALIGN(p, NETDEV_ALIGN); 58 59 /* 計算對齊的填充 */ 60 dev->padded = (char *)dev - (char *)p; 61 62 /* 分配設備引用 */ 63 dev->pcpu_refcnt = alloc_percpu(int); 64 if (!dev->pcpu_refcnt) 65 goto free_dev; 66 67 /* 地址列表初始化 */ 68 if (dev_addr_init(dev)) 69 goto free_pcpu; 70 71 /* 組播列表初始化 */ 72 dev_mc_init(dev); 73 74 /* 單播列表初始化 */ 75 dev_uc_init(dev); 76 77 /* 設置net */ 78 dev_net_set(dev, &init_net); 79 80 /* GSO設置 */ 81 dev->gso_max_size = GSO_MAX_SIZE; 82 dev->gso_max_segs = GSO_MAX_SEGS; 83 84 /* 初始化各種鏈表 */ 85 INIT_LIST_HEAD(&dev->napi_list); 86 INIT_LIST_HEAD(&dev->unreg_list); 87 INIT_LIST_HEAD(&dev->close_list); 88 INIT_LIST_HEAD(&dev->link_watch_list); 89 INIT_LIST_HEAD(&dev->adj_list.upper); 90 INIT_LIST_HEAD(&dev->adj_list.lower); 91 INIT_LIST_HEAD(&dev->ptype_all); 92 INIT_LIST_HEAD(&dev->ptype_specific); 93 #ifdef CONFIG_NET_SCHED 94 hash_init(dev->qdisc_hash); 95 #endif 96 dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; 97 98 /* 初始化設備硬件地址,mtu等參數 */ 99 setup(dev); 100 101 /* 隊列長度為0,則采用默認值 */ 102 if (!dev->tx_queue_len) { 103 dev->priv_flags |= IFF_NO_QUEUE; 104 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; 105 } 106 107 /* 設置發送隊列數 */ 108 dev->num_tx_queues = txqs; 109 dev->real_num_tx_queues = txqs; 110 111 /* 分配初始化發送隊列 */ 112 if (netif_alloc_netdev_queues(dev)) 113 goto free_all; 114 115 #ifdef CONFIG_SYSFS 116 /* 設置接收隊列數 */ 117 dev->num_rx_queues = rxqs; 118 dev->real_num_rx_queues = rxqs; 119 120 /* 分配初始化接收隊列 */ 121 if (netif_alloc_rx_queues(dev)) 122 goto free_all; 123 #endif 124 125 /* 拷貝名字 */ 126 strcpy(dev->name, name); 127 128 /* 賦值名字賦值類型 */ 129 dev->name_assign_type = name_assign_type; 130 131 /* 設置設備組 */ 132 dev->group = INIT_NETDEV_GROUP; 133 134 /* 設置默認ethtool操作 */ 135 if (!dev->ethtool_ops) 136 dev->ethtool_ops = &default_ethtool_ops; 137 138 /* 初始化netfilter入口 */ 139 nf_hook_ingress_init(dev); 140 141 return dev; 142 143 free_all: 144 free_netdev(dev); 145 return NULL; 146 147 free_pcpu: 148 free_percpu(dev->pcpu_refcnt); 149 free_dev: 150 netdev_freemem(dev); 151 return NULL; 152 }

 1 /**
 2  * ether_setup - setup Ethernet network device
 3  * @dev: network device
 4  *
 5  * Fill in the fields of the device structure with Ethernet-generic values.
 6  */
 7 void ether_setup(struct net_device *dev)
 8 {
 9     dev->header_ops        = &eth_header_ops;
10     dev->type        = ARPHRD_ETHER;
11     dev->hard_header_len     = ETH_HLEN;
12     dev->min_header_len    = ETH_HLEN;
13     dev->mtu        = ETH_DATA_LEN;
14     dev->min_mtu        = ETH_MIN_MTU;
15     dev->max_mtu        = ETH_DATA_LEN;
16     dev->addr_len        = ETH_ALEN;
17     dev->tx_queue_len    = DEFAULT_TX_QUEUE_LEN;
18     dev->flags        = IFF_BROADCAST|IFF_MULTICAST;
19     dev->priv_flags        |= IFF_TX_SKB_SHARING;
20 
21     eth_broadcast_addr(dev->broadcast);
22 
23 }

網絡設備之分配net_device結構