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

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
...@@ -7,17 +7,38 @@ Required properties: ...@@ -7,17 +7,38 @@ Required properties:
- SerDes Rx/Tx registers - SerDes Rx/Tx registers
- SerDes integration registers (1/2) - SerDes integration registers (1/2)
- SerDes integration registers (2/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: Optional properties:
- amd,speed-set: Speed capabilities of the device - amd,speed-set: Speed capabilities of the device
0 - 1GbE and 10GbE (default) 0 - 1GbE and 10GbE (default)
1 - 2.5GbE and 10GbE 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: Example:
xgbe_phy@e1240800 { xgbe_phy@e1240800 {
compatible = "amd,xgbe-phy-seattle-v1a", "ethernet-phy-ieee802.3-c45"; compatible = "amd,xgbe-phy-seattle-v1a", "ethernet-phy-ieee802.3-c45";
reg = <0 0xe1240800 0 0x00400>, reg = <0 0xe1240800 0 0x00400>,
<0 0xe1250000 0 0x00060>, <0 0xe1250000 0 0x00060>,
<0 0xe1250080 0 0x00004>; <0 0xe1250080 0 0x00004>;
interrupt-parent = <&gic>;
interrupts = <0 323 4>;
amd,speed-set = <0>; 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>;
}; };
...@@ -179,7 +179,7 @@ config SUNLANCE ...@@ -179,7 +179,7 @@ config SUNLANCE
config AMD_XGBE config AMD_XGBE
tristate "AMD 10GbE Ethernet driver" tristate "AMD 10GbE Ethernet driver"
depends on OF_NET && HAS_IOMEM depends on (OF_NET || ACPI) && HAS_IOMEM
select PHYLIB select PHYLIB
select AMD_XGBE_PHY select AMD_XGBE_PHY
select BITREVERSE select BITREVERSE
......
...@@ -328,7 +328,7 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata) ...@@ -328,7 +328,7 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL); 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"); netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
return; return;
} }
......
...@@ -422,7 +422,6 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata) ...@@ -422,7 +422,6 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
ring->cur = 0; ring->cur = 0;
ring->dirty = 0; ring->dirty = 0;
memset(&ring->rx, 0, sizeof(ring->rx));
hw_if->rx_desc_init(channel); hw_if->rx_desc_init(channel);
} }
...@@ -621,35 +620,6 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb) ...@@ -621,35 +620,6 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
return 0; 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) void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
{ {
DBGPR("-->xgbe_init_function_ptrs_desc\n"); DBGPR("-->xgbe_init_function_ptrs_desc\n");
...@@ -657,7 +627,7 @@ void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if) ...@@ -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->alloc_ring_resources = xgbe_alloc_ring_resources;
desc_if->free_ring_resources = xgbe_free_ring_resources; desc_if->free_ring_resources = xgbe_free_ring_resources;
desc_if->map_tx_skb = xgbe_map_tx_skb; 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->unmap_rdata = xgbe_unmap_rdata;
desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init; desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init;
desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init; desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init;
......
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
*/ */
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/mdio.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/bitrev.h> #include <linux/bitrev.h>
#include <linux/crc32.h> #include <linux/crc32.h>
...@@ -130,7 +131,7 @@ static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata, ...@@ -130,7 +131,7 @@ static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,
DBGPR("-->xgbe_usec_to_riwt\n"); 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 * 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, ...@@ -153,7 +154,7 @@ static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,
DBGPR("-->xgbe_riwt_to_usec\n"); 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 * 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) ...@@ -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) 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); XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3);
return 0; return 0;
...@@ -680,6 +684,9 @@ static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata) ...@@ -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) 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); XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2);
return 0; return 0;
...@@ -687,6 +694,9 @@ static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata) ...@@ -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) 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); XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0);
return 0; return 0;
...@@ -881,6 +891,23 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad, ...@@ -881,6 +891,23 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
else else
mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff); 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 /* The PCS registers are accessed using mmio. The underlying APB3
* management interface uses indirect addressing to access the MMD * management interface uses indirect addressing to access the MMD
* register sets. This requires accessing of the PCS register in two * register sets. This requires accessing of the PCS register in two
...@@ -1359,6 +1386,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1359,6 +1386,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
unsigned int tso_context, vlan_context; unsigned int tso_context, vlan_context;
unsigned int tx_set_ic; unsigned int tx_set_ic;
int start_index = ring->cur; int start_index = ring->cur;
int cur_index = ring->cur;
int i; int i;
DBGPR("-->xgbe_dev_xmit\n"); DBGPR("-->xgbe_dev_xmit\n");
...@@ -1401,7 +1429,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1401,7 +1429,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
else else
tx_set_ic = 0; tx_set_ic = 0;
rdata = XGBE_GET_DESC_DATA(ring, ring->cur); rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc; rdesc = rdata->rdesc;
/* Create a context descriptor if this is a TSO packet */ /* Create a context descriptor if this is a TSO packet */
...@@ -1444,8 +1472,8 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1444,8 +1472,8 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
ring->tx.cur_vlan_ctag = packet->vlan_ctag; ring->tx.cur_vlan_ctag = packet->vlan_ctag;
} }
ring->cur++; cur_index++;
rdata = XGBE_GET_DESC_DATA(ring, ring->cur); rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc; rdesc = rdata->rdesc;
} }
...@@ -1473,7 +1501,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1473,7 +1501,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0); XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
/* Set OWN bit if not the first descriptor */ /* 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); XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
if (tso) { if (tso) {
...@@ -1497,9 +1525,9 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1497,9 +1525,9 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
packet->length); packet->length);
} }
for (i = ring->cur - start_index + 1; i < packet->rdesc_count; i++) { for (i = cur_index - start_index + 1; i < packet->rdesc_count; i++) {
ring->cur++; cur_index++;
rdata = XGBE_GET_DESC_DATA(ring, ring->cur); rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc; rdesc = rdata->rdesc;
/* Update buffer address */ /* Update buffer address */
...@@ -1551,7 +1579,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) ...@@ -1551,7 +1579,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
/* Make sure ownership is written to the descriptor */ /* Make sure ownership is written to the descriptor */
wmb(); wmb();
ring->cur++; ring->cur = cur_index + 1;
if (!packet->skb->xmit_more || if (!packet->skb->xmit_more ||
netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev, netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev,
channel->queue_index))) channel->queue_index)))
...@@ -2107,6 +2135,23 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata) ...@@ -2107,6 +2135,23 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val); 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) static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
{ {
if (pdata->netdev->features & NETIF_F_RXCSUM) if (pdata->netdev->features & NETIF_F_RXCSUM)
...@@ -2757,6 +2802,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata) ...@@ -2757,6 +2802,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
xgbe_config_mac_address(pdata); xgbe_config_mac_address(pdata);
xgbe_config_jumbo_enable(pdata); xgbe_config_jumbo_enable(pdata);
xgbe_config_flow_control(pdata); xgbe_config_flow_control(pdata);
xgbe_config_mac_speed(pdata);
xgbe_config_checksum_offload(pdata); xgbe_config_checksum_offload(pdata);
xgbe_config_vlan_support(pdata); xgbe_config_vlan_support(pdata);
xgbe_config_mmc(pdata); xgbe_config_mmc(pdata);
......
...@@ -225,6 +225,11 @@ static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring) ...@@ -225,6 +225,11 @@ static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
return (ring->rdesc_count - (ring->cur - ring->dirty)); return (ring->rdesc_count - (ring->cur - ring->dirty));
} }
static inline unsigned int xgbe_rx_dirty_desc(struct xgbe_ring *ring)
{
return (ring->cur - ring->dirty);
}
static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel, static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel,
struct xgbe_ring *ring, unsigned int count) struct xgbe_ring *ring, unsigned int count)
{ {
...@@ -410,17 +415,13 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer) ...@@ -410,17 +415,13 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
struct xgbe_channel *channel = container_of(timer, struct xgbe_channel *channel = container_of(timer,
struct xgbe_channel, struct xgbe_channel,
tx_timer); tx_timer);
struct xgbe_ring *ring = channel->tx_ring;
struct xgbe_prv_data *pdata = channel->pdata; struct xgbe_prv_data *pdata = channel->pdata;
struct napi_struct *napi; struct napi_struct *napi;
unsigned long flags;
DBGPR("-->xgbe_tx_timer\n"); DBGPR("-->xgbe_tx_timer\n");
napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi; napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi;
spin_lock_irqsave(&ring->lock, flags);
if (napi_schedule_prep(napi)) { if (napi_schedule_prep(napi)) {
/* Disable Tx and Rx interrupts */ /* Disable Tx and Rx interrupts */
if (pdata->per_channel_irq) if (pdata->per_channel_irq)
...@@ -434,8 +435,6 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer) ...@@ -434,8 +435,6 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
channel->tx_timer_active = 0; channel->tx_timer_active = 0;
spin_unlock_irqrestore(&ring->lock, flags);
DBGPR("<--xgbe_tx_timer\n"); DBGPR("<--xgbe_tx_timer\n");
return HRTIMER_NORESTART; return HRTIMER_NORESTART;
...@@ -692,7 +691,7 @@ static void xgbe_adjust_link(struct net_device *netdev) ...@@ -692,7 +691,7 @@ static void xgbe_adjust_link(struct net_device *netdev)
struct phy_device *phydev = pdata->phydev; struct phy_device *phydev = pdata->phydev;
int new_state = 0; int new_state = 0;
if (phydev == NULL) if (!phydev)
return; return;
if (phydev->link) { if (phydev->link) {
...@@ -927,7 +926,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) ...@@ -927,7 +926,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
DBGPR("<--xgbe_stop\n"); DBGPR("<--xgbe_stop\n");
} }
static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset) static void xgbe_restart_dev(struct xgbe_prv_data *pdata)
{ {
struct xgbe_channel *channel; struct xgbe_channel *channel;
struct xgbe_hw_if *hw_if = &pdata->hw_if; struct xgbe_hw_if *hw_if = &pdata->hw_if;
...@@ -950,9 +949,8 @@ static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset) ...@@ -950,9 +949,8 @@ static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset)
xgbe_free_tx_data(pdata); xgbe_free_tx_data(pdata);
xgbe_free_rx_data(pdata); xgbe_free_rx_data(pdata);
/* Issue software reset to device if requested */ /* Issue software reset to device */
if (reset) hw_if->exit(pdata);
hw_if->exit(pdata);
xgbe_start(pdata); xgbe_start(pdata);
...@@ -967,7 +965,7 @@ static void xgbe_restart(struct work_struct *work) ...@@ -967,7 +965,7 @@ static void xgbe_restart(struct work_struct *work)
rtnl_lock(); rtnl_lock();
xgbe_restart_dev(pdata, 1); xgbe_restart_dev(pdata);
rtnl_unlock(); rtnl_unlock();
} }
...@@ -1446,7 +1444,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1446,7 +1444,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
struct xgbe_ring *ring; struct xgbe_ring *ring;
struct xgbe_packet_data *packet; struct xgbe_packet_data *packet;
struct netdev_queue *txq; struct netdev_queue *txq;
unsigned long flags;
int ret; int ret;
DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len); DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
...@@ -1458,8 +1455,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1458,8 +1455,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
ret = NETDEV_TX_OK; ret = NETDEV_TX_OK;
spin_lock_irqsave(&ring->lock, flags);
if (skb->len == 0) { if (skb->len == 0) {
netdev_err(netdev, "empty skb received from stack\n"); netdev_err(netdev, "empty skb received from stack\n");
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
...@@ -1506,10 +1501,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1506,10 +1501,6 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
ret = NETDEV_TX_OK; ret = NETDEV_TX_OK;
tx_netdev_return: tx_netdev_return:
spin_unlock_irqrestore(&ring->lock, flags);
DBGPR("<--xgbe_xmit\n");
return ret; return ret;
} }
...@@ -1587,7 +1578,7 @@ static int xgbe_change_mtu(struct net_device *netdev, int mtu) ...@@ -1587,7 +1578,7 @@ static int xgbe_change_mtu(struct net_device *netdev, int mtu)
pdata->rx_buf_size = ret; pdata->rx_buf_size = ret;
netdev->mtu = mtu; netdev->mtu = mtu;
xgbe_restart_dev(pdata, 0); xgbe_restart_dev(pdata);
DBGPR("<--xgbe_change_mtu\n"); DBGPR("<--xgbe_change_mtu\n");
...@@ -1776,15 +1767,28 @@ struct net_device_ops *xgbe_get_netdev_ops(void) ...@@ -1776,15 +1767,28 @@ struct net_device_ops *xgbe_get_netdev_ops(void)
static void xgbe_rx_refresh(struct xgbe_channel *channel) static void xgbe_rx_refresh(struct xgbe_channel *channel)
{ {
struct xgbe_prv_data *pdata = channel->pdata; struct xgbe_prv_data *pdata = channel->pdata;
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_desc_if *desc_if = &pdata->desc_if; struct xgbe_desc_if *desc_if = &pdata->desc_if;
struct xgbe_ring *ring = channel->rx_ring; struct xgbe_ring *ring = channel->rx_ring;
struct xgbe_ring_data *rdata; struct xgbe_ring_data *rdata;
desc_if->realloc_rx_buffer(channel); while (ring->dirty != ring->cur) {
rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
/* Reset rdata values */
desc_if->unmap_rdata(pdata, rdata);
if (desc_if->map_rx_buffer(pdata, ring, rdata))
break;
hw_if->rx_desc_reset(rdata);
ring->dirty++;
}
/* Update the Rx Tail Pointer Register with address of /* Update the Rx Tail Pointer Register with address of
* the last cleaned entry */ * the last cleaned entry */
rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index - 1); rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO, XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
lower_32_bits(rdata->rdesc_dma)); lower_32_bits(rdata->rdesc_dma));
} }
...@@ -1824,7 +1828,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) ...@@ -1824,7 +1828,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
struct xgbe_ring_desc *rdesc; struct xgbe_ring_desc *rdesc;
struct net_device *netdev = pdata->netdev; struct net_device *netdev = pdata->netdev;
struct netdev_queue *txq; struct netdev_queue *txq;
unsigned long flags;
int processed = 0; int processed = 0;
unsigned int tx_packets = 0, tx_bytes = 0; unsigned int tx_packets = 0, tx_bytes = 0;
...@@ -1836,8 +1839,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) ...@@ -1836,8 +1839,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
txq = netdev_get_tx_queue(netdev, channel->queue_index); txq = netdev_get_tx_queue(netdev, channel->queue_index);
spin_lock_irqsave(&ring->lock, flags);
while ((processed < XGBE_TX_DESC_MAX_PROC) && while ((processed < XGBE_TX_DESC_MAX_PROC) &&
(ring->dirty != ring->cur)) { (ring->dirty != ring->cur)) {
rdata = XGBE_GET_DESC_DATA(ring, ring->dirty); rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
...@@ -1868,7 +1869,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) ...@@ -1868,7 +1869,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
} }
if (!processed) if (!processed)
goto unlock; return 0;
netdev_tx_completed_queue(txq, tx_packets, tx_bytes); netdev_tx_completed_queue(txq, tx_packets, tx_bytes);
...@@ -1880,9 +1881,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) ...@@ -1880,9 +1881,6 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
DBGPR("<--xgbe_tx_poll: processed=%d\n", processed); DBGPR("<--xgbe_tx_poll: processed=%d\n", processed);
unlock:
spin_unlock_irqrestore(&ring->lock, flags);
return processed; return processed;
} }
...@@ -1934,7 +1932,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) ...@@ -1934,7 +1932,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
read_again: read_again:
rdata = XGBE_GET_DESC_DATA(ring, ring->cur); rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
if (ring->dirty > (XGBE_RX_DESC_CNT >> 3)) if (xgbe_rx_dirty_desc(ring) > (XGBE_RX_DESC_CNT >> 3))
xgbe_rx_refresh(channel); xgbe_rx_refresh(channel);
if (hw_if->dev_read(channel)) if (hw_if->dev_read(channel))
...@@ -1942,7 +1940,6 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) ...@@ -1942,7 +1940,6 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
received++; received++;
ring->cur++; ring->cur++;
ring->dirty++;
incomplete = XGMAC_GET_BITS(packet->attributes, incomplete = XGMAC_GET_BITS(packet->attributes,
RX_PACKET_ATTRIBUTES, RX_PACKET_ATTRIBUTES,
......
...@@ -123,7 +123,10 @@ ...@@ -123,7 +123,10 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_address.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/property.h>
#include <linux/acpi.h>
#include "xgbe.h" #include "xgbe.h"
#include "xgbe-common.h" #include "xgbe-common.h"
...@@ -148,6 +151,7 @@ static void xgbe_default_config(struct xgbe_prv_data *pdata) ...@@ -148,6 +151,7 @@ static void xgbe_default_config(struct xgbe_prv_data *pdata)
pdata->pause_autoneg = 1; pdata->pause_autoneg = 1;
pdata->tx_pause = 1; pdata->tx_pause = 1;
pdata->rx_pause = 1; pdata->rx_pause = 1;
pdata->phy_speed = SPEED_UNKNOWN;
pdata->power_down = 0; pdata->power_down = 0;
pdata->default_autoneg = AUTONEG_ENABLE; pdata->default_autoneg = AUTONEG_ENABLE;
pdata->default_speed = SPEED_10000; pdata->default_speed = SPEED_10000;
...@@ -161,6 +165,96 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata) ...@@ -161,6 +165,96 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
xgbe_init_function_ptrs_desc(&pdata->desc_if); xgbe_init_function_ptrs_desc(&pdata->desc_if);
} }
#ifdef CONFIG_ACPI
static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{
struct acpi_device *adev = pdata->adev;
struct device *dev = pdata->dev;
u32 property;
acpi_handle handle;
acpi_status status;
unsigned long long data;
int cca;
int ret;
/* Obtain the system clock setting */
ret = device_property_read_u32(dev, XGBE_ACPI_DMA_FREQ, &property);
if (ret) {
dev_err(dev, "unable to obtain %s property\n",
XGBE_ACPI_DMA_FREQ);
return ret;
}
pdata->sysclk_rate = property;
/* Obtain the PTP clock setting */
ret = device_property_read_u32(dev, XGBE_ACPI_PTP_FREQ, &property);
if (ret) {
dev_err(dev, "unable to obtain %s property\n",
XGBE_ACPI_PTP_FREQ);
return ret;
}
pdata->ptpclk_rate = property;
/* Retrieve the device cache coherency value */
handle = adev->handle;
do {
status = acpi_evaluate_integer(handle, "_CCA", NULL, &data);
if (!ACPI_FAILURE(status)) {
cca = data;
break;
}
status = acpi_get_parent(handle, &handle);
} while (!ACPI_FAILURE(status));
if (ACPI_FAILURE(status)) {
dev_err(dev, "error obtaining acpi coherency value\n");
return -EINVAL;
}
pdata->coherent = !!cca;
return 0;
}
#else /* CONFIG_ACPI */
static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{
return -EINVAL;
}
#endif /* CONFIG_ACPI */
#ifdef CONFIG_OF
static int xgbe_of_support(struct xgbe_prv_data *pdata)
{
struct device *dev = pdata->dev;
/* Obtain the system clock setting */
pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
if (IS_ERR(pdata->sysclk)) {
dev_err(dev, "dma devm_clk_get failed\n");
return PTR_ERR(pdata->sysclk);
}
pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
/* Obtain the PTP clock setting */
pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
if (IS_ERR(pdata->ptpclk)) {
dev_err(dev, "ptp devm_clk_get failed\n");
return PTR_ERR(pdata->ptpclk);
}
pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
/* Retrieve the device cache coherency value */
pdata->coherent = of_dma_is_coherent(dev->of_node);
return 0;
}
#else /* CONFIG_OF */
static int xgbe_of_support(struct xgbe_prv_data *pdata)
{
return -EINVAL;
}
#endif /*CONFIG_OF */
static int xgbe_probe(struct platform_device *pdev) static int xgbe_probe(struct platform_device *pdev)
{ {
struct xgbe_prv_data *pdata; struct xgbe_prv_data *pdata;
...@@ -169,7 +263,7 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -169,7 +263,7 @@ static int xgbe_probe(struct platform_device *pdev)
struct net_device *netdev; struct net_device *netdev;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res; struct resource *res;
const u8 *mac_addr; const char *phy_mode;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -186,6 +280,7 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -186,6 +280,7 @@ static int xgbe_probe(struct platform_device *pdev)
pdata = netdev_priv(netdev); pdata = netdev_priv(netdev);
pdata->netdev = netdev; pdata->netdev = netdev;
pdata->pdev = pdev; pdata->pdev = pdev;
pdata->adev = ACPI_COMPANION(dev);
pdata->dev = dev; pdata->dev = dev;
platform_set_drvdata(pdev, netdev); platform_set_drvdata(pdev, netdev);
...@@ -194,6 +289,9 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -194,6 +289,9 @@ static int xgbe_probe(struct platform_device *pdev)
mutex_init(&pdata->rss_mutex); mutex_init(&pdata->rss_mutex);
spin_lock_init(&pdata->tstamp_lock); spin_lock_init(&pdata->tstamp_lock);
/* Check if we should use ACPI or DT */
pdata->use_acpi = (!pdata->adev || acpi_disabled) ? 0 : 1;
/* Set and validate the number of descriptors for a ring */ /* Set and validate the number of descriptors for a ring */
BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT); BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT);
pdata->tx_desc_count = XGBE_TX_DESC_CNT; pdata->tx_desc_count = XGBE_TX_DESC_CNT;
...@@ -212,22 +310,6 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -212,22 +310,6 @@ static int xgbe_probe(struct platform_device *pdev)
goto err_io; goto err_io;
} }
/* Obtain the system clock setting */
pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
if (IS_ERR(pdata->sysclk)) {
dev_err(dev, "dma devm_clk_get failed\n");
ret = PTR_ERR(pdata->sysclk);
goto err_io;
}
/* Obtain the PTP clock setting */
pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
if (IS_ERR(pdata->ptpclk)) {
dev_err(dev, "ptp devm_clk_get failed\n");
ret = PTR_ERR(pdata->ptpclk);
goto err_io;
}
/* Obtain the mmio areas for the device */ /* Obtain the mmio areas for the device */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pdata->xgmac_regs = devm_ioremap_resource(dev, res); pdata->xgmac_regs = devm_ioremap_resource(dev, res);
...@@ -247,16 +329,42 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -247,16 +329,42 @@ static int xgbe_probe(struct platform_device *pdev)
} }
DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs); DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs);
/* Set the DMA mask */ /* Retrieve the MAC address */
if (!dev->dma_mask) ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY,
dev->dma_mask = &dev->coherent_dma_mask; pdata->mac_addr,
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); sizeof(pdata->mac_addr));
if (ret) { if (ret || !is_valid_ether_addr(pdata->mac_addr)) {
dev_err(dev, "dma_set_mask_and_coherent failed\n"); dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY);
if (!ret)
ret = -EINVAL;
goto err_io; goto err_io;
} }
if (of_property_read_bool(dev->of_node, "dma-coherent")) { /* Retrieve the PHY mode - it must be "xgmii" */
ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
&phy_mode);
if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY);
if (!ret)
ret = -EINVAL;
goto err_io;
}
pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
/* Check for per channel interrupt support */
if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY))
pdata->per_channel_irq = 1;
/* Obtain device settings unique to ACPI/OF */
if (pdata->use_acpi)
ret = xgbe_acpi_support(pdata);
else
ret = xgbe_of_support(pdata);
if (ret)
goto err_io;
/* Set the DMA coherency values */
if (pdata->coherent) {
pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
pdata->arcache = XGBE_DMA_OS_ARCACHE; pdata->arcache = XGBE_DMA_OS_ARCACHE;
pdata->awcache = XGBE_DMA_OS_AWCACHE; pdata->awcache = XGBE_DMA_OS_AWCACHE;
...@@ -266,10 +374,16 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -266,10 +374,16 @@ static int xgbe_probe(struct platform_device *pdev)
pdata->awcache = XGBE_DMA_SYS_AWCACHE; pdata->awcache = XGBE_DMA_SYS_AWCACHE;
} }
/* Check for per channel interrupt support */ /* Set the DMA mask */
if (of_property_read_bool(dev->of_node, XGBE_DMA_IRQS)) if (!dev->dma_mask)
pdata->per_channel_irq = 1; dev->dma_mask = &dev->coherent_dma_mask;
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
if (ret) {
dev_err(dev, "dma_set_mask_and_coherent failed\n");
goto err_io;
}
/* Get the device interrupt */
ret = platform_get_irq(pdev, 0); ret = platform_get_irq(pdev, 0);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "platform_get_irq 0 failed\n"); dev_err(dev, "platform_get_irq 0 failed\n");
...@@ -279,6 +393,7 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -279,6 +393,7 @@ static int xgbe_probe(struct platform_device *pdev)
netdev->irq = pdata->dev_irq; netdev->irq = pdata->dev_irq;
netdev->base_addr = (unsigned long)pdata->xgmac_regs; netdev->base_addr = (unsigned long)pdata->xgmac_regs;
memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len);
/* Set all the function pointers */ /* Set all the function pointers */
xgbe_init_all_fptrs(pdata); xgbe_init_all_fptrs(pdata);
...@@ -291,23 +406,6 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -291,23 +406,6 @@ static int xgbe_probe(struct platform_device *pdev)
/* Populate the hardware features */ /* Populate the hardware features */
xgbe_get_all_hw_features(pdata); xgbe_get_all_hw_features(pdata);
/* Retrieve the MAC address */
mac_addr = of_get_mac_address(dev->of_node);
if (!mac_addr) {
dev_err(dev, "invalid mac address for this device\n");
ret = -EINVAL;
goto err_io;
}
memcpy(netdev->dev_addr, mac_addr, netdev->addr_len);
/* Retrieve the PHY mode - it must be "xgmii" */
pdata->phy_mode = of_get_phy_mode(dev->of_node);
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
dev_err(dev, "invalid phy-mode specified for this device\n");
ret = -EINVAL;
goto err_io;
}
/* Set default configuration data */ /* Set default configuration data */
xgbe_default_config(pdata); xgbe_default_config(pdata);
...@@ -491,18 +589,35 @@ static int xgbe_resume(struct device *dev) ...@@ -491,18 +589,35 @@ static int xgbe_resume(struct device *dev)
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgbe_acpi_match[] = {
{ "AMDI8001", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
#endif
#ifdef CONFIG_OF
static const struct of_device_id xgbe_of_match[] = { static const struct of_device_id xgbe_of_match[] = {
{ .compatible = "amd,xgbe-seattle-v1a", }, { .compatible = "amd,xgbe-seattle-v1a", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, xgbe_of_match); MODULE_DEVICE_TABLE(of, xgbe_of_match);
#endif
static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume); static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
static struct platform_driver xgbe_driver = { static struct platform_driver xgbe_driver = {
.driver = { .driver = {
.name = "amd-xgbe", .name = "amd-xgbe",
#ifdef CONFIG_ACPI
.acpi_match_table = xgbe_acpi_match,
#endif
#ifdef CONFIG_OF
.of_match_table = xgbe_of_match, .of_match_table = xgbe_of_match,
#endif
.pm = &xgbe_pm_ops, .pm = &xgbe_pm_ops,
}, },
.probe = xgbe_probe, .probe = xgbe_probe,
......
...@@ -205,25 +205,16 @@ void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata) ...@@ -205,25 +205,16 @@ void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
int xgbe_mdio_register(struct xgbe_prv_data *pdata) int xgbe_mdio_register(struct xgbe_prv_data *pdata)
{ {
struct device_node *phy_node;
struct mii_bus *mii; struct mii_bus *mii;
struct phy_device *phydev; struct phy_device *phydev;
int ret = 0; int ret = 0;
DBGPR("-->xgbe_mdio_register\n"); DBGPR("-->xgbe_mdio_register\n");
/* Retrieve the phy-handle */
phy_node = of_parse_phandle(pdata->dev->of_node, "phy-handle", 0);
if (!phy_node) {
dev_err(pdata->dev, "unable to parse phy-handle\n");
return -EINVAL;
}
mii = mdiobus_alloc(); mii = mdiobus_alloc();
if (mii == NULL) { if (!mii) {
dev_err(pdata->dev, "mdiobus_alloc failed\n"); dev_err(pdata->dev, "mdiobus_alloc failed\n");
ret = -ENOMEM; return -ENOMEM;
goto err_node_get;
} }
/* Register on the MDIO bus (don't probe any PHYs) */ /* Register on the MDIO bus (don't probe any PHYs) */
...@@ -252,18 +243,19 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata) ...@@ -252,18 +243,19 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS])); MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS]));
of_node_get(phy_node);
phydev->dev.of_node = phy_node;
ret = phy_device_register(phydev); ret = phy_device_register(phydev);
if (ret) { if (ret) {
dev_err(pdata->dev, "phy_device_register failed\n"); dev_err(pdata->dev, "phy_device_register failed\n");
of_node_put(phy_node); goto err_phy_device;
}
if (!phydev->dev.driver) {
dev_err(pdata->dev, "phy driver probe failed\n");
ret = -EIO;
goto err_phy_device; goto err_phy_device;
} }
/* Add a reference to the PHY driver so it can't be unloaded */ /* Add a reference to the PHY driver so it can't be unloaded */
pdata->phy_module = phydev->dev.driver ? pdata->phy_module = phydev->dev.driver->owner;
phydev->dev.driver->owner : NULL;
if (!try_module_get(pdata->phy_module)) { if (!try_module_get(pdata->phy_module)) {
dev_err(pdata->dev, "try_module_get failed\n"); dev_err(pdata->dev, "try_module_get failed\n");
ret = -EIO; ret = -EIO;
...@@ -283,8 +275,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata) ...@@ -283,8 +275,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
pdata->phydev = phydev; pdata->phydev = phydev;
of_node_put(phy_node);
DBGPHY_REGS(pdata); DBGPHY_REGS(pdata);
DBGPR("<--xgbe_mdio_register\n"); DBGPR("<--xgbe_mdio_register\n");
...@@ -300,9 +290,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata) ...@@ -300,9 +290,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
err_mdiobus_alloc: err_mdiobus_alloc:
mdiobus_free(mii); mdiobus_free(mii);
err_node_get:
of_node_put(phy_node);
return ret; return ret;
} }
......
...@@ -233,7 +233,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) ...@@ -233,7 +233,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
snprintf(info->name, sizeof(info->name), "%s", snprintf(info->name, sizeof(info->name), "%s",
netdev_name(pdata->netdev)); netdev_name(pdata->netdev));
info->owner = THIS_MODULE; info->owner = THIS_MODULE;
info->max_adj = clk_get_rate(pdata->ptpclk); info->max_adj = pdata->ptpclk_rate;
info->adjfreq = xgbe_adjfreq; info->adjfreq = xgbe_adjfreq;
info->adjtime = xgbe_adjtime; info->adjtime = xgbe_adjtime;
info->gettime = xgbe_gettime; info->gettime = xgbe_gettime;
...@@ -254,7 +254,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) ...@@ -254,7 +254,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
*/ */
dividend = 50000000; dividend = 50000000;
dividend <<= 32; dividend <<= 32;
pdata->tstamp_addend = div_u64(dividend, clk_get_rate(pdata->ptpclk)); pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
/* Setup the timecounter */ /* Setup the timecounter */
cc->read = xgbe_cc_read; cc->read = xgbe_cc_read;
......
...@@ -182,10 +182,18 @@ ...@@ -182,10 +182,18 @@
#define XGBE_PHY_NAME "amd_xgbe_phy" #define XGBE_PHY_NAME "amd_xgbe_phy"
#define XGBE_PRTAD 0 #define XGBE_PRTAD 0
/* Common property names */
#define XGBE_MAC_ADDR_PROPERTY "mac-address"
#define XGBE_PHY_MODE_PROPERTY "phy-mode"
#define XGBE_DMA_IRQS_PROPERTY "amd,per-channel-interrupt"
/* Device-tree clock names */ /* Device-tree clock names */
#define XGBE_DMA_CLOCK "dma_clk" #define XGBE_DMA_CLOCK "dma_clk"
#define XGBE_PTP_CLOCK "ptp_clk" #define XGBE_PTP_CLOCK "ptp_clk"
#define XGBE_DMA_IRQS "amd,per-channel-interrupt"
/* ACPI property names */
#define XGBE_ACPI_DMA_FREQ "amd,dma-freq"
#define XGBE_ACPI_PTP_FREQ "amd,ptp-freq"
/* Timestamp support - values based on 50MHz PTP clock /* Timestamp support - values based on 50MHz PTP clock
* 50MHz => 20 nsec * 50MHz => 20 nsec
...@@ -361,8 +369,7 @@ struct xgbe_ring { ...@@ -361,8 +369,7 @@ struct xgbe_ring {
* cur - Tx: index of descriptor to be used for current transfer * cur - Tx: index of descriptor to be used for current transfer
* Rx: index of descriptor to check for packet availability * Rx: index of descriptor to check for packet availability
* dirty - Tx: index of descriptor to check for transfer complete * dirty - Tx: index of descriptor to check for transfer complete
* Rx: count of descriptors in which a packet has been received * Rx: index of descriptor to check for buffer reallocation
* (used with skb_realloc_index to refresh the ring)
*/ */
unsigned int cur; unsigned int cur;
unsigned int dirty; unsigned int dirty;
...@@ -377,11 +384,6 @@ struct xgbe_ring { ...@@ -377,11 +384,6 @@ struct xgbe_ring {
unsigned short cur_mss; unsigned short cur_mss;
unsigned short cur_vlan_ctag; unsigned short cur_vlan_ctag;
} tx; } tx;
struct {
unsigned int realloc_index;
unsigned int realloc_threshold;
} rx;
}; };
} ____cacheline_aligned; } ____cacheline_aligned;
...@@ -596,7 +598,8 @@ struct xgbe_desc_if { ...@@ -596,7 +598,8 @@ struct xgbe_desc_if {
int (*alloc_ring_resources)(struct xgbe_prv_data *); int (*alloc_ring_resources)(struct xgbe_prv_data *);
void (*free_ring_resources)(struct xgbe_prv_data *); void (*free_ring_resources)(struct xgbe_prv_data *);
int (*map_tx_skb)(struct xgbe_channel *, struct sk_buff *); int (*map_tx_skb)(struct xgbe_channel *, struct sk_buff *);
void (*realloc_rx_buffer)(struct xgbe_channel *); int (*map_rx_buffer)(struct xgbe_prv_data *, struct xgbe_ring *,
struct xgbe_ring_data *);
void (*unmap_rdata)(struct xgbe_prv_data *, struct xgbe_ring_data *); void (*unmap_rdata)(struct xgbe_prv_data *, struct xgbe_ring_data *);
void (*wrapper_tx_desc_init)(struct xgbe_prv_data *); void (*wrapper_tx_desc_init)(struct xgbe_prv_data *);
void (*wrapper_rx_desc_init)(struct xgbe_prv_data *); void (*wrapper_rx_desc_init)(struct xgbe_prv_data *);
...@@ -650,8 +653,12 @@ struct xgbe_hw_features { ...@@ -650,8 +653,12 @@ struct xgbe_hw_features {
struct xgbe_prv_data { struct xgbe_prv_data {
struct net_device *netdev; struct net_device *netdev;
struct platform_device *pdev; struct platform_device *pdev;
struct acpi_device *adev;
struct device *dev; struct device *dev;
/* ACPI or DT flag */
unsigned int use_acpi;
/* XGMAC/XPCS related mmio registers */ /* XGMAC/XPCS related mmio registers */
void __iomem *xgmac_regs; /* XGMAC CSRs */ void __iomem *xgmac_regs; /* XGMAC CSRs */
void __iomem *xpcs_regs; /* XPCS MMD registers */ void __iomem *xpcs_regs; /* XPCS MMD registers */
...@@ -672,6 +679,7 @@ struct xgbe_prv_data { ...@@ -672,6 +679,7 @@ struct xgbe_prv_data {
struct xgbe_desc_if desc_if; struct xgbe_desc_if desc_if;
/* AXI DMA settings */ /* AXI DMA settings */
unsigned int coherent;
unsigned int axdomain; unsigned int axdomain;
unsigned int arcache; unsigned int arcache;
unsigned int awcache; unsigned int awcache;
...@@ -739,6 +747,7 @@ struct xgbe_prv_data { ...@@ -739,6 +747,7 @@ struct xgbe_prv_data {
unsigned int phy_rx_pause; unsigned int phy_rx_pause;
/* Netdev related settings */ /* Netdev related settings */
unsigned char mac_addr[ETH_ALEN];
netdev_features_t netdev_features; netdev_features_t netdev_features;
struct napi_struct napi; struct napi_struct napi;
struct xgbe_mmc_stats mmc_stats; struct xgbe_mmc_stats mmc_stats;
...@@ -748,7 +757,9 @@ struct xgbe_prv_data { ...@@ -748,7 +757,9 @@ struct xgbe_prv_data {
/* Device clocks */ /* Device clocks */
struct clk *sysclk; struct clk *sysclk;
unsigned long sysclk_rate;
struct clk *ptpclk; struct clk *ptpclk;
unsigned long ptpclk_rate;
/* Timestamp support */ /* Timestamp support */
spinlock_t tstamp_lock; spinlock_t tstamp_lock;
......
...@@ -26,7 +26,7 @@ config AMD_PHY ...@@ -26,7 +26,7 @@ config AMD_PHY
config AMD_XGBE_PHY config AMD_XGBE_PHY
tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs" tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs"
depends on OF && HAS_IOMEM depends on (OF || ACPI) && HAS_IOMEM
---help--- ---help---
Currently supports the AMD 10GbE PHY Currently supports the AMD 10GbE PHY
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment