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

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

Merge branch 'amd-xgbe-next'



Tom Lendacky says:

====================
amd-xgbe: AMD XGBE driver updates 2015-03-19

The following series of patches includes functional updates and changes
to the driver.

- Use the phydev->advertising field instead of the phydev->supported
  field when configuring for auto-negotiation, etc.
- Use the phy_driver flags field for setting the transceiver type
  instead of hardcoding it in the ethtool support.
- Provide an auto-negotiation timeout check
- Clarify the Tx/Rx queue information messages
- Use the new DMA memory barrier operations
- Set the device DMA mask based on what the hardware reports
- Remove the software implementation of Tx coalescing
- Fix the reporting of the Rx coalescing value
- Use napi_alloc_skb when allocating an SKB in softirq

This patch series is based on net-next.

Changes from v2:
- Use jiffies instead of timespec for the auto-negotiation timeout check
- Remove the Rx path SKB allocation re-work patch since we should only
  inline the headers and the current code guards better against any
  hardware bugs

Changes from v1:
- Default to 32-bit DMA width (minimum supported) if hardware returns
  an unexpected DMA width value
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ebd6af09 385565a1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -365,6 +365,8 @@
#define MAC_HWF0R_TXCOESEL_WIDTH	1
#define MAC_HWF0R_VLHASH_INDEX		4
#define MAC_HWF0R_VLHASH_WIDTH		1
#define MAC_HWF1R_ADDR64_INDEX		14
#define MAC_HWF1R_ADDR64_WIDTH		2
#define MAC_HWF1R_ADVTHWORD_INDEX	13
#define MAC_HWF1R_ADVTHWORD_WIDTH	1
#define MAC_HWF1R_DBGMEMA_INDEX		19
+16 −12
Original line number Diff line number Diff line
@@ -1068,7 +1068,7 @@ static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata)
	rdesc->desc3 = 0;

	/* Make sure ownership is written to the descriptor */
	wmb();
	dma_wmb();
}

static void xgbe_tx_desc_init(struct xgbe_channel *channel)
@@ -1124,12 +1124,12 @@ static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
	 * is written to the descriptor(s) before setting the OWN bit
	 * for the descriptor
	 */
	wmb();
	dma_wmb();

	XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN, 1);

	/* Make sure ownership is written to the descriptor */
	wmb();
	dma_wmb();
}

static void xgbe_rx_desc_init(struct xgbe_channel *channel)
@@ -1358,18 +1358,20 @@ static void xgbe_tx_start_xmit(struct xgbe_channel *channel,
	struct xgbe_prv_data *pdata = channel->pdata;
	struct xgbe_ring_data *rdata;

	/* Make sure everything is written before the register write */
	wmb();

	/* Issue a poll command to Tx DMA by writing address
	 * of next immediate free descriptor */
	rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
	XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
			  lower_32_bits(rdata->rdesc_dma));

	/* Start the Tx coalescing timer */
	/* Start the Tx timer */
	if (pdata->tx_usecs && !channel->tx_timer_active) {
		channel->tx_timer_active = 1;
		hrtimer_start(&channel->tx_timer,
			      ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
			      HRTIMER_MODE_REL);
		mod_timer(&channel->tx_timer,
			  jiffies + usecs_to_jiffies(pdata->tx_usecs));
	}

	ring->tx.xmit_more = 0;
@@ -1565,7 +1567,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
	 * is written to the descriptor(s) before setting the OWN bit
	 * for the first descriptor
	 */
	wmb();
	dma_wmb();

	/* Set OWN bit for the first descriptor */
	rdata = XGBE_GET_DESC_DATA(ring, start_index);
@@ -1577,7 +1579,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
#endif

	/* Make sure ownership is written to the descriptor */
	wmb();
	dma_wmb();

	ring->cur = cur_index + 1;
	if (!packet->skb->xmit_more ||
@@ -1613,7 +1615,7 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
		return 1;

	/* Make sure descriptor fields are read after reading the OWN bit */
	rmb();
	dma_rmb();

#ifdef XGMAC_ENABLE_RX_DESC_DUMP
	xgbe_dump_rx_desc(ring, rdesc, ring->cur);
@@ -2004,7 +2006,8 @@ static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
	for (i = 0; i < pdata->tx_q_count; i++)
		XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, fifo_size);

	netdev_notice(pdata->netdev, "%d Tx queues, %d byte fifo per queue\n",
	netdev_notice(pdata->netdev,
		      "%d Tx hardware queues, %d byte fifo per queue\n",
		      pdata->tx_q_count, ((fifo_size + 1) * 256));
}

@@ -2019,7 +2022,8 @@ static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
	for (i = 0; i < pdata->rx_q_count; i++)
		XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, fifo_size);

	netdev_notice(pdata->netdev, "%d Rx queues, %d byte fifo per queue\n",
	netdev_notice(pdata->netdev,
		      "%d Rx hardware queues, %d byte fifo per queue\n",
		      pdata->rx_q_count, ((fifo_size + 1) * 256));
}

+29 −16
Original line number Diff line number Diff line
@@ -411,11 +411,9 @@ static irqreturn_t xgbe_dma_isr(int irq, void *data)
	return IRQ_HANDLED;
}

static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
static void xgbe_tx_timer(unsigned long data)
{
	struct xgbe_channel *channel = container_of(timer,
						    struct xgbe_channel,
						    tx_timer);
	struct xgbe_channel *channel = (struct xgbe_channel *)data;
	struct xgbe_prv_data *pdata = channel->pdata;
	struct napi_struct *napi;

@@ -437,8 +435,6 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
	channel->tx_timer_active = 0;

	DBGPR("<--xgbe_tx_timer\n");

	return HRTIMER_NORESTART;
}

static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
@@ -454,9 +450,8 @@ static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
			break;

		DBGPR("  %s adding tx timer\n", channel->name);
		hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
			     HRTIMER_MODE_REL);
		channel->tx_timer.function = xgbe_tx_timer;
		setup_timer(&channel->tx_timer, xgbe_tx_timer,
			    (unsigned long)channel);
	}

	DBGPR("<--xgbe_init_tx_timers\n");
@@ -475,8 +470,7 @@ static void xgbe_stop_tx_timers(struct xgbe_prv_data *pdata)
			break;

		DBGPR("  %s deleting tx timer\n", channel->name);
		channel->tx_timer_active = 0;
		hrtimer_cancel(&channel->tx_timer);
		del_timer_sync(&channel->tx_timer);
	}

	DBGPR("<--xgbe_stop_tx_timers\n");
@@ -519,6 +513,7 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
						RXFIFOSIZE);
	hw_feat->tx_fifo_size  = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
						TXFIFOSIZE);
	hw_feat->dma_width     = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
	hw_feat->dcb           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
	hw_feat->sph           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
	hw_feat->tso           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
@@ -553,6 +548,21 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
		break;
	}

	/* Translate the address width setting into actual number */
	switch (hw_feat->dma_width) {
	case 0:
		hw_feat->dma_width = 32;
		break;
	case 1:
		hw_feat->dma_width = 40;
		break;
	case 2:
		hw_feat->dma_width = 48;
		break;
	default:
		hw_feat->dma_width = 32;
	}

	/* The Queue, Channel and TC counts are zero based so increment them
	 * to get the actual number
	 */
@@ -692,6 +702,7 @@ void xgbe_init_rx_coalesce(struct xgbe_prv_data *pdata)
	DBGPR("-->xgbe_init_rx_coalesce\n");

	pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
	pdata->rx_usecs = XGMAC_INIT_DMA_RX_USECS;
	pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;

	hw_if->config_rx_coalesce(pdata);
@@ -1800,6 +1811,9 @@ static void xgbe_rx_refresh(struct xgbe_channel *channel)
		ring->dirty++;
	}

	/* Make sure everything is written before the register write */
	wmb();

	/* Update the Rx Tail Pointer Register with address of
	 * the last cleaned entry */
	rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
@@ -1807,16 +1821,15 @@ static void xgbe_rx_refresh(struct xgbe_channel *channel)
			  lower_32_bits(rdata->rdesc_dma));
}

static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
static struct sk_buff *xgbe_create_skb(struct napi_struct *napi,
				       struct xgbe_ring_data *rdata,
				       unsigned int *len)
{
	struct net_device *netdev = pdata->netdev;
	struct sk_buff *skb;
	u8 *packet;
	unsigned int copy_len;

	skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len);
	skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
	if (!skb)
		return NULL;

@@ -1863,7 +1876,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)

		/* Make sure descriptor fields are read after reading the OWN
		 * bit */
		rmb();
		dma_rmb();

#ifdef XGMAC_ENABLE_TX_DESC_DUMP
		xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
@@ -1986,7 +1999,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
							rdata->rx.hdr.dma_len,
							DMA_FROM_DEVICE);

				skb = xgbe_create_skb(pdata, rdata, &put_len);
				skb = xgbe_create_skb(napi, rdata, &put_len);
				if (!skb) {
					error = 1;
					goto skip_data;
+7 −12
Original line number Diff line number Diff line
@@ -291,7 +291,6 @@ static int xgbe_get_settings(struct net_device *netdev,
		return -ENODEV;

	ret = phy_ethtool_gset(pdata->phydev, cmd);
	cmd->transceiver = XCVR_EXTERNAL;

	DBGPR("<--xgbe_get_settings\n");

@@ -378,18 +377,14 @@ static int xgbe_get_coalesce(struct net_device *netdev,
			     struct ethtool_coalesce *ec)
{
	struct xgbe_prv_data *pdata = netdev_priv(netdev);
	struct xgbe_hw_if *hw_if = &pdata->hw_if;
	unsigned int riwt;

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

	memset(ec, 0, sizeof(struct ethtool_coalesce));

	riwt = pdata->rx_riwt;
	ec->rx_coalesce_usecs = hw_if->riwt_to_usec(pdata, riwt);
	ec->rx_coalesce_usecs = pdata->rx_usecs;
	ec->rx_max_coalesced_frames = pdata->rx_frames;

	ec->tx_coalesce_usecs = pdata->tx_usecs;
	ec->tx_max_coalesced_frames = pdata->tx_frames;

	DBGPR("<--xgbe_get_coalesce\n");
@@ -403,13 +398,14 @@ static int xgbe_set_coalesce(struct net_device *netdev,
	struct xgbe_prv_data *pdata = netdev_priv(netdev);
	struct xgbe_hw_if *hw_if = &pdata->hw_if;
	unsigned int rx_frames, rx_riwt, rx_usecs;
	unsigned int tx_frames, tx_usecs;
	unsigned int tx_frames;

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

	/* Check for not supported parameters  */
	if ((ec->rx_coalesce_usecs_irq) ||
	    (ec->rx_max_coalesced_frames_irq) ||
	    (ec->tx_coalesce_usecs) ||
	    (ec->tx_coalesce_usecs_irq) ||
	    (ec->tx_max_coalesced_frames_irq) ||
	    (ec->stats_block_coalesce_usecs) ||
@@ -439,17 +435,17 @@ static int xgbe_set_coalesce(struct net_device *netdev,
	}

	rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
	rx_usecs = ec->rx_coalesce_usecs;
	rx_frames = ec->rx_max_coalesced_frames;

	/* Use smallest possible value if conversion resulted in zero */
	if (ec->rx_coalesce_usecs && !rx_riwt)
	if (rx_usecs && !rx_riwt)
		rx_riwt = 1;

	/* Check the bounds of values for Rx */
	if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
		rx_usecs = hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT);
		netdev_alert(netdev, "rx-usec is limited to %d usecs\n",
			     rx_usecs);
			     hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
		return -EINVAL;
	}
	if (rx_frames > pdata->rx_desc_count) {
@@ -458,7 +454,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
		return -EINVAL;
	}

	tx_usecs = ec->tx_coalesce_usecs;
	tx_frames = ec->tx_max_coalesced_frames;

	/* Check the bounds of values for Tx */
@@ -469,10 +464,10 @@ static int xgbe_set_coalesce(struct net_device *netdev,
	}

	pdata->rx_riwt = rx_riwt;
	pdata->rx_usecs = rx_usecs;
	pdata->rx_frames = rx_frames;
	hw_if->config_rx_coalesce(pdata);

	pdata->tx_usecs = tx_usecs;
	pdata->tx_frames = tx_frames;
	hw_if->config_tx_coalesce(pdata);

+10 −9
Original line number Diff line number Diff line
@@ -374,15 +374,6 @@ static int xgbe_probe(struct platform_device *pdev)
		pdata->awcache = XGBE_DMA_SYS_AWCACHE;
	}

	/* Set the DMA mask */
	if (!dev->dma_mask)
		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);
	if (ret < 0) {
@@ -409,6 +400,16 @@ static int xgbe_probe(struct platform_device *pdev)
	/* Set default configuration data */
	xgbe_default_config(pdata);

	/* Set the DMA mask */
	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;
	ret = dma_set_mask_and_coherent(dev,
					DMA_BIT_MASK(pdata->hw_feat.dma_width));
	if (ret) {
		dev_err(dev, "dma_set_mask_and_coherent failed\n");
		goto err_io;
	}

	/* Calculate the number of Tx and Rx rings to be created
	 *  -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
	 *   the number of Tx queues to the number of Tx channels
Loading