Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93d62ef9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'amd-xgbe'



Tom Lendacky says:

====================
amd-xgbe: AMD XGBE driver updates 2015-01-16

The following series of patches includes functional updates to the
driver as well as some trivial changes.

- Fix checks/warnings from checkpatch in the amd-xgbe driver
- Fix checks/warnings from checkpatch in the amd-xgbe-phy driver
- Add a check to be sure that the amd-xgbe driver is using the
  amd-xgbe-phy driver
- Use a saved control register value when bringing the PCS out of
  suspend
- Clear all device state during a device restart
- Simplify the Rx descriptor ring tracking
- Remove the need for Tx path spinlocks
- Update the auto-negotiation logic to make use of the auto-negotiation
  interrupt
- Properly support/advertise the FEC capability of the device
- Use the proper page registers during auto-negotiation extended next
  page exchange
- Add ACPI support to the amd-xgbe and amd-xgbe-phy drivers
- Allow platform specific phy settings to be supplied by UEFI

This patch series is based on net-next.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 919d9db9 8fdb1a09
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -7,17 +7,38 @@ Required properties:
   - SerDes Rx/Tx registers
   - SerDes integration registers (1/2)
   - SerDes integration registers (2/2)
- interrupt-parent: Should be the phandle for the interrupt controller
  that services interrupts for this device
- interrupts: Should contain the amd-xgbe-phy interrupt.

Optional properties:
- amd,speed-set: Speed capabilities of the device
    0 - 1GbE and 10GbE (default)
    1 - 2.5GbE and 10GbE

The following optional properties are represented by an array with each
value corresponding to a particular speed. The first array value represents
the setting for the 1GbE speed, the second value for the 2.5GbE speed and
the third value for the 10GbE speed.  All three values are required if the
property is used.
- amd,serdes-blwc: Baseline wandering correction enablement
    0 - Off
    1 - On
- amd,serdes-cdr-rate: CDR rate speed selection
- amd,serdes-pq-skew: PQ (data sampling) skew
- amd,serdes-tx-amp: TX amplitude boost

Example:
	xgbe_phy@e1240800 {
		compatible = "amd,xgbe-phy-seattle-v1a", "ethernet-phy-ieee802.3-c45";
		reg = <0 0xe1240800 0 0x00400>,
		      <0 0xe1250000 0 0x00060>,
		      <0 0xe1250080 0 0x00004>;
		interrupt-parent = <&gic>;
		interrupts = <0 323 4>;
		amd,speed-set = <0>;
		amd,serdes-blwc = <1>, <1>, <0>;
		amd,serdes-cdr-rate = <2>, <2>, <7>;
		amd,serdes-pq-skew = <10>, <10>, <30>;
		amd,serdes-tx-amp = <15>, <15>, <10>;
	};
+1 −1
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ config SUNLANCE

config AMD_XGBE
	tristate "AMD 10GbE Ethernet driver"
	depends on OF_NET && HAS_IOMEM
	depends on (OF_NET || ACPI) && HAS_IOMEM
	select PHYLIB
	select AMD_XGBE_PHY
	select BITREVERSE
+1 −1
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)

	buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
	pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
	if (pdata->xgbe_debugfs == NULL) {
	if (!pdata->xgbe_debugfs) {
		netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
		return;
	}
+1 −31
Original line number Diff line number Diff line
@@ -422,7 +422,6 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)

		ring->cur = 0;
		ring->dirty = 0;
		memset(&ring->rx, 0, sizeof(ring->rx));

		hw_if->rx_desc_init(channel);
	}
@@ -621,35 +620,6 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
	return 0;
}

static void xgbe_realloc_rx_buffer(struct xgbe_channel *channel)
{
	struct xgbe_prv_data *pdata = channel->pdata;
	struct xgbe_hw_if *hw_if = &pdata->hw_if;
	struct xgbe_ring *ring = channel->rx_ring;
	struct xgbe_ring_data *rdata;
	int i;

	DBGPR("-->xgbe_realloc_rx_buffer: rx_ring->rx.realloc_index = %u\n",
	      ring->rx.realloc_index);

	for (i = 0; i < ring->dirty; i++) {
		rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index);

		/* Reset rdata values */
		xgbe_unmap_rdata(pdata, rdata);

		if (xgbe_map_rx_buffer(pdata, ring, rdata))
			break;

		hw_if->rx_desc_reset(rdata);

		ring->rx.realloc_index++;
	}
	ring->dirty = 0;

	DBGPR("<--xgbe_realloc_rx_buffer\n");
}

void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
{
	DBGPR("-->xgbe_init_function_ptrs_desc\n");
@@ -657,7 +627,7 @@ void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
	desc_if->alloc_ring_resources = xgbe_alloc_ring_resources;
	desc_if->free_ring_resources = xgbe_free_ring_resources;
	desc_if->map_tx_skb = xgbe_map_tx_skb;
	desc_if->realloc_rx_buffer = xgbe_realloc_rx_buffer;
	desc_if->map_rx_buffer = xgbe_map_rx_buffer;
	desc_if->unmap_rdata = xgbe_unmap_rdata;
	desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init;
	desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init;
+56 −10
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@
 */

#include <linux/phy.h>
#include <linux/mdio.h>
#include <linux/clk.h>
#include <linux/bitrev.h>
#include <linux/crc32.h>
@@ -130,7 +131,7 @@ static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,

	DBGPR("-->xgbe_usec_to_riwt\n");

	rate = clk_get_rate(pdata->sysclk);
	rate = pdata->sysclk_rate;

	/*
	 * Convert the input usec value to the watchdog timer value. Each
@@ -153,7 +154,7 @@ static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,

	DBGPR("-->xgbe_riwt_to_usec\n");

	rate = clk_get_rate(pdata->sysclk);
	rate = pdata->sysclk_rate;

	/*
	 * Convert the input watchdog timer value to the usec value. Each
@@ -673,6 +674,9 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)

static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x3)
		return 0;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3);

	return 0;
@@ -680,6 +684,9 @@ static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)

static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x2)
		return 0;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2);

	return 0;
@@ -687,6 +694,9 @@ static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata)

static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0)
		return 0;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0);

	return 0;
@@ -881,6 +891,23 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
	else
		mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);

	/* If the PCS is changing modes, match the MAC speed to it */
	if (((mmd_address >> 16) == MDIO_MMD_PCS) &&
	    ((mmd_address & 0xffff) == MDIO_CTRL2)) {
		struct phy_device *phydev = pdata->phydev;

		if (mmd_data & MDIO_PCS_CTRL2_TYPE) {
			/* KX mode */
			if (phydev->supported & SUPPORTED_1000baseKX_Full)
				xgbe_set_gmii_speed(pdata);
			else
				xgbe_set_gmii_2500_speed(pdata);
		} else {
			/* KR mode */
			xgbe_set_xgmii_speed(pdata);
		}
	}

	/* The PCS registers are accessed using mmio. The underlying APB3
	 * management interface uses indirect addressing to access the MMD
	 * register sets. This requires accessing of the PCS register in two
@@ -1359,6 +1386,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
	unsigned int tso_context, vlan_context;
	unsigned int tx_set_ic;
	int start_index = ring->cur;
	int cur_index = ring->cur;
	int i;

	DBGPR("-->xgbe_dev_xmit\n");
@@ -1401,7 +1429,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
	else
		tx_set_ic = 0;

	rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
	rdata = XGBE_GET_DESC_DATA(ring, cur_index);
	rdesc = rdata->rdesc;

	/* Create a context descriptor if this is a TSO packet */
@@ -1444,8 +1472,8 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
			ring->tx.cur_vlan_ctag = packet->vlan_ctag;
		}

		ring->cur++;
		rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
		cur_index++;
		rdata = XGBE_GET_DESC_DATA(ring, cur_index);
		rdesc = rdata->rdesc;
	}

@@ -1473,7 +1501,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
	XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);

	/* Set OWN bit if not the first descriptor */
	if (ring->cur != start_index)
	if (cur_index != start_index)
		XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);

	if (tso) {
@@ -1497,9 +1525,9 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
				  packet->length);
	}

	for (i = ring->cur - start_index + 1; i < packet->rdesc_count; i++) {
		ring->cur++;
		rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
	for (i = cur_index - start_index + 1; i < packet->rdesc_count; i++) {
		cur_index++;
		rdata = XGBE_GET_DESC_DATA(ring, cur_index);
		rdesc = rdata->rdesc;

		/* Update buffer address */
@@ -1551,7 +1579,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
	/* Make sure ownership is written to the descriptor */
	wmb();

	ring->cur++;
	ring->cur = cur_index + 1;
	if (!packet->skb->xmit_more ||
	    netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev,
						   channel->queue_index)))
@@ -2107,6 +2135,23 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
	XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
}

static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata)
{
	switch (pdata->phy_speed) {
	case SPEED_10000:
		xgbe_set_xgmii_speed(pdata);
		break;

	case SPEED_2500:
		xgbe_set_gmii_2500_speed(pdata);
		break;

	case SPEED_1000:
		xgbe_set_gmii_speed(pdata);
		break;
	}
}

static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
{
	if (pdata->netdev->features & NETIF_F_RXCSUM)
@@ -2757,6 +2802,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
	xgbe_config_mac_address(pdata);
	xgbe_config_jumbo_enable(pdata);
	xgbe_config_flow_control(pdata);
	xgbe_config_mac_speed(pdata);
	xgbe_config_checksum_offload(pdata);
	xgbe_config_vlan_support(pdata);
	xgbe_config_mmc(pdata);
Loading