Commit Graph

142 Commits

Author SHA1 Message Date
Nimrod Andy
28b5f058cf net: fec: ptp: fix convergence issue to support LinuxPTP stack
iMX6SX IEEE 1588 module has one hw issue in capturing the ATVR register.
The current SW flow is:
		ENET0->ATCR |= ENET_ATCR_CAPTURE_MASK;
		ts_counter_ns = ENET0->ATVR;
The ATVR value is not expected value that cause LinuxPTP stack cannot be convergent.

ENET Block Guide/ Chapter for the iMX6SX (PELE) address the issue:
After set ENET_ATCR[Capture], there need some time cycles before the counter
value is capture in the register clock domain. The wait-time-cycles is at least
6 clock cycles of the slower clock between the register clock and the 1588 clock.
So need something like:
		ENET0->ATCR |= ENET_ATCR_CAPTURE_MASK;
		wait();
		ts_counter_ns = ENET0->ATVR;

For iMX6SX, the 1588 ts_clk is fixed to 25Mhz, register clock is 66Mhz, so the
wait-time-cycles must be greater than 240ns (40ns * 6). The patch add 1us delay
before cpu read ATVR register.

Changes V2:
Modify the commit/comments log to describe the issue clearly.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-15 16:40:11 -04:00
Luwei Zhou
278d240478 net: fec: ptp: Enable PPS output based on ptp clock
FEC ptp timer has 4 channel compare/trigger function. It can be used to
enable pps output.
The pulse would be ouput high exactly on N second. The pulse ouput high
on compare event mode is used to produce pulse per second.  The pulse
width would be one cycle based on ptp timer clock source.Since 31-bit
ptp hardware timer is used, the timer will wrap more than 2 seconds. We
need to reload the compare compare event about every 1 second.

Signed-off-by: Luwei Zhou <b45643@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-14 14:45:08 -04:00
Nimrod Andy
5bc26726ad net: fec: Fix sparse warnings with different lock contexts for basic block
reproduce:
make  ARCH=arm C=1 2>fec.txt drivers/net/ethernet/freescale/fec_main.o
cat fec.txt

sparse warnings:
drivers/net/ethernet/freescale/fec_main.c:2916:12: warning: context imbalance
in 'fec_set_features' - different lock contexts for basic block

Christopher Li suggest to change as below:
	if (need_lock) {
		lock();
		do_something_real();
		unlock();
	} else {
		do_something_real();
	}

Reported-by: Fabio Estevam <festevam@gmail.com>
Suggested-by: Christopher Li <sparse@chrisli.org>
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-14 12:53:37 -04:00
Fabio Estevam
681d2421e1 fec: Fix fec_enet_alloc_buffers() error path
When fec_enet_alloc_buffers() fails we should better undo the previous actions,
which consists of: disabling the FEC clocks and putting the FEC pins into
inactive state.

The error path for fec_enet_mii_probe() is kept unchanged.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-06 00:53:56 -04:00
Frank Li
c259c132ad net: fec: fix build error at m68k platform
reproduce:
  wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
  chmod +x ~/bin/make.cross
  git checkout 1b7bde6d65

  make.cross ARCH=m68k m5275evb_defconfig
  make.cross ARCH=m68k

All error/warnings:

   drivers/net/ethernet/freescale/fec_main.c: In function 'fec_enet_rx_queue':
>> drivers/net/ethernet/freescale/fec_main.c:1470:3: error: implicit declaration of function 'prefetch' [-Werror=implicit-function-declaration]
      prefetch(skb->data - NET_IP_ALIGN);
      ^
   cc1: some warnings being treated as errors

missed included prefetch.h

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-06 00:19:13 -04:00
Nimrod Andy
1b7bde6d65 net: fec: implement rx_copybreak to improve rx performance
- Copy short frames and keep the buffers mapped, re-allocate skb instead of
  memory copy for long frames.
- Add support for setting/getting rx_copybreak using generic ethtool tunable

Changes V3:
* As Eric Dumazet's suggestion that removing the copybreak module parameter
  and only keep the ethtool API support for rx_copybreak.

Changes V2:
* Implements rx_copybreak
* Rx_copybreak provides module parameter to change this value
* Add tunable_ops support for rx_copybreak

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-10-01 21:28:21 -04:00
Nimrod Andy
e3c9614f3a net: fec: free resource after phy probe failed
Free memory and disable all related clocks when there has no phy
connection or phy probe failed.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-26 16:05:21 -04:00
Nimrod Andy
b64bf4b7dd net: fec: align rx data buffer size for dma map/unmap
Align allocated rx data buffer size for dma map/unmap, otherwise
kernel print warning when enable DMA_API_DEBUG.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-26 16:05:21 -04:00
Nimrod Andy
f88c7ede50 net: fec: remove the ERR006358 workaround for imx6sx enet
Remove the ERR006358 workaround for imx6sx enet since the hw issue
was fixed on the SOC.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-26 16:05:21 -04:00
Nimrod Andy
befe821335 net: fec: Add Ftype to BD to distiguish three tx queues for AVB
The current driver loss Ftype field init for BD, which cause tx
queue #1 and #2 cannot work well.

Add Ftype field to BD to distiguish three queues for AVB:
0 -> Best Effort
1 -> ClassA
2 -> ClassB

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-26 16:05:21 -04:00
Fabio Estevam
aebac74493 fec: Remove fec_enet_select_queue()
Sparse complains about fec_enet_select_queue() not being static.

Feedback from David Miller [1] was to remove this function instead of making it
static:

"Please just delete this function.

It's overriding code which does exactly the same thing.

Actually, more precisely, this code is duplicating code in a way that
bypasses many core facilitites of the networking.  For example, this
override means that socket based flow steering, XPS, etc. are all
not happening on these devices.

Without ->ndo_select_queue(), the flow dissector does __netdev_pick_tx
which is exactly what you want to happen."

[1] http://www.spinics.net/lists/netdev/msg297653.html

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-26 15:39:59 -04:00
Nimrod Andy
b749fc9bff net: fec: fix code identation
There have extra identation before .skb_copy_to_linear_data_offset(),
this patch just remove the identation.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-22 14:52:01 -04:00
Fugang Duan
37d6017b84 net: fec: Workaround for imx6sx enet tx hang when enable three queues
When enable three queues on imx6sx enet, and then do tx performance
test with iperf tool, after some time running, tx hang.

Found that:
	If uDMA is running, software set TDAR may cause tx hang.
	If uDMA is in idle, software set TDAR don't cause tx hang.

There is a TDAR race condition for mutliQ when the software sets TDAR
and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
This will cause the udma_tx and udma_tx_arbiter state machines to hang.
The issue exist at i.MX6SX enet IP.

So, the Workaround is checking TDAR status four time, if TDAR cleared by
hardware and then write TDAR, otherwise don't set TDAR.

The patch is only one Workaround for the issue ERR007885.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-19 15:36:50 -04:00
Fugang Duan
d851b47b22 net: fec: add interrupt coalescence feature support
i.MX6 SX support interrupt coalescence feature
By default, init the interrupt coalescing frame count threshold and
timer threshold.

Supply the ethtool interfaces as below for user tuning to improve
enet performance:
	rx_max_coalesced_frames
	rx_coalesce_usecs
	tx_max_coalesced_frames
	tx_coalesce_usecs

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-19 15:36:50 -04:00
Frank Li
b7bd75cf53 net: fec: refine error handle of parser queue number from DT
check tx and rx queue seperately.
fix typo, "Invalidate" and "fail".
change pr_err to pr_warn.

Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-19 15:36:49 -04:00
Rickard Strandqvist
949bdd2083 net: ethernet: freescale: fec_main.c: Cleaning up missing null-terminate in conjunction with strncpy
Replacing strncpy with strlcpy to avoid strings that lacks null terminate.

Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-15 14:17:00 -04:00
Fabian Frederick
61cd2ebb35 net: fec: use container_of to resolve bufdesc_ex from bufdesc
Use container_of instead of casting first structure member.

ARM cross-compiled but untested.

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-15 12:49:11 -04:00
Fugang Duan
b4d39b53c2 net: fec: init complete variable in early to avoid kernel dump
Software clear the MDIO interrupt before MDIO bus access, but
MAC still generate MDIO interrupt. The issue only happen on
imx6slx chip.

CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.17.0-rc1-00399-g0bcad17 #315
Backtrace:
[<800121fc>] (dump_backtrace) from [<800124e0>] (show_stack+0x18/0x1c)
 r6:8096e534 r5:8096e534 r4:00000000 r3:00000000
[<800124c8>] (show_stack) from [<806a4c60>] (dump_stack+0x8c/0xa4)
[<806a4bd4>] (dump_stack) from [<80060ab8>] (__lock_acquire+0x1814/0x1c40)
 r6:be078000 r5:be074000 r4:be03f6e4 r3:be078000
[<8005f2a4>] (__lock_acquire) from [<800616e0>] (lock_acquire+0x70/0x84)
 r10:809ada33 r9:be010600 r8:00000096 r7:00000001 r6:be074000 r5:00000000
 r4:60000193
[<80061670>] (lock_acquire) from [<806abb20>] (_raw_spin_lock_irqsave+0x40/0x54)
 r7:00000000 r6:8005a3f8 r5:00000193 r4:be03f6d4
[<806abae0>] (_raw_spin_lock_irqsave) from [<8005a3f8>] (complete+0x1c/0x4c)
 r6:80950904 r5:be03f6d0 r4:be03f6d4
[<8005a3dc>] (complete) from [<8041b4c0>] (fec_enet_interrupt+0x128/0x164)
 r6:80950904 r5:00800000 r4:be03f000 r3:00000000
[<8041b398>] (fec_enet_interrupt) from [<8006aeac>] (handle_irq_event_percpu+0x38/0x13c)
 r6:00000000 r5:be01065c r4:be399e00 r3:8041b398
[<8006ae74>] (handle_irq_event_percpu) from [<8006aff4>] (handle_irq_event+0x44/0x64)
 r10:be03f000 r9:80989fe0 r8:00000000 r7:00000096 r6:be399e00 r5:be01065c
 r4:be010600
[<8006afb0>] (handle_irq_event) from [<8006e3e8>] (handle_fasteoi_irq+0xc8/0x1bc)
 r6:8096e764 r5:be01065c r4:be010600 r3:00000000
[<8006e320>] (handle_fasteoi_irq) from [<8006a63c>] (generic_handle_irq+0x30/0x44)
 r6:be074010 r5:80945e4c r4:00000096 r3:8006e320
[<8006a60c>] (generic_handle_irq) from [<8000f218>] (handle_IRQ+0x54/0xbc)
 r4:80950d74 r3:00000180
[<8000f1c4>] (handle_IRQ) from [<800086cc>] (gic_handle_irq+0x30/0x68)
 r8:be3ab478 r7:c080e100 r6:be075bd8 r5:80950eec r4:c080e10c r3:000000a0
[<8000869c>] (gic_handle_irq) from [<80013064>] (__irq_svc+0x44/0x5c)

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:17 -04:00
Fugang Duan
41ef84ce4c net: fec: change FEC alignment according to i.mx6 sx requirement
i.MX6 SX change FEC alignment requirement.
i.MX6 SX change internal bus from AHB to AXI.
It require RX buffer must be 64 bytes alignment.
And remove TX buffer alignment requirement.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:17 -04:00
Fugang Duan
ba593e00e6 net:fec: Add fsl,imx6sx-fec compatible strings
Add compatible string "fsl,imx6sx-fec" for i.MX6SX.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Frank Li
ce99d0d3ab net: fec: add enet-avb IP support
i.MX6SX Enet-AVB support 3 tx queues, 3 rx queues.
For tx queues: ring 0 -> best effort
	       ring 1 -> Class A
	       ring 2 -> Class B
For rx queues:
	       ring 0 -> best effort
	       ring 1 -> receive VLAN packet with classification match
	       ring 2 -> receive VLAN packet with classification match

Add enet-avb IP multiqueue support for the driver.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Fugang Duan
106c314c7a net:fec: Disable enet-avb MAC instead of reset MAC
For i.MX6SX enet use AXI bus, reset MAC will make system bus dead
if ENET-AXI bus has pending access (AHB bus should not have such issue).
So, disable enet with AVB MAC instead of reset MAC itself.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Frank Li
59d0f74656 net: fec: init multi queue date structure
initilized all queues according to queue number get from DT file.

Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: Duan Fugang <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Fugang Duan
9fc095f136 net: fec: parser max queue number from dt file
By default, the tx/rx queue number is 1, user can config the queue number
at DTS file like this:
	fsl,num-tx-queues=<3>;
	fsl,num-rx-queues=<3>

Since i.MX6SX enet-AVB IP support multi queues, so use multi queues
interface to allocate and set up an Ethernet device.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Fugang Duan
4d494cdc92 net: fec: change data structure to support multiqueue
This patch just change data structure to support multi-queue.
Only 1 queue enabled.

Ethernet multiqueue mechanism can improve performance in SMP system.
For single hw queue, multiqueue can balance cpu loading.
For multi hw queues, multiple cores can process network packets in parallel,
and refer the article for the detail advantage for multiqueue:
http://vger.kernel.org/~davem/davem_nyc09.pdf

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <frank.li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Fugang Duan
95a774706d net:fec: add enet AVB feature macro define for imx6sx
Add enet AVB feature macro define for imx6sx.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Fugang Duan
9b5330edf1 net:fec: add enet refrence clock for i.MX 6SX chip
i.MX6sx enet has below clocks for user config:
clk_ipg: ipg_clk_s, ipg_clk_mac0_s, 66Mhz
clk_ahb: enet system clock, it is enet AXI clock for imx6sx.
	 For imx6sx, it alos is the clock source of interrupt coalescing.
	 The clock range: 200Mhz ~ 266Mhz.
clk_ref: refrence clock for tx and rx. For imx6sx enet RGMII mode,
	 the refrence clock is 125Mhz coming from internal PLL or external.
	 In i.MX6sx-arm2 board, the clock is from internal PLL.
	 clk_ref is optional, depends on board.
clk_enet_out: The clock can be output from internal PLL. It can supply 50Mhz
	 clock for phy. clk_enet_out is optional, depends on chip and board.
clk_ptp: 1588 ts clock. It is optional, depends on chip.

The patch add clk_ref to distiguish the different clocks.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-13 17:32:16 -04:00
Nimrod Andy
91c0d987a9 net: fec: ptp: avoid register access when ipg clock is disabled
The current kernel hang on i.MX6SX with rootfs mount from MMC.
The root cause is that ptp uses a periodic timer to access enet register
even if ipg clock is disabled.

FEC ptp driver start one period timer to read 1588 counter register in the
ptp init function that is called after FEC driver is probed.

To save power, after FEC probe finish, FEC driver disable all clocks including
ipg clock that is needed for register access.

i.MX5x, i.MX6q/dl/sl FEC register access don't cause system hang when ipg clock
is disabled, just return zero value. But for i.MX6sx SOC, it cause system hang.

To avoid the issue, we need to check ptp clock status before ptp timer count access.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-08-22 10:45:56 -07:00
Uwe Kleine-König
407066f8f3 net: fec: Support phys probed from devicetree and fixed-link
This adds support for specifying the phy to be used with the fec in the
devicetree using the standard phy-handle property and also supports
fixed-link.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-08-11 14:41:06 -07:00
Fabio Estevam
dd66d38655 fec: Simplify the PM related hooks
Get rid of the CONFIG_PM_SLEEP ifdef by annotating the suspend/resume functions
with '__maybe_unused' in order to keep the code simpler and shorter.

While at it, declare the suspend/resume functions in a single line.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-24 23:26:18 -07:00
Russell King
bfd4ecdd87 net: fec: consolidate hwtstamp implementation
Both transmit and receive use the same infrastructure for calculating
the packet timestamp.  Rather than duplicating the code, provide a
function to do this common work.  Model this function in the Intel
e1000e version which avoids calling ns_to_ktime() within the spinlock;
the spinlock is critical for timecounter_cyc2time() but not
ns_to_ktime().

Acked-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
96018f52c5 net: fec: remove useless status check in tx reap path
Remove a useless status check in the transmit reap path - we have
already checked that the BD_ENET_TX_READY bit is clear, and as the
hardware only ever clears this bit, there is no way this test can ever
be true.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
344756f6e3 net: fec: add support for dumping transmit ring on timeout
When we timeout on transmit, it would be useful to dump the transmit
ring, so we can see the ring state.  This can be helpful to diagnose
the cause of transmit timeouts.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
c1d7c48ff7 net: fec: reorder ethtool ops to match order in struct declaration
This allows us to merge two separate preprocessor conditionals together.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
db3421c114 net: fec: clear receive interrupts before processing a packet
Clear any pending receive interrupt before we process a pending packet.
This helps to avoid any spurious interrupts being raised after we have
fully cleaned the receive ring, while still allowing an interrupt to be
raised if we receive another packet.

The position of this is critical: we must do this prior to reading the
next packet status to avoid potentially dropping an interrupt when a
packet is still pending.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
36cdc743a3 net: fec: replace delayed work with standard work
As of "better implementation of iMX6 ERR006358 quirk", we no longer have
a requirement for a delayed work.  Moreover, the work is now only used
for timeout purposes, so the timeout flag is also pointless - we set it
each time we queue the work, and the work clears it.

Replace the fec_enet_delayed_work struct with a standard work_struct,
resulting in simplified timeout handling code.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:46 -07:00
Russell King
ccea296839 net: fec: better implementation of iMX6 ERR006358 quirk
Using a (delayed) workqueue for ERR006358 is not correct - a work queue
is a single-trigger device.  Once the work queue has been scheduled, it
can't be re-scheduled until it has been run.  This can cause problems -
with an appropriate packet timing, we can end up with packets queued,
but not sent by the hardware, resulting in the transmit timeout firing.

Re-implement this as per the workaround detailed in the ERR006358
documentation - if there are packets waiting to be sent when we service
the transmit ring, and we see that the transmitter is not running,
kick the transmitter to run the pending entries in the ring.

Testing here with a 10Mbit half duplex link sees the resulting iperf
TCP bandwidth increase from between 1 to 2Mbps to between 8 to 9Mbps.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:57:45 -07:00
Russell King
ef83337d13 net: fec: clean up duplex mode handling
Many places call fec_restart() with the second parameter being some kind
of previously saved duplex value, but only two places call it with some
other setting.  This is at odds with how the other link settings are
handled, and used to be racy before the rtnl locks were added to
fec_restart()'s various call paths.

Clean this up so all link capabilities are handled in the same way -
saved into the fec_enet_private structure, and then fec_restart() acts
on those settings.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:59 -07:00
Russell King
f208ce1004 net: fec: quiesce packet processing when taking link down in fec_enet_adjust_link()
When the link goes down, the adjust_link method will be called, but
there is no synchronisation to ensure that we won't be processing some
last remaining packets via the NAPI handlers while performing a reset of
the device.

Add the necessary synchronisation to ensure that packet processing
is complete before we stop and reset the FEC.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:59 -07:00
Russell King
8506fa1d8e net: fec: quiesce packet processing before changing features
Changing the features (receive checksumming) requires the hardware to be
reprogrammed, and also changes the checks in the receive packet
processing.

The current implementation has a race - fec_set_features() changes the
flags which alter the receive packet processing while the adapter is
active, and potentially receiving frames.  Only after we've modified
the software flag do we shutdown and reconfigure the hardware.

This can lead to packets being received and marked with a valid checksum
(via CHECKSUM_UNNECESSARY) when the hardware checksum validation has not
yet been enabled.

We must quiesce the device, then change the software configuration for
this feature, and then resume the device if it was previously running.

The resulting code structure also allows us to add other configuration
features in this path without having to quiesce and resume the network
interface and device.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:59 -07:00
Russell King
9a7ba4381a net: fec: quiesce packet processing before stopping device in fec_set_features()
fec_set_features() calls fec_stop() to stop the transmit ring while the
transmit queue is still active.  This can lead to the transmit ring
being restarted by an intervening packet queued for transmission, or
by the tx quirk timer expiring.

Fix this by disabling NAPI (which ensures that the NAPI handlers are
not running), and then take the transmit lock while we stop and
restart the adapter (which prevents new packets being queued).

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:59 -07:00
Russell King
31a6de34f3 net: fec: quiesce packet processing before stopping device in fec_suspend()
fec_suspend() calls fec_stop() to stop the transmit ring while the
transmit packet processing is still active.  This can lead to the
transmit queue being restarted by an intervening packet queued for
transmission, or by the tx quirk timer expiring.

Fix this by disabling NAPI first, which will ensure that the NAPI
handlers are not running.  Then, take the transmit lock before
detaching the netif device.  This ensures that there are no races
with the transmit path - and also ensures that the watchdog won't
fire.

We can then safely stop the ethernet device itself, knowing that the
rest of the driver is safely shut down.

On resume, we bring the device back up in reverse order - we restart
the device, reattach the device (under the tx lock), and then enable
the NAPI handlers.

We also need to adjust the close function to cope with this new
sequence, so that it's possible to cleanly close down the driver
after the hardware fails to resume (eg, due to the regulator_enable()
or pinctrl calls in the resume path returning an error.)

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:59 -07:00
Russell King
6af42d420b net: fec: remove inappropriate calls around fec_restart()
This is the second stage to "move calls to quiesce/resume packet
processing out of fec_restart()", where we remove calls which are not
appropriate to the call site.

In the majority of cases, there is no need to detach and reattach the
interface as we are holding the queue xmit lock across the reset.  The
exception to that is in fec_resume(), where we are already detached by
the suspend function.  Here, we can remove the call to detach the
interface.

We also do not need to stop the transmit queue.  Holding the xmit lock
is enough to ensure that the transmit packet processing is not running
while we perform our task.  However, since fec_restart() always cleans
the rings, we call netif_wake_queue() (or netif_device_attach() in the
case of resume) just before dropping the xmit lock.  This prevents the
watchdog firing.

Lastly, always call napi_enable() after the device has been reattached
in the resume path so that we know that the transmit packet processing
is already in an enabled state, so we don't call netif_wake_queue()
while detached.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:58 -07:00
Russell King
dbc64a8ea2 net: fec: move calls to quiesce/resume packet processing out of fec_restart()
Move the calls to quiesce and resume packet processing out of
fec_restart() to its call sites.  This is the first step in a two stage
clean up of this code, where we just move the calls out of fec_restart()
without changing them.  Not everywhere needs to issue these calls, and
not everywhere needs all of these calls to be issued.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:58 -07:00
Russell King
8ce5624f5b net: fec: only restart or stop the device if it is present and running
Avoid calling fec_restart() or fec_stop() while the device is down
or not present (iow suspended.)

Although the ndo_timeout method will only be called if the device is
present and running, we defer this to a work queue.  The work queue
can run independently, and so needs to repeat these checks to ensure
that a restart doesn't occur after the device has been taken down or
detached for suspend.  In this case, we call fec_restart() in the
resume path, so nothing is lost.

For fec_set_features, we add a call to fec_restart() in fec_enet_open()
to ensure that the hardware is appropriate programmed when the interface
is opened.  fec_set_features() call should not occur while we're
suspended, so we don't have to worry about that case.

The adjust_link needs similar treatment - this also is called from a
work queue, which may be run independently after we have taken the
device down and detached it.  In this case, we just mark the link
down and take no further action.  We will reset things appropriately
once the device is up and running again, at which point we will receive
another adjust_link callback.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:58 -07:00
Russell King
8bbbd3c19c net: fec: ensure fec_enet_close() copes with resume failure
When the FEC is suspended, the device is detached.  Upon resume failure,
the device is left in detached mode, possibly with some of the required
clocks not running.  We don't want to be poking the device in that state
because as it may cause bus errors.

If the device is marked detached, avoid calling fec_stop().

This depends upon: "net:fec: improve safety of suspend/resume paths"

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:58 -07:00
Russell King
da1774e5f1 net: fec: improve safety of suspend/resume/transmit timeout paths
We should hold the rtnl lock while suspending, resuming or processing
the transmit timeout to ensure that nothing will interfere while we
bring up, take down or restart the hardware.  The transmit timeout
could run if we're preempted during suspend.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-08 20:02:58 -07:00
Russell King
ffdce2cc6a net: fec: fix missing kmalloc() failure check in fec_enet_alloc_buffers()
fec_enet_alloc_buffers() assumes that kmalloc() will never fail, which
is an invalid assumption.  Fix this by implementing a common error
cleanup path, and use it to also clean up after failed bounce buffer
allocation.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-07 21:21:23 -07:00
Russell King
8b7c9efa01 net: fec: ensure fec_enet_free_buffers() properly cleans the rings
Ensure that we do not double-free any allocations, and that any transmit
skbuffs are properly freed when we clean up the rings.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-07 21:21:22 -07:00
Russell King
d6bf31431b net: fec: clean up transmit descriptor setup
Avoid writing any state until we're certain we can proceed with the
transmission: this avoids writing mapping error address values to the
descriptors, or setting the skbuff pointer until we have successfully
mapped the skb.

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-07 21:21:22 -07:00