Skip to content

Commit

Permalink
Merge branch 'amd-xgbe'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 17, 2015
2 parents 919d9db + 8fdb1a0 commit 93d62ef
Show file tree
Hide file tree
Showing 12 changed files with 932 additions and 498 deletions.
21 changes: 21 additions & 0 deletions Documentation/devicetree/bindings/net/amd-xgbe-phy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
};
2 changes: 1 addition & 1 deletion drivers/net/ethernet/amd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
32 changes: 1 addition & 31 deletions drivers/net/ethernet/amd/xgbe/xgbe-desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -621,43 +620,14 @@ 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");

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;
Expand Down
66 changes: 56 additions & 10 deletions drivers/net/ethernet/amd/xgbe/xgbe-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
*/

#include <linux/phy.h>
#include <linux/mdio.h>
#include <linux/clk.h>
#include <linux/bitrev.h>
#include <linux/crc32.h>
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -673,20 +674,29 @@ 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;
}

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;
}

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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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 */
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 93d62ef

Please sign in to comment.