⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network device drivers.htm

📁 What is this ``device driver stuff anyway? Here s a very short introduction to the concept.
💻 HTM
📖 第 1 页 / 共 4 页
字号:
</dt><dd>Link layer multicast.

</dd><dt><tt>PACKET_SELF</tt>
</dt><dd>Frame to us.

</dd><dt><tt>PACKET_OTHERHOST</tt>
</dt><dd>Frame to another single host.
</dd></dl>
This last type is normally reported as a result of an interface
running in promiscuous mode.

<p>Finally, the device driver invokes <tt>netif_rx()</tt> to
pass the buffer up to the protocol layer. The buffer is queued
for processing by the networking protocols after the interrupt
handler returns. Deferring the processing in this fashion
dramatically reduces the time interrupts are disabled and
improves overall responsiveness. Once <tt>netif_rx()</tt> is
called, the buffer ceases to be property of the device driver
and may not be altered or referred to again.

</p><p>Flow control on received packets is applied at two levels by
the protocols. Firstly a maximum amount of data may be
outstanding for <tt>netif_rx()</tt> to process. Secondly each
socket on the system has a queue which limits the amount of
pending data. Thus all flow control is applied by the protocol
layers. On the transmit side a per device variable
<tt>dev-&gt;tx_queue_len</tt> is used as a queue length limiter.
The size of the queue is normally 100 frames, which is enough
that the queue will be kept well filled when sending a lot of
data over fast links. On a slow link such as slip link, the
queue is normally set to about 10 frames, as sending even 10
frames is several seconds of queued data.

</p><p>One piece of magic that is done for reception with most
existing device, and one you should implement if possible, is
to reserve the neccessary bytes at the head of the buffer to
land the IP header on a long word boundary. The existing
ethernet drivers thus do:
</p><pre>skb=dev_alloc_skb(length+2);
if(skb==NULL)
    return;
skb_reserve(skb,2);
/* then 14 bytes of ethernet hardware header */
</pre>
to align IP headers on a 16 byte boundary, which is also
the start of a cache line and helps give performance
improvments. On the Sparc or DEC Alpha these improvements are
very noticable.

<h3>Optional Functionality</h3>

<p>Each device has the option of providing additional functions
and facilities to the protocol layers. Not implementing these
functions will cause a degradation in service available via the
interface but not prevent operation. These operations split
into two categories--configuration and activation/shutdown.

</p><h3>Activation And Shutdown</h3>

<p>When a device is activated (that is, the flag
<tt>IFF_UP</tt> is set) the <tt>dev-&gt;open()</tt> method is
invoked if the device has provided one. This permits the device
to take any action such as enabling the interface that are
needed when the interface is to be used. An error return from
this function causes the device to stay down and causes the
user request to activate the device to fail with the error
returned by <tt>dev-&gt;open()</tt>

</p><p>The second use of this function is with any device loaded as a
module. Here it is neccessary to prevent a device being
unloaded while it is open. Thus the <tt>MOD_INC_USE_COUNT</tt>
macro must be used within the open method.

</p><p>The <tt>dev-&gt;close()</tt> method is invoked when the device is
configured down and should shut off the hardware in such a way
as to minimise machine load (for example by disabling the
interface or its ability to generate interrupts). It can also
be used to allow a module device to be unloaded now that it is
down. The rest of the kernel is structured in such a way that
when a device is closed, all references to it by pointer are
removed. This ensures that the device may safely be unloaded
from a running system. The close method is not permitted to
fail.

</p><h3>Configuration And Statistics</h3>

<p>A set of functions provide the ability to query and to set
operating parameters.  The first and most basic of these is a
<tt>get_stats</tt> routine which when called returns a struct
<tt>enet_statistics</tt> block for the interface. This allows
user programs such as ifconfig to see the loading on the
interface and any problem frames logged. Not providing this
will lead to no statistics being available.

</p><p>The <tt>dev-&gt;set_mac_address()</tt> function is called whenever
a superuser process issues an ioctl of type
<tt>SIOCSIFHWADDR</tt> to change the physical address of a
device. For many devices this is not meaningful and for others
not supported. If so leave this functiom pointer as
<tt>NULL</tt>. Some devices can only perform a physical
address change if the interface is taken down. For these check
<tt>IFF_UP</tt> and if set then return <tt>-EBUSY</tt>.

</p><p>The <tt>dev-&gt;set_config()</tt> function is called by the
<tt>SIOCSIFMAP</tt> function when a user enters a command like
<tt>ifconfig eth0 irq 11</tt>. It passes an <tt>ifmap</tt>
structure containing the desired I/O and other interface
parameters. For most interfaces this is not useful and you can
return NULL.

</p><p>Finally, the <tt>dev-&gt;do_ioctl()</tt> call is invoked whenever
an ioctl in the range <tt>SIOCDEVPRIVATE</tt> to
<tt>SIOCDEVPRIVATE+15</tt> is used on your interface. All these
ioctl calls take a struct <tt>ifreq</tt>. This is copied into
kernel space before your handler is called and copied back at
the end. For maximum flexibility any user may make these calls
and it is up to your code to check for superuser status when
appropriate. For example the PLIP driver uses these to set
parallel port time out speeds to allow a user to tune the plip
device for their machine.

</p><h3>Multicasting</h3>

<p>Certain physical media types such as ethernet support
multicast frames at the physical layer. A multicast frame is
heard by a group, but not all, hosts on the network, rather
than going from one host to another.

</p><p>The capabilities of ethernet cards are fairly variable. Most
fall into one of three categories:
</p><ol>
<li>No multicast filters. The card either receives all
multicasts or none of them. Such cards can be a nuisance on a
network with a lot of multicast traffic such as group video
conferences.

</li><li>Hash filters. A table is loaded onto the card giving a
mask of entries that we wish to hear multicast for. This
filters out some of the unwanted multicasts but not all.

</li><li>Perfect filters. Most cards that support perfect
filters combine this option with 1 or 2 above. This is done
because the perfect filter often has a length limit of 8 or 16
entries.
</li></ol>
It is especially important that ethernet interfaces are
programmed to support multicasting. Several ethernet protocols
(notably Appletalk and IP multicast) rely on ethernet
multicasting. Fortunately, most of the work is done by the
kernel for you (see net/core/dev_mcast.c).

<p>The kernel support code maintains lists of physical
addresses your interface should be allowing for multicast. The
device driver may return frames matching more than the
requested list of multicasts if it is not able to do perfect
filtering.

</p><p>Whenever the list of multicast addresses changes the device
drivers <tt>dev-&gt;set_multicast_list()</tt> function is invoked.
The driver can then reload its physical tables. Typically this
looks something like:
</p><pre>if(dev-&gt;flags&amp;IFF_PROMISC)
    SetToHearAllPackets();
else if(dev-&gt;flags&amp;IFF_ALLMULTI)
    SetToHearAllMulticasts();
else
{
    if(dev-&gt;mc_count&lt;16)
    {
        LoadAddressList(dev-&gt;mc_list);
        SetToHearList();
    }
    else
        SetToHearAllMulticasts();
}
</pre>
There are a small number of cards that can only do unicast
or promiscuous mode. In this case the driver, when presented
with a request for multicasts has to go promiscuous. If this is
done, the driver must itself also set the <tt>IFF_PROMISC</tt>
flag in <tt>dev-&gt;flags</tt>.

<p>In order to aid driver writer the multicast list is kept
valid at all times. This simplifies many drivers, as a reset
from error condition in a driver often has to reload the
multicast address lists.

</p><h3>Ethernet Support Routines</h3>

<p>Ethernet is probably the most common physical interface type
that is handled. The kernel provides a set of general purpose
ethernet support routines that such drivers can use.

</p><p><tt>eth_header()</tt> is the standard ethernet handler for the
<tt>dev-&gt;hard_header</tt> routine, and can be used in any
ethernet driver. Combined with <tt>eth_rebuild_header()</tt>
for the rebuild routine it provides all the ARP lookup required
to put ethernet headers on IP packets.

</p><p>The <tt>eth_type_trans()</tt> routine expects to be fed a raw
ethernet packet. It analyses the headers and sets
<tt>skb-&gt;pkt_type</tt> and <tt>skb-&gt;mac</tt> itself as well as
returning the suggested value for <tt>skb-&gt;protocol</tt>. This
routine is normally called from the ethernet driver receive
interrupt handler to classify packets.

</p><p><tt>eth_copy_and_sum()</tt>, the final ethernet support routine,
is quite internally complex but offers significant performance
improvements for memory mapped cards. It provides the support
to copy and checksum data from the card into an
<tt>sk_buff</tt> in a single pass. This single pass through
memory almost eliminates the cost of checksum computation when
used and can really help IP throughput.

</p><blockquote><i>Alan Cox has been working on Linux since version
0.95, when he installed it in order to do further work on the
AberMUD game. He now manages the Linux Networking, SMP, and
Linux/8086 projects and hasn't done any work on AberMUD since
November 1993.</i></blockquote> 
<p>
</p><p></p><hr size="3">
<p><b><a name="Messages">Messages</a></b>
<nobr>
<font size="-1">







</font>
</nobr>
 </p><p>
<nobr>
<dl compact="compact">
<dt> 2. <img src="network%20device%20drivers_files/question.gif" alt="Question:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/2.html">
Question on alloc_skb()</a> <i> by Joern Wohlrab</i> </dt>
<dd>
<dl compact="compact">
<dt> 1. <img src="network%20device%20drivers_files/disagree.gif" alt="Disagree:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/2/1.html">
Re: Question on alloc_skb()</a> <i> by Erik Petersen</i> </dt>
</dl>
</dd>
<dt> 1. <img src="network%20device%20drivers_files/question.gif" alt="Question:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/1.html">
Question on network interfaces</a> <i> by <a href="http://www.crhc.uiuc.edu/%7Evijay">Vijay Gupta</a></i> </dt>
<dd>
<dl compact="compact">
<dt> 2. <img src="network%20device%20drivers_files/feedback.gif" alt="Feedback:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/1/2.html">
Re: Question on network interfaces</a> <i> by <a href="http://www.di.fc.ul.pt/%7Eroque/">Pedro Roque</a></i> </dt>
<dt> 1. <img src="network%20device%20drivers_files/note.gif" alt="None:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/1/1.html">
Untitled</a><i></i> </dt>
<dd>
<dl compact="compact">
<dt> 1. <img src="network%20device%20drivers_files/note.gif" alt="Note:" align="middle" height="15" width="15">
<a href="http://tldp.org/LDP/khg/HyperNews/get/net/net-intro/1/1/1.html">
Finding net info</a> <i> by <a href="http://www.linux.org.uk/">Alan Cox</a></i> </dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</nobr>

</p><p>
</p><p>



  





<br> 
 
<br></p></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -