o Header file cleanup.
o bus_dma(9) conversion.
- Removed all consumers of vtophys(9) and converted to use
bus_dma(9).
- Typhoon2 functional specification says the controller supports
64bit DMA addressing. However all Typhoon controllers are known
to lack of DAC support so 64bit DMA support was disabled.
- The hardware can't handle more 16 fragmented Tx DMA segments so
teach txp(4) to collapse these segments to be less than 16.
- Added Rx buffer alignment requirements(4 bytes alignment) and
implemented fixup code to align receive frame. Previously
txp(4) always copied Rx frame to align it on 2 byte boundary
but its copy overhead is much higher than unaligned access on
i386/amd64. Alignment fixup code is now applied only for
strict-alignment architectures. With this change i386 and
amd64 will get instant Rx performance boost. Typhoon2 datasheet
mentions a command that pads arbitrary bytes in Rx buffer but
that command does not work.
- Nuked pointer trick in descriptor ring. This does not work on
sparc64 and replaced it with bcopy. Alternatively txp(4) can
embed a 32 bits index value into the descriptor and compute
real buffer address but it may make code complicated.
- Added endianness support code in various Tx/Rx/command/response
descriptor access. With this change txp(4) should work on all
architectures.
o Added comments for known firmware bugs(Tx checksum offloading,
TSO, VLAN stripping and Rx buffer padding control).
o Prefer faster memory space register access to I/O space access.
Added fall-back mechanism to use alternative I/O space access.
The hardware supports both memory and I/O mapped access. Users
can still force to use old I/O space access by setting
hw.txp.prefer_iomap tunable to 1 in /boot/loader.conf.
o Added experimental suspend/resume methods.
o Nuke error prone Rx buffer handling code and implemented local
buffer management with TAILQ. Be definition the controller can't
pass the last received frame to host if no Rx free buffers are
available to use as head and tail pointer of Rx descriptor ring
can't have the same value. In that case the Rx buffer pointer in
Rx buffer ring still holds a valid buffer and txp_rxbuf_reclaim()
can't fill Rx buffers as the first buffer is still valid. Instead
of relying on the value of Rx buffer ring, introduce local buffer
management code to handle empty buffer situation. This should fix
a long standing bug which completely hangs the controller under
high network load. I could easily trigger the issue by sending 64
bytes UDP frames with netperf. I have no idea how this bugs was
not fixed for a long time.
o Converted ithread interrupt handler to filter based one.
o Rearranged txp_detach routine such that it's now used for general
clean-up routine.
o Show sleep image version on device attach time. This will help
to know what action should be taken depending on sleep image
version. The version information in datasheet was wrong for newer
NV images so I followed Linux which seems to correctly extract
version numbers from response descriptors.
o Firmware image is no longer downloaded in device attach time. Now
it is reloaded whenever if_init is invoked. This is to ensure
correct operation of hardware when something goes wrong.
Previously the controller always run without regard to running
state of firmware. This change will add additional controller
initialization time but it give more robust operation as txp(4)
always start off from a known state. The controller is put into
sleep state until administrator explicitly up the interface.
o As firmware is loaded in if_init handler, it's now possible to
implement real watchdog timeout handler. When watchdog timer is
expired, full-reset the controller and initialize the hardware
again as most other drivers do. While I'm here use our own timer
for watchdog instead of using if_watchdog/if_timer interface.
o Instead of masking specific interrupts with TXP_IMR register,
program TXP_IER register with the interrupts to be raised and
use TXP_IMR to toggle interrupt generation.
o Implemented txp_wait() to wait a specific state of a controller.
o Separate boot related code from txp_download_fw() and name it
txp_boot() to handle boot process.
o Added bus_barrier(9) to host to ARM communication.
o Added endianness to all typhoon command processing. The ARM93C
always expects little-endian format of command/data.
o Removed __STRICT_ALIGNMENT which is not valid on FreeBSD.
__NO_STRICT_ALIGNMENT is provided for that purpose on FreeBSD.
Previously __STRICT_ALIGNMENT was unconditionally defined for
all architectures.
o Rewrote SIOCSIFCAP ioctl handler such that each capability can be
controlled by ifconfig(8). Note, disabling VLAN hardware tagging
has no effect due to the bug of firmware.
o Don't send TXP_CMD_CLEAR_STATISTICS to clear MAC statistics in
txp_tick(). The command is not atomic. Instead, just read the
statistics and reflect saved statistics to the statistics.
dev.txp.%d.stats sysctl node provides detailed MAC statistics.
This also reduces a lot of waste of CPU cycles as processing a
command ring takes a very long time on ARM93C. Note, Rx
multicast and broadcast statistics does not seem to right. It
might be another bug of firmware.
o Implemented link state change handling in txp_tick(). Now sending
packets is allowed only after establishing a valid link. Also
invoke link state change notification whenever its state is
changed so pseudo drivers like lagg(4) that relies on link state
can work with failover or link aggregation without hacks.
if_baudrate is updated to resolved speed so SNMP agents can get
correct bandwidth parameters.
o Overhauled Tx routine such that it now honors number of allowable
DMA segments and checks for 4 free descriptors before trying to
send a frame. A frame may require 4 descriptors(1 frame
descriptor, 1 or more frame descriptors, 1 TSO option descriptor,
one free descriptor to prevent descriptor wrap-around) at least
so it's necessary to check available free descriptors prior to
setting up DMA operation.
o Added a sysctl variable dev.txp.%d.process_limit to control
how many received frames should be served in Rx handler. Valid
ranges are 16 to 128(default 64) in unit of frames.
o Added ALTQ(4) support.
o Added missing IFCAP_VLAN_HWCSUM as txp(4) can offload checksum
calculation as well as VLAN tag insertion/stripping.
o Fixed media header length for VLAN.
o Don't set if_mtu in device attach, it's already set in
ether_ifattach().
o Enabled MWI.
o Fixed module unload panic when bpf listeners are active.
o Rearranged ethernet address programming logic such that it works
on strict-alignment architectures.
o Removed unused member variables in softc.
o Added support for WOL.
o Removed now unused TXP_PCI_LOMEM/TXP_PCI_LOIO.
o Added wakeup command TXP_BOOTCMD_WAKEUP definition.
o Added a new firmware version query command, TXP_CMD_READ_VERSION.
o Removed volatile keyword in softc as bus_dmamap_sync(9) should
take care of this.
o Removed embedded union trick of a structure used to to access
a pointer on LP64 systems.
o Added a few TSO related definitions for struct txp_tcpseg_desc.
However TSO is not used at all due to the limitation of hardware.
o Redefined PKT_MAX_PKTLEN to theoretical maximum size of a frame.
o Switched from bus_space_{read|write}_4 to bus_{read|write}_4.
o Added a new macro TXP_DESC_INC to compute next descriptor index.
Tested by: don.nasco <> gmail dot com
required to make 3CR990 familiy controllers run on NV flash
firmware version 03.001.008.
The latest firmware added HMAC digest information so teach txp(4)
to pass them to sleep image before downloading is started.
While I'm here restore previous IMR/IER register if firmware
downloading have failed.
PR: kern/89876, kern/132047
priorities of the technologies supported by 802.3 Selector Field
value.
1000BASE-T full duplex
1000BASE-T
100BASE-T2 full duplex
100BASE-TX full duplex
100BASE-T2
100BASE-T4
100BASE-TX
10BASE-T full duplex
10BAST-T
However PHY drivers didn't honor the order such that 100BASE-T4 had
higher priority than 100BASE-TX full duplex. Fix that long standing
bugs such that have PHY drivers choose the highest common denominator
ability.
Fix a bug in dcphy which inadvertently aceepts 100BASE-T4.
PR: 92599
If these drivers are setting M_VLANTAG because they are stripping the
layer 2 802.1Q headers, then they need to be re-inserting them so any
bpf(4) peers can properly decode them.
It should be noted that this is compiled tested only.
MFC after: 3 weeks
m_pkthdr.ether_vlan. The presence of the M_VLANTAG flag on the mbuf
signifies the presence and validity of its content.
Drivers that support hardware VLAN tag stripping fill in the received
VLAN tag (containing both vlan and priority information) into the
ether_vtag mbuf packet header field:
m->m_pkthdr.ether_vtag = vlan_id; /* ntohs()? */
m->m_flags |= M_VLANTAG;
to mark the packet m with the specified VLAN tag.
On output the driver should check the mbuf for the M_VLANTAG flag to
see if a VLAN tag is present and valid:
if (m->m_flags & M_VLANTAG) {
... = m->m_pkthdr.ether_vtag; /* htons()? */
... pass tag to hardware ...
}
VLAN tags are stored in host byte order. Byte swapping may be necessary.
(Note: This driver conversion was mechanic and did not add or remove any
byte swapping in the drivers.)
Remove zone_mtag_vlan UMA zone and MTAG_VLAN definition. No more tag
memory allocation have to be done.
Reviewed by: thompsa, yar
Sponsored by: TCP/IP Optimization Fundraise 2005
case if memory allocation failed.
- Remove fourth argument from VLAN_INPUT_TAG(), that was used
incorrectly in almost all drivers. Indicate failure with
mbuf value of NULL.
In collaboration with: yongari, ru, sam
rather than in ifindex_table[]; all (except one) accesses are
through ifp anyway. IF_LLADDR() works faster, and all (except
one) ifaddr_byindex() users were converted to use ifp->if_addr.
- Stop storing a (pointer to) Ethernet address in "struct arpcom",
and drop the IFP2ENADDR() macro; all users have been converted
to use IF_LLADDR() instead.
the ifp, so you can't call it before doing if_alloc(). Also, there's
really no need to call it here anyway: the code I originally ported from
OpenBSD incorrectly set the station address only once at device attach
time, instead of setting in txp_init(). This meant you couldn't change
the address with ifconfig txp0 ether xx:xx:xx:xx:xx:xx. I added the
call to txp_set_filter() in txp_init() to correct this, but forgot to
remove the call from txp_attach(). Until now, it never mattered.
With this fix, the txp driver tests good:
txp0: <3Com 3cR990-TX-97 Etherlink with 3XP Processor> port 0xb800-0xb87f mem 0xe6800000-0xe683ffff irq 12 at device 10.0 on pci0
txp0: Ethernet address: 00:01:03:d4:91:4f
even initialized it, but it never used it.
- Use callout_*() to manage the callout.
- Use m_devget() to copy data out of the rx buffers rather than doing it
all by hand.
- Use m_getcl() to allocate mbuf clusters rather than doing it all by hand.
- Don't free the software descriptor for a rx ring entry if we can't
allocate an mbuf cluster for it. We left a dangling pointer and never
reallocated the entry anyway. OpenBSD's code (from which this was
derived) has the same bug.
Tested by: NO ONE (despite repeated requests)
Reviewed by: wpaul (5)
could get an interrupt after we free the ifp, and the interrupt
handler depended on the ifp being still alive, this could, in theory,
cause a crash. Eliminate this possibility by moving the if_free to
after the bus_teardown_intr() call.
- Set errno to ENXIO instead of 0 in several attach failure cases.
- Setup the interrupt handler at the very end of txp_attach() after
ether_ifattach().
- Various whitespace fixes in function prototypes.
IFF_DRV_RUNNING, as well as the move from ifnet.if_flags to
ifnet.if_drv_flags. Device drivers are now responsible for
synchronizing access to these flags, as they are in if_drv_flags. This
helps prevent races between the network stack and device driver in
maintaining the interface flags field.
Many __FreeBSD__ and __FreeBSD_version checks maintained and continued;
some less so.
Reviewed by: pjd, bz
MFC after: 7 days
over iteration of their multicast address lists when synchronizing the
hardware address filter with the network stack-maintained list.
Problem reported by: Ed Maste (emaste at phaedrus dot sandvine dot ca>
MFC after: 1 week
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
the interface as IFF_NEEDSGIANT so if_start is run holding Giant.
Note: mutexes are initialized in the softc for this driver, but the
locking appears inadequate to allow Giant-free operation.
if_xname, if_dname, and if_dunit. if_xname is the name of the interface
and if_dname/unit are the driver name and instance.
This change paves the way for interface renaming and enhanced pseudo
device creation and configuration symantics.
Approved By: re (in principle)
Reviewed By: njl, imp
Tested On: i386, amd64, sparc64
Obtained From: NetBSD (if_xname)
However, they are presently necessary due to bigger bogusness in the
pci bus layer not doing the right thing on suspend/resume or on
initial device probe. This is exactly the sort of thing that the
BURN_BRIDGES option was invented for. Mark all of them as
BURN_BRIDGES. As soon as I have the powerstate stuff properly
integrated into the pci bus code, I intend to remove all these
workarounds.
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.)
o don't strip the Ethernet header from inbound packets; pass packets
up the stack intact (required significant changes to some drivers)
o reference common definitions in net/ethernet.h (e.g. ETHER_ALIGN)
o track ether_ifattach/ether_ifdetach API changes
o track bpf changes (use BPF_TAP and BPF_MTAP)
o track vlan changes (ifnet capabilities, revised processing scheme, etc.)
o use if_input to pass packets "up"
o call ether_ioctl for default handling of ioctls
Reviewed by: many
Approved by: re
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