sparc64 GENERIC and the sound device drivers known working on sparc64
to use bus_get_dma_tag() to obtain the parent DMA tag so we can get rid
of the sparc64_root_dma_tag kludge eventually. Except for ath(4), sk(4),
stge(4) and ti(4) these changes are runtime tested (unless I booted up
the wrong kernels again...).
operation as it ran out of free descriptors or if there are too many
segments in the first place, call bus_dmamap_unload() in order to
unload the already loaded segments.
For trying to map the defragmented mbuf (chain) in re_encap() this
introduces re_dma_map_desc() setting arg.rl_maxsegs to 0 as a new
failure mode. Previously we just ignored this case, corrupting our
view of the TX ring.
o In re_txeof():
- Don't clear IFF_DRV_OACTIVE unless there are at least 4 free TX
descriptors. Further down the road re_encap() will bail if there
aren't at least 4 free TX descriptors, causing re_start() 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 4 with a macro RL_TX_DESC_THLD
throughout this driver.
- Don't cancel the watchdog timeout as soon as there's at least one
free TX descriptor but instead only if all descriptors have been
handled. It's perfectly normal, especially in the DEVICE_POLLING
case, that re_txeof() is called when only a part of the enqueued
TX descriptors have been handled, causing the watchdog to be
disarmed prematurely.
o In re_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
re_start() to not trying to prepend the mbuf (chain) if re_encap()
has freed it.
- Remove dupe initialization of members of struct rl_dmaload_arg to
values that didn't change since trying to process the fragmented
mbuf chain.
While at it remove an unused member from struct rl_dmaload_arg.
o In re_start() remove a abandoned, banal comment. The corresponding
code was moved to re_attach() some time ago.
With these changes re(4) now survives one day (until stopped) of
hammering out packets here.
Reviewed by: yongari
MFC after: 2 weeks
only support external PHYs (besides not connectable internal ones
which respond at the usual addresses, but which don't hurt if we
let them show up) and don't wedge when isolating PHYs. Actually,
this change special cases limiting PHYs to Am79C97{3,5,8}, for
which this driver doesn't implement swiching between the internal
and external PHYs, yet, and Am79C971, where isolating the external
PHY (at least in case it's a DP83840A) wedges the chip. Together
with sys/dev/mii/acphy.c rev. 1.21 this adds support for the
100baseFX port of AT-2700 series adaptors, which use two AC101,
one for the copper and one for the fibre port (there might be
variants which only use one PHY though).
- Fix a bug in the previous revision that prevented the address of
the used (external) PHY to be actually recorded.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
MFC after: 1 week
- Use printf() and device_printf() instead of log() in ichsmb(4).
- Create the mutex sooner during ichsmb(4) attach.
- Attach the interrupt handler later during ichsmb(4) attach to avoid
races.
- Don't try to set PCIM_CMD_PORTEN in ichsmb(4) attach as the PCI bus
driver does this already.
- Add locking to alpm(4), amdpm(4), amdsmb(4), intsmb(4), nfsmb(4), and
viapm(4).
- Axe ALPM_SMBIO_BASE_ADDR, it's not really safe to write arbitrary values
into BARs, and the PCI bus layer will allocate resources now if needed.
- Merge intpm(4) and intsmb(4) into just intsmb(4). Previously, intpm(4)
attached to the PCI device and created an intsmb(4) child. Now,
intsmb(4) just attaches to PCI directly.
- Change several intsmb functions to take a softc instead of a device_t
to make things simpler.
- Rename confusing AGP_INTEL_I845_MCHCFG to AGP_INTEL_I845_AGPM.
- Move E7205 and E7505 from i8x5 to i8x0 family. It probably worked
because the actual offset is the same.
In fact, all three families have the bit at the exact same place. Only
differences are name and width of the registers, i.e., NBXCFG (0x50, dword),
RDCR (0x51, byte), AGPM (0x51, byte), MCHCFG (0x50, word) depending on
the family of the chipsets.
Because accessing ID registers in rtl81x9 needs 32bit register access
and RL_IDR4/RL_IDR5 registers are reservered registers bzero() is
needed before copying ethernet address.
This fixes unaligned memory accesses panic in sparc64.
PR: kern/106801
MFC after: 3 days
timer in xl_txeof()/xl_txeof_90xB(); xl_poll_locked() unconditionally
invokes xl_txeof()/xl_txeof_90xB(), effectively circumventing that
the watchdog ever fires in the DEVICE_POLLING case as its timer is
constantly reloaded.
- Remove the banal and pedantically outdated comment regarding setting
xl_wdog_timer to 0 in xl_txeof().
Pointed out by: bde
driving xl_watchdog() in order to avoid races accessing if_timer.
While at it relax the watchdog a bit by reloading it in xl_txeof()/
xl_txeof_90xB() if there are still packets enqueued.
- Use bus_get_dma_tag() so xl(4) works on platforms requiring it.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
via the PCN_CSR_MODE register. Along with sys/dev/mii/nsphy.c 1.26
this fixes the case of certain Am79c971-based HP cards and on-board
ones in IBM machines reporting link but not actually passing any
traffic. [1]
- Add support for the internal 10baseT PHY, which actually is used on
at least said HP cards (together with an external DP83840A in a
multiple PHYs configuration). With cards that don't make use of this
internal PHY it'll also show up in FreeBSD but not cause any harm.
This is still missing support for multiple PHYs configuration using
the internal 100baseTX and/or HomePNA PHYs together with external
PHYs or multiple external PHYs though.
- In pcn_ifmedia_upd() call pcn_reset() as otherwise the Am79C971 of
at least said HP cards can wedge when switching from the internal
10baseT PHY to the external PHY. This means that we need to also
initialize and possibly start the chip again in pcn_ifmedia_upd(),
which isn't that bad though as for setting the media port the chip
has to be powered down or stopped anyway and unlike documented
doesn't take effect until the next initialization.
PR: 27995, 25959, 72966 (likely) [1]
MFC after: 2 weeks
by this driver and largely are not even PCI devices in pcn_chipid.
- Use device_printf(9)/if_printf(9) rather than implementing their
functionality with printf(9).
- Sprinkle some const.
the CAM_NEW_TRAN_CODE that has been in the tree for some years now.
This first step consists solely of adding to or correcting
CAM_NEW_TRAN_CODE pieces in the kernel source tree such
that a both a GENERIC (at least on i386) and a LINT build
with CAM_NEW_TRAN_CODE as an option will compile correctly
and run (at least with some the h/w I have).
After a short settle time, the other pieces (making
CAM_NEW_TRAN_CODE the default and updating libcam
and camcontrol) will be brought in.
This will be an incompatible change in that the size of structures
related to XPT_PATH_INQ and XPT_{GET,SET}_TRAN_SETTINGS change
in both size and content. However, basic system operation and
basic system utilities work well enough with this change.
Reviewed by: freebsd-scsi and specific stakeholders
in #ifdef __NO_STRICT_ALIGNMENT rather than #if defined(__i386__) ||
defined(__amd64__). Currently this change is cosmetic only though.
While at it, fix a nearby style(9) bug and remove a no longer used
header.
The key problem was that the aperture size detection using the MSAC bit
doesn't work -- the bit appears to be set even when it shouldn't be. Linux
takes a different approach, testing for a bit of the GMADR (PCIR_BAR(2)) being
set. However, as I don't think that's a safe way to test aperture size, we
just allocate the resource and check its size. This also pointed out that
agp_generic_attach hadn't been allocating our aperture resource, which may
have caused problems in some cases.
Also corrected is a minor copy-and-pasteo in an error case.
PR: kern/103079
Submitted by: mnag
Tested on: i945GM, i915GM
MFC after: 2 weeks
if_ioctl, if_watchdog, etc, or in functions that are used by
these methods only. In all other cases use device_printf().
This also fixes several panics, when if_printf() is called before
softc->ifp was initialized.
Submitted by: Alex Lyashkov <umka sevcity.net>
- Change smbus_callback() to pass a void * rather than caddr_t.
- Change smbus_bread() to pass a pointer to the count and have it be an
in/out parameter. The input is the size of the buffer (same as before),
but on return it will contain the actual amount of data read back from
the bus. Note that this value may be larger than the input value. It
is up to the caller to treat this as an error if desired.
- Change the SMB_BREAD ioctl to write out the updated struct smbcmd which
will contain the actual number of bytes read in the 'count' field. To
preserve the previous ABI, the old ioctl value is mapped to SMB_OLD_BREAD
which doesn't copy the updated smbcmd back out to userland. I doubt anyone
actually used the old BREAD anyway as it was rediculous to do a bulk-read
but not tell the using program how much data was actually read.
- Make the smbus driver and devclass public in the smbus module and
push all the DRIVER_MODULE()'s for attaching the smbus driver to
various foosmb drivers out into the foosmb modules. This makes all
the foosmb logic centralized and allows new foosmb modules to be
self-contained w/o having to hack smbus.c everytime a new smbus driver
is added.
- Add a new SMB_EINVAL error bit and use it in place of EINVAL to return
an error for bad arguments (such as invalid counts for bread and bwrite).
- Map SMB bus error bits to EIO in smbus_error().
- Make the smbus driver call bus_generic_probe() and require child drivers
such as smb(4) to create device_t's via identify routines. Previously,
smbus just created one anonymous device during attach, and if you had
multiple drivers that could attach it was just random chance as to which
driver got to probe for the sole device_t first.
- Add a mutex to the smbus(4) softc and use it in place of dummy splhigh()
to protect the 'owner' field and perform necessary synchronization for
smbus_request_bus() and smbus_release_bus().
- Change the bread() and bwrite() methods of alpm(4), amdpm(4), and
viapm(4) to only perform a single transaction and not try to use a
loop of multiple transactions for a large request. The framing and
commands to use for a large transaction depend on the upper-layer
protocol (such as SSIF for IPMI over SMBus) from what I can tell, and the
smb(4) driver never allowed bulk read/writes of more than 32-bytes
anyway. The other smb drivers only performed single transactions.
- Fix buffer overflows in the bread() methods of ichsmb(4), alpm(4),
amdpm(4), amdsmb(4), intpm(4), and nfsmb(4).
- Use SMB_xxx errors in viapm(4).
- Destroy ichsmb(4)'s mutex after bus_generic_detach() to avoid problems
from child devices making smb upcalls that would use the mutex during
their detach methods.
MFC after: 1 week
Reviewed by: jmg (mostly)
misc. control registers correctly and it is inconsistent with north bridge.
In fact, there are too many broken BIOS implementations out there and we
cannot fix every possible combination but at least it is consistent with
what we advertise with ioctl(2).
Instead the threshould is initialized in device attach. Later the
threshold could be increased in Tx underrun error and the new
threshold should be used in xl_init_locked().
- Change the workaround for the autopad/checksum offload bug so that
instead of lying about the map size, we actually create a properly
padded mbuf and map it as usual. The other trick works, but is ugly.
This approach also gives us a chance to zero the pad space to avoid
possibly leaking data.
- With the PCIe devices, it looks issuing a TX command while there's
already a transmission in progress doesn't have any effect. In other
words, if you send two packets in rapid succession, the second one may
end up sitting in the TX DMA ring until another transmit command is
issued later in the future. Basically, if re_txeof() sees that there
are still descriptors outstanding, it needs to manually resume the
TX DMA channel by issuing another TX command to make sure all
transmissions are flushed out. (The PCI devices seem to keep the
TX channel moving until all descriptors have been consumed. I'm not
sure why the PCIe devices behave differently.)
(You can see this issue if you do the following test: plug an re(4)
interface into another host via crossover cable, and from the other
host do 'ping -c 2 <host with re(4) NIC>' to prime the ARP cache,
then do 'ping -c 1 -s 1473 <host with re(4) NIC>'. You're supposed
to see two packets sent in response, but you may only see one. If
you do 'ping -c 1 -s 1473 <host with re(4) NIC>' again, you'll
see two packets, but one will be the missing fragment from the last
ping, followed by one of the fragments from this ping.)
- Add the PCI ID for the US Robotics 997902 NIC, which is based on
the RTL8169S.
- Add a tsleep() of 1 second in re_detach() after the interrupt handler
is disconnected. This should allow any tasks queued up by the ISR
to drain. Now, I know you're supposed to use taskqueue_drain() for
this, but something about the way taskqueue_drain() works with
taskqueue_fast queues doesn't seem quite right, and I refuse to be
tricked into fixing it.
- Correct the PCI ID for the 8169SC/8110SC in the device list (I added
the macro for it to if_rlreg.h before, but forgot to use it.)
- Remove the extra interrupt spinlock I added previously. After giving it
some more thought, it's not really needed.
- Work around a hardware bug in some versions of the 8169. When sending
very small IP datagrams with checksum offload enabled, a conflict can
occur between the TX autopadding feature and the hardware checksumming
that can corrupt the outbound packet. This is the reason that checksum
offload sometimes breaks NFS: if you're using NFS over UDP, and you're
very unlucky, you might find yourself doing a fragmented NFS write where
the last fragment is smaller than the minimum ethernet frame size (60
bytes). (It's rare, but if you keep NFS running long enough it'll
happen.) If checksum offload is enabled, the chip will have to both
autopad the fragment and calculate its checksum header. This confuses
some revs of the 8169, causing the packet that appears on the wire
to be corrupted. (The IP addresses and the checksum field are mangled.)
This will cause the NFS write to fail. Unfortunately, when NFS retries,
it sends the same write request over and over again, and it keeps
failing, so NFS stays wedged.
(A simple way to provoke the failure is to connect the failing system
to a network with a known good machine and do "ping -s 1473 <badhost>"
from the good system. The ping will fail.)
Someone had previously worked around this using the heavy-handed
approahch of just disabling checksum offload. The correct fix is to
manually pad short frames where the TCP/IP stack has requested
checksum offloading. This allows us to have checksum offload turned
on by default but still let NFS work right.
- Not a bug, but change the ID strings for devices with hardware rev
0x30000000 and 0x38000000 to both be 8168B/8111B. According to RealTek,
they're both the same device, but 0x30000000 is an earlier silicon spin.
cards: the chips are all marked "RTL8111B", but they put stickers on the
back that say "RTL8168B/8111B". The manual says there's only one HWREV code
for both the 8111B and 8168B devices, which is 0x30000000, but the cards
they sent me actually report HWREV of 0x38000000. Deciding to trust the
hardware in front of me rather than a possibly incorrect manual (it wouldn't
be the first time the HWREVs were incorrectly documented), I changed the
8168 revision code. It turns out this was a mistake though: 0x30000000
really is a valid for the 8168.
There are two possible reasons for there to be two different HWREVs:
1) 0x30000000 is used only for the 8168B and 0x38000000 is only for
the 8111B.
2) There were 8111/8168 rev A devices which both used code 0x30000000,
and the 8111B/8168B both use 0x38000000.
The product list on the RealTek website doesn't mention the existence of
any 8168/8111 rev A chips being in production though, and I've never seen
one, so until I get clarification from RealTek, I'm going to assume that
0x30000000 is just for the 8168B and 0x38000000 is for the 8111B only.
So, the HWREV code for the 8168 has been put back to 0x30000000,
a new 8111 HWREV code has been added, and there are now separate
entries for recognizing both devices in the device list. This will
allow all devices to work, though if it turns out I'm wrong I may
need to change the ID strings
latter is a PCIe 10/100 chip.
Finally fix the EEPROM reading code so that we can access the EEPROMs on all
devices. In order to access the EEPROM, we must select 'EEPROM programming'
mode, and then set the EEPROM chip select bit. Previously, we were setting
both bits simultaneously, which doesn't work: they must be set in the
right sequence.
Always obtain the station address from the EEPROM, now that EEPROM
reading works correctly.
Make the TX interrupt moderation code based on the internal timer
optional and turned off by default.
Make the re_diag() routine conditional and off by default. When it is
on, only use it for the original 8169, which was the only device that
that really needed it.
Modify interrupt handling to use a fast interrupt handler and fast
taskqeueue.
Correct the rgephy driver so that it only applies the DSP fixup for
PHY revs 0 and 1. Later chips are fixed and don't need the fixup.
Make the rgephy driver advertise both 1000_FD and 1000_HD bits in
autoneg mode. A couple of the devices don't autoneg correctly unless
configured this way.