pkg://Ethernet-HOWTO-html.tar.gz:84888/Ethernet-HOWTO-8.html
downloads
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
<TITLE>Linux Ethernet-Howto: ±â¼úÀû Á¤º¸</TITLE>
<LINK HREF="Ethernet-HOWTO-9.html" REL=next>
<LINK HREF="Ethernet-HOWTO-7.html" REL=previous>
<LINK HREF="Ethernet-HOWTO.html#toc8" REL=contents>
</HEAD>
<BODY>
<A HREF="Ethernet-HOWTO-9.html">´ÙÀ½</A>
<A HREF="Ethernet-HOWTO-7.html">ÀÌÀü</A>
<A HREF="Ethernet-HOWTO.html#toc8">Â÷·Ê</A>
<HR>
<H2><A NAME="tech-intro"></A> <A NAME="s8">8. ±â¼úÀû Á¤º¸</A></H2>
<P>
<P>ÀÌ ¹®¼´Â Ä«µå°¡ ¾î¶»°Ô ÀÛµ¿Çϴ°¡¸¦ Á¶±ÝÀÌ¶óµµ ´õ ÀÌÇØÇÏ±æ ¿øÇϰųª, ÇöÀç µå¶óÀ̹öµéÀ»
°¡Áö°í ³î°Å³ª ÇöÀç Áö¿øµÇÁö ¾Ê´Â Ä«µåÀÇ °íÀ¯ÇÑ µå¶óÀ̹ö¸¦ ¸¸µé·Á°í ÇÏ´ÂÀ̵鿡°Ô ¸Å¿ì À¯¿ë
ÇÒ °ÍÀÌ´Ù. ¸¸ÀÏ ÀÌ Ä«Å×°í¸®¿¡ ºüÁ®µé±â ½È´Ù¸é ÀÌ ÀåÀ» ³Ñ¾î°¡µµ µÈ´Ù.
<P>
<H2><A NAME="data-xfer"></A> <A NAME="ss8.1">8.1 Programmed I/O vs. °øÀ¯ ¸Þ¸ð¸® vs. DMA</A>
</H2>
<P>
<P>¸¸ÀÏ ¿©·¯ºÐÀÌ ÀÌ¹Ì ¹éÅõ¹é ÆÐŶµéÀ» º¸³»°í ¹ÞÀ»¼ö ÀÖ´Ù¸é, ¼±À» ÅëÇØ ´õ ¸¹Àº °ÍÀ» ³ÖÀ»¼ö´Â
¾ø´Ù. ¸ðµç Çö´ëÀûÀÎ ÀÌ´õ³Ý Ä«µå´Â ¹éÅõ¹é ÆÐŶµéÀ» ¹ÞÀ»¼ö ÀÖ´Ù. ¸®´ª½ºÀÇ DP8390 µå¶óÀ̹öµé
(wd80x3, SMC-Ultra, 3c503, ne2000, µîµî)Àº ¹éÅõ¹é ÆÐŶµéÀ» ¸Å¿ì Àß º¸³»°í(ÇöÀçÀÇ ÀÎÅÍ·´Æ®
´ë±â½Ã°£¿¡ ÀÇÁ¸ÇÑ´Ù) 3c509¿Í AT1500 Çϵå¿þ¾î´Â ÀÚµ¿À¸·Î ¹éÅõ¹é ÆÐŶµéÀ» º¸³»´Âµ¥ ÀüÇô ¹®
Á¦°¡ ¾ø´Ù.
<P>ISA ¹ö½º´Â 5.3MB/sec (42Mb/sec)ÀÇ ¼Óµµ¸¦ °¡Áú¼ö ÀÖÀ¸¸ç, 10Mbps ÀÌ´õ³Ý¿¡´Â ÃæºÐÇØ º¸ÀδÙ.
100Mbps Ä«µåµéÀÇ °æ¿ì¿¡´Â ³×Æ®¿öÅ© ´ë¿ªÆøÀÇ ÀÌÁ¡À» ¾ò±â À§Çؼ´Â ´õ ºü¸¥ ¹ö½º°¡ ÇÊ¿äÇÑ
°ÍÀÌ ´ç¿¬ÇÏ´Ù.
<P>
<H3>Programmed I/O (e.g. NE2000, 3c509)</H3>
<P>
<P>Pro: ¾î¶°ÇÑ °Á¦ÀûÀÎ ½Ã½ºÅÛ ÀÚ¿øÀÇ »ç¿ëµµ ¾øÀ¸¸ç, ¾ÆÁÖ Á¶±ÝÀÇ I/O ·¹Áö½ºÅ͸¦ »ç¿ëÇϰí,
16M Á¦ÇÑÀ» °¡ÁöÁö ¾Ê´Â´Ù.
<P>Con: º¸Åë Àü¼Û·üÀÌ °¡Àå ´À¸®°í, CPU´Â Ç×»ó ±â´Ù·Á¾ßÇϸç, ³¢¾îµç ÆÐŶ¿¡ ´ëÇÑ Á¢±ÙÀº º¸Åë
Èûµé°Å³ª ºÒ°¡´ÉÇÏ´Ù.
<P>
<H3>°øÀ¯ ¸Þ¸ð¸® (e.g. WD80x3, SMC-Ultra, 3c503)</H3>
<P>
<P>Pro: °£´ÜÇϰí, programmed I/O º¸´Ù ºü¸£¸ç, ÆÐŶµé¿¡ ´ëÇÑ ¹«ÀÛÀ§ Á¢±ÙÀÌ Çã¿ëµÈ´Ù. ¾îµð¿¡¼
»ç¿ëµÇ³Ä¸é, ¸®´ª½º µå¶óÀ̹öµéÀÌ µé¾î¿Â IP ÆÐŶµéÀÌ Ä«µå¿¡¼ º¹»çµÇ¹Ç·Î ±×µéÀÇ Ã¼Å©¼¶À» °è
»êÇϰí, ±×·ÎÀÎÇØ µ¿±ÞÀÇ PIO Ä«µå¿¡ ºñÇØ CPU Á¡À¯À²ÀÌ Àû¾îÁø´Ù.
<P>Con: ¸Þ¸ð¸® °ø°£À» »ç¿ëÇϸç (DOS »ç¿ëÀڵ鿡°Ô´Â ¸Å¿ì Å«°ÅÁö¸¸, ¸®´ª½º»ó¿¡¼´Â Ưº°È÷ ¹®Á¦
µÇÁö ¾Ê´Â´Ù), ±×¸®°í ¿©ÀüÈ÷ CPU¸¦ Àâ¾ÆµÐ´Ù.
<P>
<H3>Slave (normal) Direct Memory Access (e.g. ¸®´ª½º¿¡´Â ¾ø´Ù!)</H3>
<P>
<P>Pro: ½ÇÁ¦ µ¥ÀÌŸ Àü¼Û½Ã¿¡´Â CPU ¸¦ ³õ¾ÆÁØ´Ù.
<P>Con: °æ°è¼± »óŸ¦ È®ÀÎÇϰí, ÀÎÁ¢ÇÑ ¹öÆÛµéÀ» Àç¹èÄ¡Çϸç, DMA ¸®Áö½ºÅ͵éÀ» ÇÁ·Î±×·¡¹ÖÇÏ¿©
¸ðµç ±â¼úµéÁß¿¡ °¡Àå ´À¸®´Ù. ¶ÇÇÑ ºÎÁ·ÇÑ DMA ä³ÎÀ» »ç¿ëÇϸç, Àú¼öÁØ ¸Þ¸ð¸® ¹öÆÛÀÇ Á¤·ÄÀ»
ÇÊ¿ä·Î ÇÑ´Ù.
<P>
<H3><A NAME="master"></A> Bus Master Direct Memory Access (e.g. LANCE, DEC 21040) </H3>
<P>
<P>Pro: µ¥ÀÌŸ Àü¼ÛÁß¿¡´Â CPU°¡ ÀÚÀ¯·Î¿ì¸ç, ¹öÆÛµé°ú ÇÔ²² ¹è¿ÇÒ¼ö ÀÖÀ¸¸ç, ISA ¹ö½º»ó¿¡¼
ÀÒ¾î¹ö¸®´Â ¾ÆÁÖ Á¶±ÝÀ̳ª ¾Æ´Ï¸é CPU½Ã°£À» ÀüÇô ÇÊ¿ä·ÎÇÏÁö ¾Ê±âµµ ÇÑ´Ù. ´ëºÎºÐÀÇ ¹ö½º ¸¶½º
Å͸µ ¸®´ª½º µå¶óÀ̹öµéÀº ÇöÀç `Ä«ÇǺ극ÀÌÅ©' ±¸Á¶¸¦ »ç¿ëÇϴµ¥ À̰ÍÀº Ä«µå°¡ Å« ÆÐŶµéÀ»
Ä¿³Î ³×Æ®¿öÅ· ¹öÆÛ¿¡ Á÷Á¢ ³Ö´Â Àå¼ÒÀ̰í, ÀÛÀº ÆÐŶµéÀº CPU°¡ º¹»çÇÔÀ¸·Î¼ ÀÌÈÄ·Î ÁøÇàµÇ´Â
ij½Ã¸¦ ÁغñÇÏ°Ô ÇÑ´Ù.
<P>Con: (ISA ¹ö½º Ä«µåµé¿¡¸¸ ÇØ´çµÈ´Ù)
Ä«µå¿¡´Â Àú¼öÁØ ¸Þ¸ð¸® ¹öÆÛ¿Í DMAä³ÎÀÌ ÇÊ¿äÇÏ´Ù.
Any bus-master will have problems with other bus-masters
that are bus-hogs, such as some primitive SCSI adaptors. A few
badly-designed motherboard chipsets have problems with
bus-masters. And a reason for not using <EM>any</EM> type of
DMA device is using a 486 processor designed for
plug-in replacement of a 386: these processors must
flush their cache with each DMA cycle. (This includes
the Cx486DLC, Ti486DLC, Cx486SLC, Ti486SLC, etc.)
<P>
<P>
<H2><A NAME="skel"></A> <A NAME="ss8.2">8.2 Writing a Driver</A>
</H2>
<P>
<P>The only thing that one needs to use an ethernet card with Linux
is the appropriate driver. For this, it is essential that the
manufacturer will release the technical programming information to
the general public without you (or anyone) having to sign your life
away. A good guide for the likelihood of getting documentation
(or, if you aren't writing code, the likelihood that someone
else will write that driver you really, really need) is the
availability of the Crynwr (nee Clarkson) packet driver. Russ
Nelson runs this operation, and has been very helpful in supporting
the development of drivers for Linux. <EM>Net-surfers</EM> can try this
URL to look up Russ' software.
<P>
<A HREF="http://www.crynwr.com/crynwr/home.html">Russ Nelson's Packet Drivers</A><P>Given the documentation, you can write a driver for
your card and use it for Linux (at least in theory).
Keep in mind that some old hardware that was designed for XT type
machines will not function very well in a multitasking
environment such as Linux. Use of these will lead to major
problems if your network sees a reasonable amount of traffic.
<P>Most cards come with drivers for MS-DOS interfaces such as
NDIS and ODI, but these are useless for Linux. Many people
have suggested directly linking them in or automatic
translation, but this is nearly impossible. The MS-DOS
drivers expect to be in 16 bit mode and hook into `software
interrupts', both incompatible with the Linux kernel. This
incompatibility is actually a feature, as some Linux drivers
are considerably better than their MS-DOS counterparts. The
`8390' series drivers, for instance, use ping-pong transmit
buffers, which are only now being introduced in the MS-DOS world.
<P>(Ping-pong Tx buffers means using at least 2 max-size
packet buffers for Tx packets. One is loaded while the card
is transmitting the other. The second is then sent as soon
as the first finished, and so on. In this way, most cards
are able to continuously send back-to-back packets onto
the wire.)
<P>OK. So you have decided that you want to write a driver for the
Foobar Ethernet card, as you have the programming information,
and it hasn't been done yet. (...these are the two main
requirements ;-) You should start with the skeleton
network driver that is provided
with the Linux kernel source tree. It can be found in the file
/usr/src/linux/drivers/net/skeleton.c in all recent kernels.
Also have a look at the Kernel Hackers Guide, at the
following URL:
<A HREF="http://www.redhat.com:8080/HyperNews/get/khg.html">KHG</A><P>
<P>
<H2><A NAME="ss8.3">8.3 Driver interface to the kernel</A>
</H2>
<P>
<P>Here are some notes on the functions that you would have to
write if creating a new driver. Reading this in conjunction
with the above skeleton driver may help clear things up.
<P>
<P>
<H3>Probe</H3>
<P>
<P>Called at boot to check for existence of card. Best if it
can check un-obtrsively by reading from memory, etc. Can
also read from I/O ports. Initial writing to I/O ports in a probe
is <EM>not good</EM> as it may kill another device.
Some device initialization is usually done here (allocating
I/O space, IRQs,filling in the dev->??? fields etc.)
You need to know what io ports/mem the card can be
configured to, how to enable shared memory (if used)
and how to select/enable interrupt generation, etc.
<P>
<H3>Interrupt handler</H3>
<P>
<P>Called by the kernel when the card posts an interrupt.
This has the job of determining why the card posted
an interrupt, and acting accordingly. Usual interrupt
conditions are data to be rec'd, transmit completed,
error conditions being reported. You need to know
any relevant interrupt status bits so that you can
act accordingly.
<P>
<H3>Transmit function</H3>
<P>
<P>Linked to dev->hard_start_xmit() and is called by the
kernel when there is some data that the kernel wants
to put out over the device. This puts the data onto
the card and triggers the transmit. You need to
know how to bundle the data and how to get it onto the
card (shared memory copy, PIO transfer, DMA?) and in
the right place on the card. Then you need to know
how to tell the card to send the data down the wire, and
(possibly) post an interrupt when done.
When the hardware can't accept additional packets it should set
the dev->tbusy flag. When additional room is available, usually
during a transmit-complete interrupt, dev->tbusy should be cleared
and the higher levels informed with <CODE>mark_bh(INET_BH)</CODE>.
<P>
<H3>Receive function</H3>
<P>
<P>Called by the kernel interrupt handler when the card reports
that there is data on the card. It pulls the data off
the card, packages it into a sk_buff and lets the
kernel know the data is there for it by doing a
netif_rx(sk_buff). You need to know how to enable
interrupt generation upon Rx of data, how to check any
relevant Rx status bits, and how to get that data off the
card (again sh mem, PIO, DMA, etc.)
<P>
<H3>Open function</H3>
<P>
<P>linked to dev->open and called by the networking layers
when somebody does <CODE>ifconfig eth0 up</CODE> - this
puts the device on line and enables it for Rx/Tx of
data. Any special initialization incantations that were
not done in the probe sequence (enabling IRQ generation, etc.)
would go in here.
<P>
<H3>Close function (optional)</H3>
<P>
<P>This puts the card in a sane state when someone
does <CODE>ifconfig eth0 down</CODE>.
It should free the IRQs and DMA channels if the hardware permits,
and turn off anything that will save power (like the transceiver).
<P>
<H3>Miscellaneous functions</H3>
<P>
<P>Things like a reset function, so that if things go south,
the driver can try resetting the card as a last ditch effort.
Usually done when a Tx times out or similar. Also a function
to read the statistics registers of the card if so equipped.
<P>
<H2><A NAME="3com-tech"></A> <A NAME="ss8.4">8.4 Technical information from 3Com</A>
</H2>
<P>
<P>If you are interested in working on drivers for 3Com cards,
you can get technical documentation from 3Com. Cameron has
been kind enough to tell us how to go about it below:
<P>3Com's Ethernet Adapters are documented for driver writers
in our `Technical References' (TRs). These manuals describe
the programmer interfaces to the boards but they don't talk
about the diagnostics, installation programs, etc that end
users can see.
<P>The Network Adapter Division marketing department has the
TRs to give away. To keep this program efficient, we
centralized it in a thing called `CardFacts.' CardFacts is
an automated phone system. You call it with a touch-tone
phone and it faxes you stuff. To get a TR, call CardFacts
at 408-727-7021. Ask it for Developer's Order Form,
document number 9070. Have your fax number ready when you
call. Fill out the order form and fax it to 408-764-5004.
Manuals are shipped by Federal Express 2nd Day Service.
<P>There are people here who think we are too free with the
manuals, and they are looking for evidence that the system
is too expensive, or takes too much time and effort.
So far, 3Com customers have been really good about
this, and there's no problem with the level of requests
we've been getting. We need your continued cooperation and
restraint to keep it that way.
<P>
<H2><A NAME="amd-notes"></A> <A NAME="ss8.5">8.5 Notes on AMD PCnet / LANCE Based cards</A>
</H2>
<P>
<P>The AMD LANCE (Local Area Network Controller for Ethernet)
was the original offering, and has since been replaced by
the `PCnet-ISA' chip, otherwise known as the 79C960.
Note that the name `LANCE'
has stuck, and some people will refer to the new chip by the old
name. Dave Roberts of the Network Products Division of AMD was kind
enough to contribute the following information regarding this chip:
<P>`Functionally, it is equivalent to a NE1500. The register set
is identical to the old LANCE with the 1500/2100 architecture
additions. Older 1500/2100 drivers will work on the PCnet-ISA.
The NE1500 and NE2100 architecture is basically the same.
Initially Novell called it the 2100, but then tried to distinguish
between coax and 10BASE-T cards. Anything that was 10BASE-T only was
to be numbered in the 1500 range. That's the only difference.
<P>Many companies offer PCnet-ISA based products, including HP,
Racal-Datacom, Allied Telesis, Boca Research, Kingston Technology, etc.
The cards are basically the same except that some manufacturers
have added `jumperless' features that allow the card to
be configured in software. Most have not. AMD offers a standard
design package for a card that uses the PCnet-ISA and many
manufacturers use our design without change.
What this means is that anybody who wants to write drivers for
most PCnet-ISA based cards can just get the data-sheet from AMD. Call
our literature distribution center at (800)222-9323 and ask for the
Am79C960, PCnet-ISA data sheet. It's free.
<P>A quick way to understand whether the card is a `stock' card
is to just look at it. If it's stock, it should just have one large
chip on it, a crystal, a small IEEE address PROM, possibly a socket
for a boot ROM, and a connector (1, 2, or 3, depending on the media
options offered). Note that if it's a coax card, it will have some
transceiver stuff built onto it as well, but that should be near the
connector and away from the PCnet-ISA.'
<P>A note to would-be card hackers is that different LANCE
implementations do `restart' in different ways. Some pick up
where they left off in the ring, and others start right from
the beginning of the ring, as if just initialised.
<P>
<H2><A NAME="promisc"></A> <A NAME="ss8.6">8.6 Multicast and Promiscuous Mode</A>
</H2>
<P>
<P>Another one of the things Donald has worked on is
implementing multicast and promiscuous mode hooks.
All of the <EM>released</EM> (i.e. <B>not</B> ALPHA) ISA drivers
now support promiscuous mode.
<P>Donald writes:
`I'll start by discussing promiscuous mode, which is
conceptually easy to implement. For most hardware you
only have to set a register bit, and from then on you get
every packet on the wire. Well, it's almost that easy;
for some hardware you have to shut the board (potentially
dropping a few packet), reconfigure it, and then re-enable
the ethercard.
OK, so that's easy, so I'll move on something that's not
quite so obvious: Multicast. It can be done two ways:
<P>
<OL>
<LI> Use promiscuous mode, and a packet filter like the
Berkeley packet filter (BPF). The BPF is a pattern matching
stack language, where you write a program that picks out the
addresses you are interested in. Its advantage is that it's
very general and programmable. Its disadvantage is that there
is no general way for the kernel to avoid turning on promiscuous
mode and running every packet on the wire through every registered
packet filter. See
<A HREF="#bpf">The Berkeley Packet Filter</A>
for more info.
</LI>
<LI> Using the built-in multicast filter that most etherchips have.
</LI>
</OL>
<P>I guess I should list what a few ethercards/chips provide:
<P>
<PRE>
Chip/card Promiscuous Multicast filter
----------------------------------------
Seeq8001/3c501 Yes Binary filter (1)
3Com/3c509 Yes Binary filter (1)
8390 Yes Autodin II six bit hash (2) (3)
LANCE Yes Autodin II six bit hash (2) (3)
i82586 Yes Hidden Autodin II six bit hash (2) (4)
</PRE>
<P>
<OL>
<LI> These cards claim to have a filter, but it's a simple
yes/no `accept all multicast packets', or `accept no
multicast packets'.
</LI>
<LI> AUTODIN II is the standard ethernet CRC (checksum)
polynomial. In this scheme multicast addresses are hashed
and looked up in a hash table. If the corresponding bit
is enabled, this packet is accepted. Ethernet packets are
laid out so that the hardware to do this is trivial -- you
just latch six (usually) bits from the CRC circuit (needed
anyway for error checking) after the first six octets (the
destination address), and use them as an index into the
hash table (six bits -- a 64-bit table).
</LI>
<LI> These chips use the six bit hash, and must have the
table computed and loaded by the host. This means the
kernel must include the CRC code.
</LI>
<LI> The 82586 uses the six bit hash internally, but it
computes the hash table itself from a list of multicast
addresses to accept.
</LI>
</OL>
<P>Note that none of these chips do perfect filtering, and we
still need a middle-level module to do the final
filtering. Also note that in every case we must keep a
complete list of accepted multicast addresses to recompute
the hash table when it changes.
<P>
<H2><A NAME="bpf"></A> <A NAME="ss8.7">8.7 The Berkeley Packet Filter (BPF)</A>
</H2>
<P>
<P>The general idea of the developers is
that the BPF functionality should not be provided
by the kernel, but should be in a (hopefully little-used)
compatibility library.
<P>For those not in the know: BPF (the Berkeley Packet Filter)
is an mechanism for specifying to the kernel networking layers
what packets you are interested in. It's implemented as a
specialized stack language interpreter built into a low level
of the networking code. An application passes a program
written in this language to the kernel, and the kernel runs the
program on each incoming packet. If the kernel has multiple
BPF applications, each program is run on each packet.
<P>The problem is that it's difficult to deduce what kind of
packets the application is really interested in from the packet
filter program, so the general solution is to always run the
filter. Imagine a program that registers a BPF program to
pick up a low data-rate stream sent to a multicast address.
Most ethernet cards have a hardware multicast address filter
implemented as a 64 entry hash table that ignores most unwanted
multicast packets, so the capability exists to make this a very
inexpensive operation. But with the BPF the kernel must switch
the interface to promiscuous mode, receive _all_ packets, and
run them through this filter. This is work, BTW, that's very
difficult to account back to the process requesting the packets.
<P>
<HR>
<A HREF="Ethernet-HOWTO-9.html">´ÙÀ½</A>
<A HREF="Ethernet-HOWTO-7.html">ÀÌÀü</A>
<A HREF="Ethernet-HOWTO.html#toc8">Â÷·Ê</A>
</BODY>
</HTML>