Re: skb_pull()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> It looks to me as though the skb-pull() function is what I want.  I can pull
> each 1K chunk off at a time.  Is it really that simple?  However, an element
> of doubt has been put in my mind by the description of the function in the
> Linux Device Drivers book ("Removes data from the head of the packet.  The
> driver won't need to use this function, but is included for completeness.")
> Hopefully, it is complete.

I think "completeness" refers to the book, not to the functionality of 
skb_pull(). I think it is most unsual to use skb_pull() in a network device 
driver.

> Will I be able to use skb_push()
> function to assemble a 4K frame in a similar manner on the receive side?

Normally, you'd use skb_put(). This assumes that the first chunk is received 
first:

skb = dev_alloc_skb (4K + alignment);
skb_reserve (skb, alignment);
insl (ioaddr + x, skb_put (skb, 1K), 1K); /* 1st chunk. */
...
insl (ioaddr + x, skb_put (skb, 1K), 1K); /* 2nd chunk. */
...
insl (ioaddr + x, skb_put (skb, 1K), 1K); /* 3rd chunk. */
...
insl (ioaddr + x, skb_put (skb, 1K), 1K); /* 4th chunk. */

If you get the first chunk last, then use skb_push():

skb = dev_alloc_skb (4K + alignment);
skb_reserve (skb, 4K + alignment);
insl (ioaddr + x, skb_push (skb, 1K), 1K); /* 4th chunk. */
...
insl (ioaddr + x, skb_push (skb, 1K), 1K); /* 3rd chunk. */
...
insl (ioaddr + x, skb_push (skb, 1K), 1K); /* 2nd chunk. */
...
insl (ioaddr + x, skb_push (skb, 1K), 1K); /* 1st chunk. */

(I don't know what skb_push() returns, I'm assuming it returns a pointer to 
the new 1K chunk in skb_put() style. If not, modify accordingly.)

This should work fine with 2.2 kernels too.

All of the above assumed that you use PIO transfers. With a DMA device, 
you'll need to manage the pointers yourself on the receive side when dealing 
with the chunks. Something like:

skb = dev_alloc_skb (4K + alignment);
skb_reserve (skb, alignment);
dma_pointer = pci_map_single (pdev, skb->head, 4K, PCI_DMA_FROMDEVICE);
/* await completion of DMA */
skb_put (skb, length_of_whole_packet);
pci_unmap_single (pdev, dma_pointer, skb->head, 4K, PCI_DMA_FROMDEVICE);

(Please the the order of the arguments.)

Regards,
Rask Ingemann Lambertsen
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux