series, the 8139C+ has a descriptor-based DMA mechanism, and its
performance is actually pretty respectable. Note: the 8139D chip does
not support C+ mode. Only the 8139C+ and 8169 gigE chips support C+ mode.
Supported features:
- RX and TX checksum offload
- hardware VLAN tag insertion/extraction
- TX interrupt moderation using the 8139's on-board timer
Everything should be properly busdma'ed and endian-independent, so
things should work ok on non-x86 platforms. Unfortunately, my call
for testers on this code was met with deafening silence, and I don't
have access to any non-x86 FreeBSD boxes at the moment, so this is
speculation.
The device detection code has been cleaned up a little as well
(thanks to Michal Mertl) for the patches.
There are also updates to the rl(4) man page (which I accidentally
checked in before when I updated the dc(4) man page. Oops.)
Todo: finish support for the 8169 gigabit ethernet chip. This
mainly requires writing an rlgphy driver to handle the 8169's built-in
PHY. This will have to wait until I actually get my hands on an 8169
card for testing though. (I still can't find a source for one in the
U.S. Suggestions/pointers welcome.)
forced to do slightly bogus power state manipulation. However, this
is one of those features that is preventing further progress, so mark
them as BURN_BIRDGES like I did for the drivers in sys/dev/...
This, like the other change, are a no-op unless you have BURN_BRIDGES
in your kernel.
Add two new arguments to bus_dma_tag_create(): lockfunc and lockfuncarg.
Lockfunc allows a driver to provide a function for managing its locking
semantics while using busdma. At the moment, this is used for the
asynchronous busdma_swi and callback mechanism. Two lockfunc implementations
are provided: busdma_lock_mutex() performs standard mutex operations on the
mutex that is specified from lockfuncarg. dftl_lock() is a panic
implementation and is defaulted to when NULL, NULL are passed to
bus_dma_tag_create(). The only time that NULL, NULL should ever be used is
when the driver ensures that bus_dmamap_load() will not be deferred.
Drivers that do not provide their own locking can pass
busdma_lock_mutex,&Giant args in order to preserve the former behaviour.
sparc64 and powerpc do not provide real busdma_swi functions, so this is
largely a noop on those platforms. The busdma_swi on is64 is not properly
locked yet, so warnings will be emitted on this platform when busdma
callback deferrals happen.
If anyone gets panics or warnings from dflt_lock() being called, please
let me know right away.
Reviewed by: tmm, gibbs
bit in the EEPROM mode register on. Also, the address must be written
in two 32-bit register accesses instead of 6 8-bit accesses.
Tested with my 8139B cardbus NIC.
PR: kern/35900
Submitted by: Mark Kettenis <kettenis@chello.nl>
if attach succeeded. device_is_alive just tells us that probe
succeeded. Since we were using it to do things like detach net
interfaces, this caused problems when there were errors in the attach
routine.
Symptoms of problem reported by: martin blapp
- Unconditionally call *_stop() if device is in the tree. This is to
prevent callouts from happening after the device is gone. Checks for
bus_child_present() should be added in the future to keep from touching
potentially non-existent hardware in *_detach(). Found by iedowse@.
- Always check for and free miibus children, even if the device is not in
the tree since some failure cases could have gotten here.
- Call ether_ifdetach() in the irq setup failure case
- ti(4), xl(4): move ifmedia_init() calls to the beginning of attach so
that ifmedia_removeall() can be unconditionally called on detach. There
is no way to detect whether ifmedia has been initialized without using
a separate variable (as tl(4) does).
- Add comments to indicate assumptions of code path
network layer (ether).
- Don't abuse module names to facilitate ifconfig module loading;
such abuse isn't really needed. (And if we do need type information
associated with a module then we should make it explicit and not
use hacks.)
unencapsulated packet back into the IFQ. Unfortunately, the only reason
rl_encap would fail was due to m_defrag failing, which should only happen
when we're low on mbufs. Hence, it was possible for us to end up with
an IFQ full of packets which could never clear the queue because they could
never be defragmented because they were themselves taking up all the mbufs.
To solve this, take if_xl's approach to the problem of encapsulation failure:
drop the packet.
MFC after: 3 days
- Remove locking of the softc in the attach method, instead depending on
bus_setup_intr being at the end of attach (delaying interrupt enable until
after ether_ifattach is called)
- Call *_detach directly in the error case of attach, depending on checking
in detach to only free resources that were allocated. This puts all
resource freeing in one place, avoiding thinkos that lead to memory leaks.
- Add bus_child_present check to calls to *_stop in the detach method to
be sure hw is present before touching its registers.
- Remove bzero softc calls since device_t should do this for us.
- dc: move interrupt allocation back where it was before. It was unnecessary
to move it. This reverts part of 1.88
- rl: move irq allocation before ether_ifattach. Problems might have been
caused by allocating the irq after enabling interrupts on the card.
- rl: call rl_stop before ether_ifdetach
- sf: call sf_stop before ether_ifdetach
- sis: add missed free of sis_tag
- sis: check errors from tag creation
- sis: move dmamem_alloc and dmamap_load to happen at same time as tag creation
- sk: remove duplicate initialization of sk_dev
- ste: add missed bus_generic_detach
- ti: call ti_stop before ether_ifdetach
- ti: add missed error setting in ti_rdata alloc failure
- vr: add missed error setting in I/O, memory mapping cases
- xl: add missed error setting in I/O, memory mapping cases
- xl: remove multi-level goto on attach failure
- xl: move dmamem_alloc and dmamap_load to happen at same time as tag creation
- Calls to free(9) are unconditional because it is valid to call free with a
null pointer.
Reviewed by: imp, mdodd
is read one clock edge too late. This bit is driven low by
slave (as any other input data bits from slave) when the clock
is LOW. The current code did read the bit after the clock was
driven high again.
Reviewed by: luoqi
MFC after: 2 weeks
o use if_input for input packet processing
o don't strip the Ethernet header for input packets
o use BPF_* macros bpf tapping
o call ether_ioctl to handle default ioctl case
o track vlan changes
Reviewed by: many
Approved by: re
has gone away instead of spinning in the interrupt handler. This stops
my machine from hanging when I eject a rl(4)-based cardbus card.
Reviewed by: imp
the same thing as the SMC 1211, but with their own vendor ID.
Update the device list to support this NIC. (Discovered these
cards lying around the lab at work.)
doesn't support NWAY, the RealTek PHY (both the integrated ones on 8139
chips and the RTL8201L 10/100 PHY) will not report the link speed via
the ANLPAR or BMSR registers. For the 8201L, we need to look in magic
vendor-specific PHY register 0x19. For the 8139 MAC+PHY combo, we have
to be able to test the RL_MEDIASTAT register.
The changes to rlphy.c are based largely on the patch from PR 30836,
however I tried to eliminate some magic numbers by creating an entry
for the 8201 PHY in miidevs.
Also updated if_rl.c to allow the rlphy driver to read the RL_MEDIASTAT
register via the rl_miibus_readreg() routine.
most cases NULL is passed, but in some cases such as network driver locks
(which use the MTX_NETWORK_LOCK macro) and UMA zone locks, a name is used.
Tested on: i386, alpha, sparc64
calling vtophys() and contigmalloc()/contigfree() directly. Hopefully,
I have shaken out all of the problems with busdma on the alpha now.
(Everything seems to work as expected.)
Also, change the max RX DMA limit to 1024 bytes instead of "unlimited,"
as the latter seems not to work correctly on the alpha that I tested.
(At 100Mbps, all attempts to receive frames yield RX errors.)
something: offset into the first mbuf of the target chain before copying
the source data over.
Make drivers using m_devget() with a first argument "data - ETHER_ALIGN"
to use the offset argument to pass ETHER_ALIGN in. The way it was previously
done is potentially dangerous if the source data was at the top of a page
and the offset caused the previous page to be copied (if the
previous page has not yet been appropriately mapped).
The old `offset' argument in m_devget() is not used anywhere (it's always
0) and dates back to ~1995 (and earlier?) when support for ethernet trailers
existed. With that support gone, it was merely collecting dust.
Tested on alpha by: jlemon
Partially submitted by: jlemon
Reviewed by: jlemon
MFC after: 3 weeks
- Use pci_get_powerstate()/pci_set_powerstate() in all the other drivers
that need them so we don't have to fiddle with the PCI power management
registers directly.
- Use pci_enable_busmaster()/pci_enable_io() to turn on busmastering and
PIO/memory mapped accesses.
- Add support to the RealTek driver for the D-Link DFE-530TX+ which has
a RealTek 8139 with its own PCI ID. (Submitted by Jason Wright)
- Have the SiS 900/National DP83815 driver be sure to disable PME
mode in sis_reset(). This apparently fixes a problem on some
motherboards where the DP83815 chip fails to receive packets.
(Submitted by Chuck McCrobie <mccrobie@cablespeed.com>)
All calls to mtx_init() for mutexes that recurse must now include
the MTX_RECURSE bit in the flag argument variable. This change is in
preparation for an upcoming (further) mutex API cleanup.
The witness code will call panic() if a lock is found to recurse but
the MTX_RECURSE bit was not set during the lock's initialization.
The old MTX_RECURSE "state" bit (in mtx_lock) has been renamed to
MTX_RECURSED, which is more appropriate given its meaning.
The following locks have been made "recursive," thus far:
eventhandler, Giant, callout, sched_lock, possibly some others declared
in the architecture-specific code, all of the network card driver locks
in pci/, as well as some other locks in dev/ stuff that I've found to
be recursive.
Reviewed by: jhb
PCI code. This saves each driver from having to grovel around looking
for the right registers to twiddle.
I should eventually convert the other PCI drivers to do this; for now,
these three are ones which I know need power state handling.
(identified by the IO map being 256 bytes long instead of 128)
This chip works very unreliably on my Lanner embedded PC with the rl driver.
Lots of watchdog timeouts or poor performance.
Forcing the media type to 10 Meg (ifconfig rl0 media 10baseT/UTP) is a good
workaround.
This looks very similar to the problem reported in PR kern/18790
It is interesting to note that the linux driver has lots of special
case code for this chip.
- Add DRIVER_MODULE() declaration to make this driver a
child of cardbus
- Handle different width EEPROMs
The CIS parser still barfs when scanning this card, but it seems to
probe/attach correctly anyway. I can't do a traffic test just yet
since I don't have a proper crossover cable handy.
a RealTek 8139 cardbus device. Unfortunately it doesn't quite work yet
because the CIS parser barfs on it.
Submitted by msmith, with some small tweaks by me.
takes care of all the 10/100 and gigE PCI drivers that I've done.
Next will be the wireless drivers, then the USB ones. I may pick up
some stragglers along the way. I'm sort of playing this by ear: if
anyone spots any places where I've screwed up horribly, please let me
know.
ether_ifdetach().
The former consolidates the operations of if_attach(), ng_ether_attach(),
and bpfattach(). The latter consolidates the corresponding detach operations.
Reviewed by: julian, freebsd-net
of the individual drivers and into the common routine ether_input().
Also, remove the (incomplete) hack for matching ethernet headers
in the ip_fw code.
The good news: net result of 1016 lines removed, and this should make
bridging now work with *all* Ethernet drivers.
The bad news: it's nearly impossible to test every driver, especially
for bridging, and I was unable to get much testing help on the mailing
lists.
Reviewed by: freebsd-net
the case where we receive a packet that wraps from the end of the
RX buffer back to the start. This fixes an unaligned access trap on
the alpha with NFS.
Note that if_aue doesn't strictly depend on usb because it uses the
method interface for calls rather than using internal symbols, and
because it's a child driver of usb and therefore will not try and do
anything unless the parent usb code is loaded at some point. if_aue does
strictly depend on miibus as it will fail to link if it is missing.
- Only call m_pullup() when necessary.
- Check return value from rl_encap() in rl_start() to avoid panic when
we run out of mbufs. (Fixes PR kern/17582)
PR: kern/17582
frames would be handled incorrectly due to bad usage of m_pullup() in
the case where the frame wraps from the end of the receive buffer back
the beginning.
Also, when manually extending small packets to pad them to the minimum
frame length during transmission, zero out the pad area to make some
really paranoid people happy.
- Fix a bug in rl_rxeof() handler: in the case where the packet wraps
from the end of the receive buffer back to the beginning, we need to
insure that at least sizeof(ether_header) bytes make it into the first
mbuf. If we don't, then doing eh = mtod(m, struct ether_header *)
loses. To avoid this, we use m_pullup() to suck at least MHLEN -
RL_ETHER_ALIGN bytes into the first mbuf, which should also help
small packets fit into a single mbuf.
Pointed out by: Philip A. Prindeville <philipp@zembu.com>
- Make the transmit threshold autotuning: start off with a small value
and jack it up when TX underruns are detected.
- Also improve TX error recovery: kick the chip in the head with a
reset/init sequence to make sure it recovers afer a transmit error.
there are stubs compiled into the kernel if BPF support is not enabled,
there aren't any problems with unresolved symbols. The modules in /modules
are compiled with BPF support enabled anyway, so the most this will do is
bloat GENERIC a little.
declaration for the interface driver from "foo" to "if_foo" but leave the
declaration for the miibus attached to the interface driver alone. This
lets the internal module name be "if_foo" while still allowing the miibus
instances to attach to "foo."
This should allow ifconfig to autoload driver modules again without
breaking the miibus attach.
This whole idea isn't going to work until somebody makes the bus/kld
code smarter. The idea here is to change the module's internal name
from "foo" to "if_foo" so that ifconfig can tell a network driver from
a non-network one. However doing this doesn't work correctly no matter
how you slice it. For everything to work, you have to change the name
in both the driver_t struct and the DRIVER_MODULE() declaration. The
problems are:
- If you change the name in both places, then the kernel thinks that
the device's name is now "if_foo", so you get things like:
if_foo0: <FOO ethernet> irq foo at device foo on pcifoo
if_foo0: Ethernet address: foo:foo:foo:foo:foo:foo
This is bogus. Now the device name doesn't agree with the logical
interface name. There's no reason for this, and it violates the
principle of least astonishment.
- If you leave the name in the driver_t struct as "foo" and only
change the names in the DRIVER_MODULE() declaration to "if_foo" then
attaching drivers to child devices doesn't work because the names don't
agree. This breaks miibus: drivers that need to have miibuses and PHY
drivers attached never get them.
In other words: damned if you do, damned if you don't.
This needs to be thought through some more. Since the drivers that
use miibus are broken, I have to change these all back in order to
make them work again. Yes this will stop ifconfig from being able
to demand load driver modules. On the whole, I'd rather have that
than having the drivers not work at all.
This fixes, at least, panics in ncr_attach() on i386's with about 5MB
of memory. The restriction was a hack to leave some low memory for ISA
DMA, but on i386's we now allocate pages from the top down, so all the
restriction did was cause our allocations to fail when there is no free
memory above 1MB.
events, in order to pave the way for removing a number of the ad-hoc
implementations currently in use.
Retire the at_shutdown family of functions and replace them with
new event handler lists.
Rework kern_shutdown.c to take greater advantage of the use of event
handlers.
Reviewed by: green
compiles cleanly on the Alpha. (On the alpha, the port type is an int,
not a short).
Cast a couple of pointers to ints via 'uintptr_t' rather than 'unsigned
int' since uintptr_t is long (64 bit) on Alpha, as are pointers.
few changes:
- there was a bug in rl_list_tx_init(): it was calculating the registers
to initialize incorrectly. Not a problem on the x86 where unaligned
access are allowed, but a problem on the alpha.
- set rl_btag accordingly depending on the machine type
- rl_rxeof() needs to be sure to longword-align the packet data. This
is a little tricky since we copy the data out of the receive buffer
using m_devget(), however there's no way to tell m_devget() to fill
in the mbufs starting at a particular offset. To get around this,
we tell m_devget to copy bytes+2 bytes starting at offset offset-2. This
results in the proper alignment, and we can trim off the two leading
bytes afterwards with m_adj(). We also allocate some extra space before
the start of the receive buffer so that we don't get into trouble in
the case where offset == 0.
- redefine vtophys() in if_rlreg.h for the alpha.
Making this chipset work on the alpha is sort of the inverse of putting
a jet engine on a rowboat (putting a propeller on a 747?) but when
you can get these things for $5 a pop, it's hard to stop people from
buying them.
#define COMPAT_PCI_DRIVER(name,data) DATA_SET(pcidevice_set,data)
.. to 2.2.x and 3.x if people think it's worth it. Driver writers can do
this if it's not defined. (The reason for this is that I'm trying to
progressively eliminate use of linker_sets where it hurts modularity and
runtime load capability, and these DATA_SET's keep getting in the way.)
- Rewrite the transmit section to be a little less bogus.
- Set ifq_maxlen correctly. RL_TX_LIST_CNT - 1 is wrong, because for the
RealTek, RL_TX_LIST_CNT is 4. Set it to IFQ_MAXLEN instead.
Addtron appear to have their own VIA Rhine II and RealTek 8139 boards
with custom PCI vendor and device IDs. This commit updates the PCI
vendor and device lists in the vr and rl drivers so that we can probe
the additional devices.
Found by: nosing around the PCI vendor and device code list at:
http://www.halcyon.com/scripts/jboemler/pci/pcicode
of the CRC as the multicast hash table bit, not the lower six bits. Plus
we have to flip on all bits in the table for multicast mode.
Pointed out by: Kazushi SUGYO <k-sugyou@nwsl.mesh.ad.jp>
as a RealTek 8139
if_rlreg.h: use bus_space_read_X() in CSR_READ_X() macros instead of
directly calling inb()/outb() etc...
rl.4 + RELNOTES.TXT: mention that SMC EtherEZ PCI 1211-TX is supported
by the RealTek driver
which is either a RealTek 8139 in disguise or a RealTek workalike.
This commit fixes the PCI vendor/device ID for this device
and updates the description string to reflect the actual identity
of the device.
I also changed the transmit encapsulation routine to always to
buffer copies on transmit. We end up doing this 99% of the time
anyway. I also tweaked the code that pads packets out to the minimum
length (60) bytes. I was fixing up the m_pkthdr.len value but not
m_len. I don't think this makes that much difference in the grand
scheme of things, but it makes me feel better.
RealTek 8129/8139 chipset like I've been threatening. Update kernel
configs, userconfig.c, relnotes and sysinstall. No man page yet;
comming soon.
I consider this driver stable enough that I want to give it some
exposure in -current.