Data transmission Before entering the send function, let's look at the e100_up()->e100_alloc_cbs function: static int e100_alloc_cbs(struct nic *nic){struct cb *cb;unsigned int i, count = nic-> ;params.cbs.count;nic->cuc_cmd = cuc_start;nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;nic->cbs_avail = 0;
//Linear DMA mapping, here is the virtual address, nic->cbs = pci_alloc_consistent(nic->pdev,sizeof(struct cb) * count, &nic->cbs_dma_addr);if(! Nic->cbs)return -ENOMEM;//Create a circular send buffer for(cb = nic->cbs, i = 0; i < count; cb++, i++) {cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;cb->prev = (i == 0) ? nic->cbs + count - 1 : cb - 1;cb->dma_addr = Nic->cbs_dma_addr + i * sizeof(struct cb);cb->link = cpu_to_le32(nic->cbs_dma_addr +((i+1) % count) * sizeof(struct cb));cb->skb = NULL;}//Initialize each pointer so that it points to the buffer initial position nic->cb_to_use = nic->cb_to_send = ni C->cb_to_clean = nic->cbs;nic->cbs_avail = count;return 0;} In this code, the preparation for the transmission is completed and the send ring cache is established. When sending a number of plays, the data will eventually be sent to the dev->gt_hard_start_xmit function. In the e100 code, that is, e100_xmit_frame(). Go inside and look at: static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev){struct nic *nic = netdev_priv(netdev);int err;if(nic-> Flags & ich_10h_workaround) {e100_exec_cmd(nic, cuc_nop, 0); udelay(1);}err = e100_exec_cb(nic, skb, e100_xmit_prepare);switch(err) {case -ENOSPC:/* We queued the skb, but now We're out of space. */netif_stop_queue(netdev);break;case -ENOMEM:/* This is a hard error - log it. */DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\ " ;);netif_stop_queue(netdev);return 1;}netdev->trans_start = jiffies;return 0;} continue to trace into e100_exec_cb(nic, skb, e100_xmit_prepare); static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb , void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)){struct cb *cb;unsigned long flags;int err = 0;spin_lock_irqsave(&nic->cb_lock, flags);if( Unlikely(!nic->cbs_avail)) {err = -ENOMEM;goto err_unlock;}
//will skb Into the ring send buffer //cb_to_use: the current use position of the send buffer cb = nic-> cb_to_use; nic-> cb_to_use = cb-> next; nic-> cbs_avail--; cb->skb = skb; If(unlikely(!nic->cbs_avail))err = -ENOSPC;cb_prepare(nic, cb, skb);/* Order is important otherwise we'll be in a race with h/w:* set S-bit in Current first, then clear S-bit in previous. */cb->command
Generally speaking, after installing ubuntu, the centralized display driver has been installed. Howe
System Requirements: Unlimited release, requires PC platform (x86 architecture CPU), Glibc version
Starting today, I officially entered the development of tiny4412. Today I mainly watched the startu
In the various Linux distributions now, the enterprise version of red hat is relatively safe. For t
Liunx jdk installation tutorial
Problem with installing vmware tool on Fedora Core6
PXE+TFTP+DHCP network automatically boots and installs Linux
File system loading during Linux boot process
Linux sort command parameters and usage details
Do a good job in Linux log management
Linux cd command Switch working directory
Unix Common Commands Detailed Explanation
Solve the problem that Windows 2000 can't start.
Win8 Release Preview latest development status
Win7 system computer into the U disk appears a lot of removable disk how to do
Win10 system how to add dial-up connection desktop shortcut
Found that the memory can not be read and written and the solution
Insider preview version how to upgrade Win10 official version
Using Windows XP Enterprise has fallen behind Maintenance costs are large
Windows Server 2016 preview version 10512 Chinese ios image leaked
View the blue screen code of the Windows 8 system to solve the blue screen problem