Commit Graph

59 Commits

Author SHA1 Message Date
Marius Strobl
2a79fd39b4 o In preparation for basing a new driver on this one:
- ANSIfy
  - try to bring closer to style(9)
  - remove banal comments.
o Add my copyright for having done lots of fixes and improvements.
2007-12-30 01:32:03 +00:00
Pyun YongHyeon
e489b71b07 Fix a NULL pointer dereference in Tx checksum calculation.
Pointed out by: marius
2007-10-13 00:24:09 +00:00
Marius Strobl
1ed3fed743 o Revert the part of if_gem.c rev. 1.35 which added a call to gem_stop()
to gem_attach() as the former access softc members not yet initialized
  at that time and gem_reset() actually is enough to stop the chip. [1]
o Revise the use of gem_bitwait(); add bus_barrier() calls before calling
  gem_bitwait() to ensure the respective bit has been written before we
  starting polling on it and poll for the right bits to change, f.e. even
  though we only reset RX we have to actually wait for both GEM_RESET_RX
  and GEM_RESET_TX to clear. Add some additional gem_bitwait() calls in
  places we've been missing them according to the GEM documentation.
  Along with this some excessive DELAYs, which probably only were added
  because of bugs in gem_bitwait() and its use in the first place, as
  well as as have of an gem_bitwait() reimplementation in gem_reset_tx()
  were removed.
o Add gem_reset_rxdma() and use it to deal with GEM_MAC_RX_OVERFLOW errors
  more gracefully as unlike gem_init_locked() it resets the RX DMA engine
  only, causing no link loss and the FIFOs not to be cleared. Also use it
  deal with GEM_INTR_RX_TAG_ERR errors, with previously were unhandled.
  This was based on information obtained from the Linux GEM and OpenSolaris
  ERI drivers.
o Turn on workarounds for silicon bugs in the Apple GMAC variants.
  This was based on information obtained from the Darwin GMAC and Linux GEM
  drivers.
o Turn on "infinite" (i.e. maximum 31 * 64 bytes in length) DMA bursts.
  This greatly improves especially RX performance.
o Optimize the RX path, this consists of:
  - kicking the receiver as soon as we've a spare descriptor in gem_rint()
    again instead of just once after all the ready ones have been handled;
  - kicking the receiver the right way, i.e. as outlined in the GEM
    documentation in batches of 4 and by pointing it to the descriptor
    after the last valid one;
  - calling gem_rint() before gem_tint() in gem_intr() as gem_tint() may
    take quite a while;
  - doubling the size of the RX ring to 256 descriptors.
  Overall the RX performance of a GEM in a 1GHz Sun Fire V210 was improved
  from ~100Mbit/s to ~850Mbit/s.
o In gem_add_rxbuf() don't assign the newly allocated mbuf to rxs_mbuf
  before calling bus_dmamap_load_mbuf_sg(), if bus_dmamap_load_mbuf_sg()
  fails we'll free the newly allocated mbuf, unable to recycle the
  previous one but a NULL pointer dereference instead.
o In gem_init_locked() honor the return value of gem_meminit().
o Simplify gem_ringsize() and dont' return garbage in the default case.
  Based on OpenBSD.
o Don't turn on MAC control, MIF and PCS interrupts unless GEM_DEBUG is
  defined as we don't need/use these interrupts for operation.
o In gem_start_locked() sync the DMA maps of the descriptor rings before
  every kick of the transmitter and not just once after enqueuing all
  packets as the NIC might instantly start transmitting after we kicked
  it the first time.
o Keep state of the link state and use it to enable or disable the MAC
  in gem_mii_statchg() accordingly as well as to return early from
  gem_start_locked() in case the link is down. [3]
o Initialize the maximum frame size to a sane value.
o In gem_mii_statchg() enable carrier extension if appropriate.
o Increment if_ierrors in case of an GEM_MAC_RX_OVERFLOW error and in
  gem_eint(). [3]
o Handle IFF_ALLMULTI correctly; don't set it if we've turned promiscuous
  group mode on and don't clear the flag if we've disabled promiscuous
  group mode (these were mostly NOPs though). [2]
o Let gem_eint() also report GEM_INTR_PERR errors.
o Move setting sc_variant from gem_pci_probe() to gem_pci_attach() as
  device probe methods are not supposed to touch the softc.
o Collapse sc_inited and sc_pci into bits for sc_flags.
o Add CTASSERTs ensuring that GEM_NRXDESC and GEM_NTXDESC are set to
  legal values.
o Correctly set up for 802.3x flow control, though #ifdef out the code
  that actually enables it as this needs more testing and mainly a proper
  framework to support it.
o Correct and add some conversions from hard-coded functions names to
  __func__ which were borked or forgotten in if_gem.c rev. 1.42.
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o In gem_pci_attach() in case attaching fails release the resources in
  the opposite order they were allocated.
o Make gem_reset() static to if_gem.c as it's not needed outside that
  module.
o Remove the GEM_GIGABIT flag and the associated code; GEM_GIGABIT was
  never set and the associated code was in the wrong place.
o Remove sc_mif_config; it was only used to cache the contents of the
  respective register within gem_attach().
o Remove the #ifdef'ed out NetBSD/OpenBSD code for establishing a suspend
  hook as it will never be used on FreeBSD.
o Also probe Apple Intrepid 2 GMAC and Apple Shasta GMAC, add support for
  Apple K2 GMAC. Based on OpenBSD.
o Add support for Sun GBE/P cards, or in other words actually add support
  for cards based on GEM to gem(4). This mainly consists of adding support
  for the TBI of these chips. Along with this the PHY selection code was
  rewritten to hardcode the PHY number for certain configurations as for
  example the PHY of the on-board ERI of Blade 1000 shows up twice causing
  no link as the second incarnation is isolated.
  These changes were ported from OpenBSD with some additional improvements
  and modulo some bugs.
o Add code to if_gem_pci.c allowing to read the MAC-address from the VPD on
  systems without Open Firmware.
  This is an improved version of my variant of the respective code in
  if_hme_pci.c
o Now that gem(4) is MI enable it for all archs.

Pointed out by:	yongari [1]
Suggested by:	rwatson [2], yongari [3]
Tested on:	i386 (GEM), powerpc (GMACs by marcel and yongari),
		sparc64 (ERI and GEM)
Reviewed by:	yongari
Approved by:	re (kensmith)
2007-09-26 21:14:18 +00:00
Marius Strobl
e87137e133 - In gem_bitwait() check that the bit clears/was set in the content
of the register rather than in the offset describing the register.
- In gem_reset_rx() let gem_bitwait() check for the Rx reset bit
  rather than the Tx reset bit to clear.

Obtained from:	OpenBSD (same/similar bugs being fixed)
2007-06-16 23:27:59 +00:00
Pyun YongHyeon
12fb0330d8 o Implemented Rx/Tx checksum offload. The simple checksum logic in
GEMs is unable to discriminate UDP from TCP packets such that
  it can generate 0x0000 checksum value for the UDP datagram. So the
  UDP checksum offload was disabled by default. You can enable it
  by setting link0 flag with ifconfig(8).
o bus_dma(9) clean up. It now correctly set number of required DMA
  segments/size and removed incorrect use of BUS_DMA_ALLOCNOW flag
  in static allocations done via bus_dmamem_alloc(9).
o Implemented ALTQ(9) support.
o Implemented Tx side bus_dmamap_load_mbuf_sg(9) which can remove
  several book keeping chores orginated from call-back mechanism.
  Therefore gem_txdma_callback() was removed and its functionality
  was reimplemented in gem_load_txmbuf().
o Don't set GEM_TD_START_OF_PACKET flag until all remaining mbuf
  chains are set. I think it was a long standing bug and it caused
  fluctuating interrupts/CPU usage patterns while netperf test
  is in progress. Previously it seems that we race with the device.
  Because I don't have a documentation for GEM I'm not sure this is
  correct but almost all other documentations I have stated this
  implications on setting SOP mark in descriptor ring(e.g. hme(4)).
o Borrowed gem_defrag() from ath(4) which is supposed to be much
  faster than m_defrag(9) since it's not need to defrag all
  mbuf chains.
o gem_load_txmbuf() was changed to allow passed mbuf chains to free.
  Caller of gem_load_txmbuf() correctly handles freed mbuf chains.
o In gem_start_locked(), added checks for availability of Tx
  descriptors before trying to load DMA maps which could save CPU
  cycles when number of available descriptors are low. Also, simplyfy
  IFF_DRV_OACTIVE detection logic.
o Removed hard-coded function names in CTR macros and replaced it
  with __func__.
o Moved statistics counter register access to gem_tick() to reduce
  number of PCI bus accesses. There is no reason to update statistics
  counters in interrupt handler.
o Removed unnecessary call of gem_start_locked() in gem_ioctl().

Reviewed by:	grehan (initial version), marius (with improvements and suggestions)
Tested by:	grehan (ppc), marius(sparc64)
2007-06-04 06:01:04 +00:00
Poul-Henning Kamp
e1bb13cd30 Since if_gem is being touted as one of our more architecturally
correct network drivers with respect to busmaster DMA, go over it
with at duster to make other aspects of it a role model:

Eliminate the pci specific softc, it serves no rational purpose.

Use convenience resource allocation/deallocation functions to save
code and errorhandling.

Switch from bus_space_{read|write}_%u() to bus_{read|write}_%u()
functions and forget about tags and handles, the resource will know
about those, should they be needed.  This also eliminates a number
of inconsistently named local variables.
2007-05-04 19:15:28 +00:00
Paolo Pisati
ef544f6312 o break newbus api: add a new argument of type driver_filter_t to
bus_setup_intr()

o add an int return code to all fast handlers

o retire INTR_FAST/IH_FAST

For more info: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=465712+0+current/freebsd-current

Reviewed by: many
Approved by: re@
2007-02-23 12:19:07 +00:00
Marius Strobl
8cb37876d6 - Use the gem_tick() callout instead of if_slowtimo() for driving
gem_watchdog() in order to avoid races accessing if_timer.
  While at it relax the watchdog a bit by reloading it in gem_tint()
  if there are still packets enqueued.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
- Fix inconsistencies in prototypes.
2006-12-06 02:04:25 +00:00
John-Mark Gurney
378f231e7d add a newbus method for obtaining the bus's bus_dma_tag_t... This is
required by arches like sparc64 (not yet implemented) and sun4v where there
are seperate IOMMU's for each PCI bus...  For all other arches, it will
end up returning NULL, which makes it a no-op...

Convert a few drivers (the ones we've been working w/ on sun4v) to the
new convection...  Eventually all drivers will need to replace the parent
tag of NULL, w/ bus_get_dma_tag(dev), though dev is usually different for
each driver, and will require hand inspection...

Reviewed by:	scottl (earlier version)
2006-09-03 00:27:42 +00:00
Sam Leffler
ff046a6c6b add missed calls to bpf_peers_present 2006-06-02 23:14:40 +00:00
Ruslan Ermilov
342ed5d948 Fix -Wundef warnings found when compiling i386 LINT, GENERIC and
custom kernels.
2005-12-05 11:58:35 +00:00
Ruslan Ermilov
4a0d6638b3 - Store pointer to the link-level address right in "struct ifnet"
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.
2005-11-11 16:04:59 +00:00
Marius Strobl
1f317bf968 - In gem_ioctl() move the call to ether_ioctl() to the default case of
the switch statement in order to make this driver more like other
  Ethernet NIC drivers.
- In gem_attach() call gem_stop() in addition to gem_reset() to make
  sure the chip actually is stopped and not just reset.
- In gem_stop() also stop the gem_rint_timeout() callout in case the
  driver is compiled with GEM_RINT_TIMEOUT defined.

Merge some locking improvements from hme(4):
- Use callout_init_mtx() to close races between gem_stop() and gem_tick()
  as weel as gem_stop() and gem_rint() in case the driver is compiled
  with GEM_RINT_TIMEOUT defined.
- Use the driver lock instead of Giant in a bus dma callback.
- Lock the driver lock around mii operations.
- Cleanup locking in gem_ioctl().
- Remove redundant assertions that the driver lock is not held in
  gem_attach() and gem_detach() since mtx_lock() will assert that
  already since the driver lock is not recursive.
- Add callout_drain()'s to gem_detach() after calling gem_stop() to make
  sure that if softclock is running on another CPU and is blocked on our
  driver lock, we will wait until it has acquired the lock, seen that it
  was cancelled, dropped the lock, and awakened us so that we can safely
  destroy the mutex.
2005-09-18 13:23:19 +00:00
Marius Strobl
00d12766ef - Allow for VLAN-sized frames and set IFCAP_VLAN_MTU.
- On resume all registers have to be initialized again like after
  power-on so reset sc_inited in gem_suspend() in order get all of
  the registers set next time gem_init_regs() is called.
- On at least some ERI and GEM revisions GEM_MAC_RX_OVERFLOW happen
  often due to a silicon bug and re-initializing is all we can do
  about these errors so make handling them non-verbose.
- Remove a superfluous memset(3) call in gem_meminit(), all elements
  are initialized to 0 anyway.

MFC after:	1 week
2005-08-28 15:07:30 +00:00
Robert Watson
13f4c340ae Propagate rename of IFF_OACTIVE and IFF_RUNNING to IFF_DRV_OACTIVE and
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
2005-08-09 10:20:02 +00:00
Robert Watson
13b203d0d7 Modify device drivers supporting multicast addresses to lock if_addr_mtx
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
2005-08-03 00:18:35 +00:00
Marius Strobl
8cfaff7d0b Remove NOP spl*() calls and add locking (making gem(4) MPSAFE).
Based on:	hme(4)
Reviewed by:	yongari
Tested on:	powerpc(grehan), sparc64
2005-07-24 18:45:15 +00:00
Marius Strobl
c3d5598aa8 - Wrap the handler and associated code for collecting completed RX
descriptors that are still marked owned in #ifdef GEM_RINT_TIMEOUT
  instead of #if 0 for convenience.
- Remove stale code and comment about relying on the preset XIF config.
- In case of a watchdog timeout call the init function instead of just
  the start function so the chip is properly reset.

Merge from hme(4):
- Convert to use bus_dmamap_load_mbuf_sg() for loading RX buffers.
- Protect from a duplicate mbuf free panic in case the DMA engine hangs.

Reviewed by:	yongari
Tested on:	powerpc(grehan), sparc64
MFC after:	1 week
2005-07-24 18:12:31 +00:00
Brooks Davis
25bd46d0e7 Stop the interface before detaching and freeing it, rather than after.
Reported by:	marius
2005-06-12 15:33:45 +00:00
Brooks Davis
fc74a9f93a Stop embedding struct ifnet at the top of driver softcs. Instead the
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
2005-06-10 16:49:24 +00:00
Warner Losh
538565c4a5 Use BUS_PROBE_DEFAULT for pci probe return value 2005-03-05 18:30:12 +00:00
Warner Losh
098ca2bda9 Start each of the license/copyright comments with /*-, minor shuffle of lines 2005-01-06 01:43:34 +00:00
Robert Watson
268f132afc Since if_gem doesn't contain locking or run with INTR_MPSAFE, mark
the interface as IFF_NEEDSGIANT so if_start is run holding Giant.
2004-08-13 23:11:24 +00:00
Marius Strobl
c240bd8cf8 - Remove a variable no longer used after the conversion to ether_crc32_le().
- While here, save on another one no longer really necessary after the
  conversion.
2004-06-10 00:04:16 +00:00
Christian Weisgerber
0e939c0cea Replace handrolled CRC calculation with ether_crc32_[lb]e(). 2004-06-09 14:34:04 +00:00
Poul-Henning Kamp
186f2b9e04 Add missing <sys/module.h> includes currently relying on nested include
in <sys/kernel.h>
2004-06-03 06:10:02 +00:00
Maxime Henrion
866a788cc2 We don't need to initialize if_output, ether_ifattach() does it
for us.
2004-05-23 16:11:53 +00:00
Thomas Moestl
3a5aee5adc Clean up two printf()s that were on a line by themselves unintendedly
after the ethernet address printing was moved to common code.
2004-04-23 19:43:35 +00:00
Matthew N. Dodd
322b1dc4b0 Let ether_ifattach() announce our MAC address.
Submitted by:	Marius Strobl <marius@alchemy.franken.de>
2004-03-20 20:12:13 +00:00
Nate Lawson
5f96beb9e0 Convert callers to the new bus_alloc_resource_any(9) API.
Submitted by:	Mark Santcroos <marks@ripe.net>
Reviewed by:	imp, dfr, bde
2004-03-17 17:50:55 +00:00
Peter Grehan
aa1985722c Add new Apple GEM PCI id. 2004-02-02 01:11:39 +00:00
David E. O'Brien
4609c9a528 Properly initialize all members of the sentinel entry. 2003-12-26 05:36:08 +00:00
Brooks Davis
9bf40ede4a Replace the if_name and if_unit members of struct ifnet with new members
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)
2003-10-31 18:32:15 +00:00
Marcel Moolenaar
11a91bffe5 Preparatory commit to allow prototypes in ofw_machdep.h to contain
both newbus types and OFW types. This involves either including
<machine/bus.h> or <dev/ofw/openfirm.h>.

Reviewed by: jake, jmg, tmm
2003-09-02 20:24:42 +00:00
David E. O'Brien
aad970f1fe Use __FBSDID().
Also some minor style cleanups.
2003-08-24 17:55:58 +00:00
Warner Losh
681f7d03c4 s=gem/foo=dev/gem/foo= 2003-08-23 06:30:21 +00:00
Scott Long
f6b1c44d1f Mega busdma API commit.
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
2003-07-01 15:52:06 +00:00
Thomas Moestl
5905e65b56 Some gem and hme hardware bogusly has the intpin register hardwired to
0; detect this case and correct it. While being there, clean up nearby
comments.
2003-07-01 14:11:04 +00:00
Thomas Moestl
18100346d1 Miscellaneous fixes:
- Fix compilation without GEM_DEBUG.
- Do not #define GEM_DEBUG by default; it adds overhead (due to bzero()ing
  RX space) and is not needed any more, since the driver is quite stable
  now.
- Fix watchdog timeouts when failing to load TX packets.
- Do not forcibly limit the number of descriptors used for a packet to
  GEM_NTXSEGS, by passing this number to bus_dma_tag_create(). There is
  no requirement for a limit any lower than the total number of
  available descriptors, and the present limit caused network problems
  due to mbuf chains requiring more descriptors.
  GEM_NTXSEGS is still used to estimate the interrupt window size, for
  which we just need an estimate.

Approved by:	re (rwatson)
2003-05-15 16:57:55 +00:00
Matthew N. Dodd
533294b956 - Don't call pci_enable_io() in drivers (unless needed for resume).
- Don't test memory/port status and emit an error message; the PCI
  bus code will do this now.
2003-04-16 03:16:57 +00:00
Matthew N. Dodd
f246e4a17f - Express hard dependencies on bus (pci, isa, pccard) and
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.)
2003-04-15 06:37:30 +00:00
Warner Losh
a163d034fa Back out M_* changes, per decision of the TRB.
Approved by: trb
2003-02-19 05:47:46 +00:00
Thomas Moestl
3437dbef6d Free resources when failing to set up the interrupt. 2003-01-21 17:28:36 +00:00
Thomas Moestl
b2d59f4234 bus_dmamap_sync() overhaul:
- Remove NetBSD-style or-ed together BUS_DMASYNC operations, in some
  cases relaxing the (intended) syncing operation a bit.
- Stop pretending that that we can sync part of a dmamap: replace the
  GEM_CDTXSYNC and GEM_CDRXSYNC macros with GEM_CDSYNC to sync the
  complete control map, and combine syncs wherever possible to avoid
  the overhead.
- Sync all maps before unloading them.
- Remove a few syncs which should be unnecessary.
2003-01-21 17:17:01 +00:00
Alfred Perlstein
44956c9863 Remove M_TRYWAIT/M_WAITOK/M_WAIT. Callers should use 0.
Merge M_NOWAIT/M_DONTWAIT into a single flag M_NOWAIT.
2003-01-21 08:56:16 +00:00
Thomas Moestl
cbbdf2367e Add detach, shutdown, suspend and resume methods. The latter two are
not really tested, but are derived from the original NetBSD version.
2003-01-08 20:12:45 +00:00
Thomas Moestl
305f2c0632 - Convert to use bus_dmamap_load_mbuf().
- remove DPRINTF(), there is a CTR*() for any of them, and KTR is
  far more useful to debug this driver.
- some cleanups; remove some unused code and definitions.
2003-01-06 22:09:01 +00:00
Maxime Henrion
6c9ecf447f Catch up with sam's changes to network interfaces. 2002-11-15 14:36:33 +00:00
Sam Leffler
673d91916d network interface driver changes:
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
2002-11-14 23:54:55 +00:00
Thomas Moestl
08e0fdeb39 Call bpf_mtap() on outgoing packets. 2002-10-26 12:32:07 +00:00