void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) 1825 { 1826 __wsum csum; 1827 long csstart; 1828 1829 if (skb->ip_summed == CHECKSUM_PARTIAL) 1830 csstart = skb->csum_start - skb_headroom(skb); 1831 else 1832 csstart = skb_headlen(skb); 1833 1834 BUG_ON(csstart > skb_headlen(skb)); 1835 1836 skb_copy_from_linear_data(skb, to, csstart); 1837 1838 csum = 0; 1839 if (csstart != skb->len) 1840 csum = skb_copy_and_csum_bits(skb, csstart, to + csstart, 1841 skb->len - csstart, 0); 1842 1843 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1844 long csstuff = csstart + skb->csum_offset; 1845 1846 *((__sum16 *)(to + csstuff)) = csum_fold(csum); 1847 } 1848 }
今天还发现了一个特别好的网站,可以去查各类的linux函数
http://lxr.free-electrons.com/ident?v=2.6.35&i=
另外还有一篇文章,介绍乐很多网卡驱动中的函数:
Now, we explain the code in Table 11. The function rtl8139_open starts with requesting the IRQ by calling API request_irq. In this function, weregister the interrupt handler rtl8139_interrupt. This function shall becalled by kernel, whenever the device generates an interrupt. Now, weallocate memory, where outgoing packets reside before being sent onwire. Note that API pci_allocate_consistant returns kernel virtualaddress. The physical address is returned in third argument, which islater used by driver. Also observe that we have allocated memory neededfor all four descriptors. Function rtl8139_init_ring distributes thismemory to four descriptors. Here, we call function rtl8139_hw_start tomake the device ready for transmitting packets. At first, we reset thedevice, so that device shall be in a predictable and known state. Thisis done by writing reset value (described in specification) in CR(Command Register). We wait until the written value is read back, whichmeans device has reset. The next function, barrier ( ), is called to force thekernel to do required memory I/O immediately without doing anyoptimization. Once the device is reset, we enable transmission mode ofthe device by writing transmission enable value in CR. Next, we configure TCR(Transmission Configuration Register). The only thing we are specifying toTCR register is "Max DMA Burst Size per Tx DMA Burst". The rest we leave atdefault values. (See specification for more details.) Now we write theDMAable address of all four descriptors to TSAD (Transmission StartAddress Descriptor) registers. Next, we enable the interrupt, by writingin IMR (Interrupt Mask Register). This register lets us configure theinterrupts; the device will be generating. Last, we callnetif_start_queue to tell the kernel that device is ready. The onlything remaining is writing the rtl8139_interrupt function. For the time being,let's skip this. At this time, the device is ready to sendpackets, but the function to send packets out is missing. (Rememberhard_start_xmit.) So, let's do it.
连接在 这里