Rev 1.56 of if_dc.c removed calls to mii_pollstat() from the dc_tick()
routine. dc_tick() is called regularly to detect link up and link down
status, especially when autonegotiating.
The expectation was that mii_tick() (which is still called from dc_tick())
would update status information automatically in all cases where it would
be sensible to do so.
Unfortunately, with authentic 21143 chips this is not the case, and
the driver never successfully autonegotiates. This is because (despite
what it says in the 21143 manual) the chip always claims that link is not
present while the autonegotiation enable bit is set. Autonegotation takes
place and succeeds, but the driver tests the link bits before it switches
off the autonegotiation enable bit, and success is not recognised.
The simplest solution is to call dcphy_status() more often for MII_TICK
calls by dropping out of the switch statement instead of exiting when
we are autonegotiating and link appears to not be present. When
autonegotiation succeeds, dcphy_status() will note the speed and fdx/hdx
state and turn off the autonegotiation enable bit. The next call to
dcphy_status() will notice that link is present, and the dc driver code
will be notified.
Macronix chips also use this code, but implement link detection as
described in the manual, and hence don't need this patch. However, tests
on a Macronix 98715AEC-C show that it does not adversely affect them.
This could be done better but is the minimal effective change, and most
closely mimics what was happening prior to rev 1.56 of if_dc.c. (Actually
I also deleted a small amount of unnecessary code while I was in the area.)
Reviewed by: wpaul
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
One to notify the system that the MTU for VLAN can be 1500 so the vlan
will automatically be configured with a 1500 MTU the other is to ignore
the error case if the received frame is to long.
The frame size notification came from code in the SIS driver, and
the support for long frames derived from the NetBSD Tulip driver.
Tested on: 4 port D-Link adapter DFE-570TX 4 Intel 21143
Netgear card with 82c169 PNIC 10/100BaseTX
Reviewed by: ru (manpage), wpaul (not objected to), archie
Approved by: imp
Obtained from: NetBSD
to Phil Kernick:
"The problem is that in full duplex mode, the Conexant chip always reports a
carrier lost error, even when the frame is successfully sent. So, if we
have a Conexant chip, then ignore carrier lost when in full duplex
mode."
Since the Xircom chips seem to have the same issue and since we already
have a workaround for this, just expand the workaround test to also
check for DC_IS_CONEXANT().
to a label is inside an #ifdef block, then the label should *also* be
inside an #ifdef block. Hide the "done:" label which is only used if
DEVICE_POLLING is enabled under #ifdef DEVICE_POLLING.
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.)
The reason we are required to commit to -current first is so that later
MFC's do not risk the loss of existing bug fixes. Even if this was not
strictly required in -current, it should still be fixed there too.
mbuf allocation fails, and fix (i hope) a couple of style bugs.
I believe these printf() are extremely dangerous because now they can
occur on every incoming packet and are not rate limited. They were
meant to warn the sysadmin about lack of resources, but now they
can become a nice way to panic your system under load.
Other drivers (e.g. the fxp driver) have nothing like this.
There is a pending discussion on putting this kind of warnings
elsewhere, and I hope we can fix this soon.
underlying unaligned bcopy) on incoming packets that are already
available (albeit unaligned) in a buffer.
The performance improvement varies, depending on CPU and memory
speed, but can be quite large especially on slow CPUs. I have seen
over 50% increase on forwarding speed on the sis driver for the
486/133 (embedded systems), which does exactly the same thing.
The behaviour is controlled by a sysctl variable, hw.dc_quick which
defaults to 1. Set it to 0 to restore the old behaviour.
After running a few experiments (in userland, though) I am convinced
that doing the m_devget() is detrimental to performance in almost
all cases.
Even if your CPU has degraded performance with misaligned data,
the bcopy() in the driver has the same overhead due to misaligment
as the one that you save in the uiomove(), plus you do one extra
copy and pollute the cache.
But more often than not, you do not even have to touch the payload,
e.g. when you are forwarding packets, and even in the often-cited
case of NFS, you often end up passing a pointer to the payload to
the disk controller.
In any case, you can play with the sysctl variable to toggle between
the two behaviours, and see if it makes a difference.
MFC-after: 3 days
in the 21143, instead of giving priority to the receive unit.
This gives a 10-15% performance improvement in the forwarding rate
under heavy load.
Reviewed-by: Bill Paul
. Make internal service routines static.
. Use a consistent ordering of checks in MII_TICK. Do the work in the
mii_phy_tick() subroutine if appropriate.
. Call mii_phy_update() to trigger the callbacks.
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>
a bunch of frames. In this case, the dc_link flag is cleared, and dc_start()
stops draining the if_snd send queue, which results in lots of 'no buffers
available' errors being reported to applications. The whole idea behind
not draining the send queue until the link comes up was to avoid having
the gratuitous ARP being lost while we're waiting for autoneg to complete
after the interface is first brought up. As an optimization, change the
test in dc_start() so that we only bail if dc_link is not set _and_ there
are less than 10 packets in the send queue. If the queue has many frames
in it, we need to drain them. If the queue has a small number of frames
in it, we can hold off on sending them until the link comes up.
MFC after: 1 week
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>)
case there is nothing to do. This happens normally when the card shares
the interrupt line with other devices.
This code saves a couple of microseconds per interrupt even on a
fast CPU. You normally would not care, except under heavy tinygram
traffic where you can have some 50-100.000 interrupts per second...
On passing, correct a spelling error.
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)
if_vr: handle the case where vr_encap() returns failure: bust out of the
packet sending loop instead of panicking. Also add some missing
newlines to some printf()s.
if_dc: The miibus_read and miibus_write methods keep swapping in and
out of MII mode by fiddling with CSR6 for cards with MII PHYs.
This is a hack to support the original Macronix 98713 card which
has built-in NWAY that uses an MII-like management interface
even though it uses serial transceivers. Conditionalize this
so that we only do this on 98713 chips, since it does bad things
to genuine tulip chips (and maybe other clones).
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.
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.
them. If we leave garbage in them, the dc_apply_fixup() routine may
try to follow bogus pointers when applying the reset fixup.
Noticed by: Andrew Gallatin
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.
the PCI latency timer value to 0x80. Davicom's Linux driver does this,
and it drastically reduces the number of TX underruns in my tests. (Note:
this is done only for the Davicom chips. I'm not sure it's a good idea to
do it for all of them.)
Again, still waiting on confirmation before merging to stable.
DM9100/DM9102 chips. Do not set DC_TX_ONE. The DC_TX_USE_TX_INTR flag
causes dc_encap() to set the 'interrupt on TX completion' bit only
once every 64 packets. This is an attempt to reduce the number
of interrupts generated by the chip. You're supposed to get a 'no more
TX buffers left' interrupt once you hit the last packet whether you
ask for one or not, however it seems the Davicom chip doesn't generate
this interrupt, or at least it doesn't generate it under the same
circumstances. The result is that if you transmit n packets, where
n is less than 64, and then wait 5 seconds, you'll get a watchdog
timeout whether you want one or not. The DC_TX_INTR_ALWAYS causes
dc_encap() to request an interrupt for every frame.
I'm still waiting on confirmation from a couple of users to see if this
fixes their problems with the Davicom DM9102 before I merge this into
-stable, but this fixed the problem for me in my own testing so I'm
willing to make the change to -current right away.
This commit adds support for Xircom X3201 based cardbus cards.
Support for the TDK 78Q2120 MII is also added.
IBM Etherjet, Intel and Xircom cards uses these chips.
Note that as a result of this commit, some Intel/DEC 21143 based cardbus
cards will also attach, but not get link. That is being looked at.