respectively and fix all bus_dma(9) issues seen when bounce buffers
are used.
o Setup frame handling had no bus_dmamap_sync(9) which prevented
driver from configuring RX filter. Add missing bus_dmamap_sync(9)
in both dc_setfilt_21143()/dc_setfilt_xircom() and dc_txeof().
o Use bus_addr_t for DMA segment instead of using u_int32_t.
o Introduce dc_dma_alloc()/dc_dma_free() functions to allocate/free
DMA'able memory.
o Create two DMA descriptor list for each TX/RX lists. This change
will minimize the size of bounce buffers that would be used in
each TX/RX path. Previously driver had to copy both TX/RX lists
when bounce buffer is active.
o 21143 data sheet says descriptor list requires 4 bytes alignment.
Remove PAGE_SIZE alignment restriction and use
sizeof(struct dc_dec).
o Setup frame requires 4 bytes alignment. Remove PAGE_SIZE
alignment restriction and use sizeof(struct dc_dec).
o Add missing DMA map unload for both setup frame and TX/RX
descriptor list.
o Overhaul RX handling logic such that make driver always allocate
new RX buffer with dc_newbuf(). Previously driver allowed to
copy received frame with m_devget(9) after passing the
descriptor ownership to controller. This can lead to passing
wrong frame to upper stack.
o Introduce dc_discard_rxbuf() which will discard received frame
and reuse loaded DMA map and RX mbuf.
o Correct several wrong bus_dmamap_sync(9) usage in dc_rxeof and
dc_txeof. The TX/RX descriptor lists are updated by both driver
and HW so READ/WRITE semantics should be used.
o If driver failed to allocate new RX buffer, update if_iqdrops
counter instead of if_ierrors since driver received the frame
without errors.
o Make sure to unload loaded setup frame DMA map in dc_txeof and
clear the mark of setup frame of the TX descriptor in dc_txeof().
o Add check for possible TX descriptor overruns in dc_encap() and
move check for free buffer to caller, dc_start_locked().
o Swap the loaded DMA map and the last DMA map for multi-segmented
frames. Since dc_txeof() assumes the last descriptor of the
frame has the DMA map, driver should swap the first and the last
DMA map in dc_encap(). Previously driver tried to unload
not-yet-loaded DMA map such that the loaded DMA map was not
unloaded at all for multi-segmented frames.
o Rewrite DC_RXDESC/DC_TXDESC macro to simpler one.
o Remove definition of ETHER_ALIGN, it's already defined in
ethernet.h.
With this changes, dc(4) works with bounce buffers and it shall
also fix issues which might have shown in PAE environments.
Tested by: marius
request TX completion interrupt for every 8-th frames. Previously
dc(4) requested TX completion interrupt if number of queued TX
descriptors is greater than 64. This caused a lot of TX completion
interrupt under high TX load once driver queued more than 64 TX
descriptors. It's quite normal to see more than 64 queued TX
descriptors under high TX load.
This change reduces the number of TX completion interrupts to be
less than 17k under high TX load. Because this change does not
generate TX completion interrupt for each frame, add reclaiming
transmitted buffers in dc_tick not to generate false watchdog
timeouts.
While I'm here add check for queued descriptors in dc_txeof() since
there is no more work to do when there is no pending descriptors.
frame in DM910x controllers. In r67595(more than 10 years ago) it
was replaced to use "Store and Forward" mode and made controller
generate TX completion interrupt for every frame.
port such that reading station address from second port always
returned 0xFF:0xFF:0xFF:0xFF:0xFF:0xFF Unfortunately it seems there
is no easy way to know whether SROM is shared or not. Workaround
the issue by traversing dc(4) device list and see whether we're
using second port and use station address of controller 0 as base
station address of second port.
PR: kern/79262
MFC after: 2 weeks
drivers, there should be a 1us delay after every write when
bit-banging the MII. Also insert barriers in order to ensure
the intended ordering. These changes hopefully will solve the
bus wedging occasionally experienced with DM9102A since r182461.
- Deobfuscate dc_mii_readreg() a bit.
stopped nor the waiting state and also no other means to check
whether the receiver is idle (see also r163774), we have no choice
than to call mii_tick(9) unconditionally even in the case of the
DC_REDUCED_MII_POLL handling as far as the RX side is concerned.
This isn't necessarily worse than checking whether RX is idle
though because unlike as with TX we're racing with the hardware,
which might receive packets any time while we poll the MII, anyway.
Reported and tested by: Jacob Owens
Reviewed by: yongari
MFC after: 3 days
- Correct the maxsize parameter when creating the mbufs busdma tag to
reflect the actual requirement of dc(4).
- Move the KASSERT in dc_newbuf() to the right spot.
- Also convert the TX side to take advantage of bus_dmamap_load_mbuf_sg(9).
- Move the comment regarding dc_start_locked() to the right spot.
MFC after: 2 weeks
requiring DC_TX_ALIGN or DC_TX_COALESCE, which was previously done
in dc_start_locked(), into dc_encap().
o In dc_encap():
- If m_defrag() fails just drop the packet like other NIC drivers
do. This should only happen when there's a mbuf shortage, in which
case it was possible to end up with an IFQ full of packets which
couldn't be processed as they couldn't be defragmented as they
were taking up all the mbufs themselves. This includes adjusting
dc_start_locked() to not trying to prepend the mbuf (chain) if
dc_encap() has freed it.
- Likewise, if bus_dmamap_load_mbuf() fails as dc_dma_map_txbuf()
failed, free the mbuf possibly allocated by the above call to
m_defrag() and drop the packet.
o In dc_txeof():
- Don't clear IFF_DRV_OACTIVE unless there are at least 6 free TX
descriptors. Further down the road dc_encap() will bail if there
are only 5 or fewer free TX descriptors, causing dc_start_locked()
to abort and prepend the dequeued mbuf again so it makes no sense
to pretend we could process mbufs again when in fact we won't.
While at it replace this magic 5 with a macro DC_TX_LIST_RSVD.
- Just always assign idx to sc->dc_cdata.dc_tx_cons; it doesn't
make much sense to exclude the idx == sc->dc_cdata.dc_tx_cons
case.
o In dc_dma_map_txbuf() there's no need to set sc->dc_cdata.dc_tx_err
to error if the latter is != 0, bus_dmamap_load_mbuf() already
returns the same error value in that case anyway.
o For less overhead, convert to use bus_dmamap_load_mbuf_sg() for
loading RX buffers.
o Remove some banal and/or outdated comments.
Approved by: re (kensmith)
MFC after: 1 week
depending on the NIC and isn't used at all with HomePNA links)
instead of if_slowtimo() for driving dc_watchdog() in order to
avoid races accessing if_timer.
- Use bus_get_dma_tag() so dc(4) works on platforms requiring it.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
- Remove an alpha remnant in dc_softc.
if_watchdog, etc., or in functions used only in these methods.
In all other functions in the driver use device_printf().
- Use __func__ instead of typing function name.
Submitted by: Alex Lyashkov <umka sevcity.net>
vendor-specific device ids across vendors.
- Include the revision in the dc_devs[] array instead of special casing
the revid handling in dc_devtype().
- Use PCI bus accessors to read registers instead of pci_read_config()
where possible.
- Use an 8-bit write to update the latency timer.
- Use PCIR_xxx constants and remove unused DC_xxx related to standard
PCI config registers.
MFC after: 1 week
commit. Copy the ethernet address into a local buffer, which we know
is sufficiently aligned for the width of the memory accesses that we
do. This also eliminates all suspicious and potentionally harmful
casts.
In collaboration with: ru
struct ifnet or the layer 2 common structure it was embedded in have
been replaced with a struct ifnet pointer to be filled by a call to the
new function, if_alloc(). The layer 2 common structure is also allocated
via if_alloc() based on the interface type. It is hung off the new
struct ifnet member, if_l2com.
This change removes the size of these structures from the kernel ABI and
will allow us to better manage them as interfaces come and go.
Other changes of note:
- Struct arpcom is no longer referenced in normal interface code.
Instead the Ethernet address is accessed via the IFP2ENADDR() macro.
To enforce this ac_enaddr has been renamed to _ac_enaddr.
- The second argument to ether_ifattach is now always the mac address
from driver private storage rather than sometimes being ac_enaddr.
Reviewed by: sobomax, sam
frame, not the first. It is probably also not safe to free the mbuf chain
as soon as the OWN bit is cleared on the first descriptor since the chip
may not be done copying the frame into the transmit FIFO. Revert the part of
of busdma conversion (if_dc.c rev 1.115) which changed dc_txeof() to look for
the status in the first descriptor and free the mbuf chain when processing
the first descriptor for the frame, and revert the matching changes elsewhere
in the driver. This part of the busdma change caused the driver to report
spurious collisions and output errors, even when running in full-duplex mode.
Reverting the mbuf chain handling slightly complicates dc_dma_map_txbuf(),
since it is responsible for setting the OWN bits on the descriptors, but does
not normally have direct access to the mbuf chain.
Tested by:
Dejan Lesjak <dejan.lesjak at ijs.si> alpha/<Intel 21143 10/100BaseTX>
"Xin LI" <delphij at frontfree.net> i386/<Macronix 98713 10/100BaseTX>
Wiktor Niesiobedzki <bsd at w.evip.pl> i386/<3Com OfficeConnect 10/100B>
Reviewed by: mux
the packets are immediately returned for sending (e.g. when bridging
or packet forwarding). There are more efficient ways to do this
but for now use the least intrusive approach.
Reviewed by: imp, rwatson
for 21143 based cards which use SIA mode.
This fixes 10mbit mode for ZNYX ZX346Q cards and other
21143 based cards.
PR: 32118
Submitted by: Rene de Vries <rene@tunix.nl>
Geert Jan de Groot <GeertJan.deGroot@tunix.nl>
Obtained from: BSDI
MFC after: 2 weeks
- MN-110 10/100 USB ethernet (ADMtek Pegasus II, if_aue)
- MN-120 10/100 cardbus (ADMtek Centaur-C, if_dc)
- MN-130 10/100 PCI (ADMtek Centaur-P, if_dc)
Also update dc(4) man page to mention support for MN-120 and MN-130.
to have this driver working on sparc64. It still needs to be made
endian-clean before it can work there.
Special thanks to dragonk@evilcode.net for sending me a dc(4) card so
that I was able to do this work.
Many cheers to all the people that tested this change, thanks to them,
this change shouldn't break anything :-).
Tested by: marcel (i386 and ia64), ru (i386), wilko (alpha),
mbr (i386), wpaul (i386) and
Will Saxon <WillS@housing.ufl.edu> (i386)
OpenBSD who got the code (or the idea) from the NetBSD tlp driver.
This gets some cardbus dc cards working (either completely or nearly
so). It also appears to get additional pci cards working, without
breaking working ones.
# Maybe some additional work is needed here. Also, the cardbus attachment
# might need to match on the CIS rather than on the vendor/device so we have
# a finer level of detail as to what the card is. Technically, the
# vendor/device fields are undefined for CardBus (even though most cards are
# using common silicon with pci models).
This is temporary hack, better and generalized solution probably
should be implemented at lower layer(MII or PCI?).
Tested by: shoko.araki@soliton.co.jp
MFC after: 1 week
Non-SMP, i386-only, no polling in the idle loop at the moment.
To use this code you must compile a kernel with
options DEVICE_POLLING
and at runtime enable polling with
sysctl kern.polling.enable=1
The percentage of CPU reserved to userland can be set with
sysctl kern.polling.user_frac=NN (default is 50)
while the remainder is used by polling device drivers and netisr's.
These are the only two variables that you should need to touch. There
are a few more parameters in kern.polling but the default values
are adequate for all purposes. See the code in kern_poll.c for
more details on them.
Polling in the idle loop will be implemented shortly by introducing
a kernel thread which does the job. Until then, the amount of CPU
dedicated to polling will never exceed (100-user_frac).
The equivalent (actually, better) code for -stable is at
http://info.iet.unipi.it/~luigi/polling/
and also supports polling in the idle loop.
NOTE to Alpha developers:
There is really nothing in this code that is i386-specific.
If you move the 2 lines supporting the new option from
sys/conf/{files,options}.i386 to sys/conf/{files,options} I am
pretty sure that this should work on the Alpha as well, just that
I do not have a suitable test box to try it. If someone feels like
trying it, I would appreciate it.
NOTE to other developers:
sure some things could be done better, and as always I am open to
constructive criticism, which a few of you have already given and
I greatly appreciated.
However, before proposing radical architectural changes, please
take some time to possibly try out this code, or at the very least
read the comments in kern_poll.c, especially re. the reason why I
am using a soft netisr and cannot (I believe) replace it with a
simple timeout.
Quick description of files touched by this commit:
sys/conf/files.i386
new file kern/kern_poll.c
sys/conf/options.i386
new option
sys/i386/i386/trap.c
poll in trap (disabled by default)
sys/kern/kern_clock.c
initialization and hardclock hooks.
sys/kern/kern_intr.c
minor swi_net changes
sys/kern/kern_poll.c
the bulk of the code.
sys/net/if.h
new flag
sys/net/if_var.h
declaration for functions used in device drivers.
sys/net/netisr.h
NETISR_POLL
sys/dev/fxp/if_fxp.c
sys/dev/fxp/if_fxpvar.h
sys/pci/if_dc.c
sys/pci/if_dcreg.h
sys/pci/if_sis.c
sys/pci/if_sisreg.h
device driver modifications
Introduce an additional device flag for those NICs which require the
transmit buffers to be aligned to 32-bit boundaries.
(the equivalen fix for STABLE is slightly simpler because there are
no supported chips which require this alignment there.)
laptops with this chip should test this and report back as I don't have
access to this hardware myself. People with -stable systems should try
the patch at:
http://www.freebsd.org/~wpaul/conexant.patch.gz
Submitted by: Phil Kernick <Phil@Kernick.org>
mtx_enter(lock, type) becomes:
mtx_lock(lock) for sleep locks (MTX_DEF-initialized locks)
mtx_lock_spin(lock) for spin locks (MTX_SPIN-initialized)
similarily, for releasing a lock, we now have:
mtx_unlock(lock) for MTX_DEF and mtx_unlock_spin(lock) for MTX_SPIN.
We change the caller interface for the two different types of locks
because the semantics are entirely different for each case, and this
makes it explicitly clear and, at the same time, it rids us of the
extra `type' argument.
The enter->lock and exit->unlock change has been made with the idea
that we're "locking data" and not "entering locked code" in mind.
Further, remove all additional "flags" previously passed to the
lock acquire/release routines with the exception of two:
MTX_QUIET and MTX_NOSWITCH
The functionality of these flags is preserved and they can be passed
to the lock/unlock routines by calling the corresponding wrappers:
mtx_{lock, unlock}_flags(lock, flag(s)) and
mtx_{lock, unlock}_spin_flags(lock, flag(s)) for MTX_DEF and MTX_SPIN
locks, respectively.
Re-inline some lock acq/rel code; in the sleep lock case, we only
inline the _obtain_lock()s in order to ensure that the inlined code
fits into a cache line. In the spin lock case, we inline recursion and
actually only perform a function call if we need to spin. This change
has been made with the idea that we generally tend to avoid spin locks
and that also the spin locks that we do have and are heavily used
(i.e. sched_lock) do recurse, and therefore in an effort to reduce
function call overhead for some architectures (such as alpha), we
inline recursion for this case.
Create a new malloc type for the witness code and retire from using
the M_DEV type. The new type is called M_WITNESS and is only declared
if WITNESS is enabled.
Begin cleaning up some machdep/mutex.h code - specifically updated the
"optimized" inlined code in alpha/mutex.h and wrote MTX_LOCK_SPIN
and MTX_UNLOCK_SPIN asm macros for the i386/mutex.h as we presently
need those.
Finally, caught up to the interface changes in all sys code.
Contributors: jake, jhb, jasone (in no particular order)
the interface to use callout_* instead of timeout(). Also add an
IS_MPSAFE #define (currently off) which will mark the driver as mpsafe
to the upper layers.