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

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

Merge branch 'xgene-fixes'



Iyappan Subramanian says:

====================
drivers: net: xgene: Bug fixes

This patch set addresses the following bug fixes that were found during testing.

  1. IPv4 forward test crash
    - drivers: net: xgene: fix IPv4 forward crash

  2. Sharing of irqs
    - drivers: net: xgene: fix sharing of irqs

  3. Ununiform latency across queues
    - drivers: net: xgene: fix ununiform latency across queues

  4. Fix statistics counters race condition
    - drivers: net: xgene: fix statistics counters race condition

  5. Correcting register offset and field lengths
    - drivers: net: xgene: fix register offset

v2: Address review comments from v1
- Defer TSO fix, and reposting all other patches from v1

v1:
- Initial version
====================

Signed-off-by: default avatarIyappan Subramanian <isubramanian@apm.com>

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 72eec92a e2f2d9a7
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ static void xgene_cle_idt_to_hw(u32 dstqid, u32 fpsel,
static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
				  struct xgene_cle_dbptr *dbptr, u32 *buf)
{
	buf[0] = SET_VAL(CLE_DROP, dbptr->drop);
	buf[4] = SET_VAL(CLE_FPSEL, dbptr->fpsel) |
		 SET_VAL(CLE_DSTQIDL, dbptr->dstqid);

@@ -412,7 +413,7 @@ static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
			.branch = {
				{
					/* IPV4 */
					.valid = 0,
					.valid = 1,
					.next_packet_pointer = 22,
					.jump_bw = JMP_FW,
					.jump_rel = JMP_ABS,
@@ -420,7 +421,7 @@ static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
					.next_node = PKT_PROT_NODE,
					.next_branch = 0,
					.data = 0x8,
					.mask = 0xffff
					.mask = 0x0
				},
				{
					.valid = 0,
@@ -456,7 +457,7 @@ static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
					.next_node = RSS_IPV4_TCP_NODE,
					.next_branch = 0,
					.data = 0x0600,
					.mask = 0xffff
					.mask = 0x00ff
				},
				{
					/* UDP */
@@ -468,7 +469,7 @@ static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
					.next_node = RSS_IPV4_UDP_NODE,
					.next_branch = 0,
					.data = 0x1100,
					.mask = 0xffff
					.mask = 0x00ff
				},
				{
					.valid = 0,
@@ -642,7 +643,7 @@ static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
				{
					/* TCP DST Port */
					.valid = 0,
					.next_packet_pointer = 256,
					.next_packet_pointer = 258,
					.jump_bw = JMP_FW,
					.jump_rel = JMP_ABS,
					.operation = EQT,
+2 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@
#define CLE_TYPE_POS		0
#define CLE_TYPE_LEN		2

#define CLE_DROP_POS		28
#define CLE_DROP_LEN		1
#define CLE_DSTQIDL_POS		25
#define CLE_DSTQIDL_LEN		7
#define CLE_DSTQIDH_POS		0
+11 −8
Original line number Diff line number Diff line
@@ -219,27 +219,30 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
			    struct xgene_enet_pdata *pdata,
			    enum xgene_enet_err_code status)
{
	struct rtnl_link_stats64 *stats = &pdata->stats;

	switch (status) {
	case INGRESS_CRC:
		stats->rx_crc_errors++;
		ring->rx_crc_errors++;
		ring->rx_dropped++;
		break;
	case INGRESS_CHECKSUM:
	case INGRESS_CHECKSUM_COMPUTE:
		stats->rx_errors++;
		ring->rx_errors++;
		ring->rx_dropped++;
		break;
	case INGRESS_TRUNC_FRAME:
		stats->rx_frame_errors++;
		ring->rx_frame_errors++;
		ring->rx_dropped++;
		break;
	case INGRESS_PKT_LEN:
		stats->rx_length_errors++;
		ring->rx_length_errors++;
		ring->rx_dropped++;
		break;
	case INGRESS_PKT_UNDER:
		stats->rx_frame_errors++;
		ring->rx_frame_errors++;
		ring->rx_dropped++;
		break;
	case INGRESS_FIFO_OVERRUN:
		stats->rx_fifo_errors++;
		ring->rx_fifo_errors++;
		break;
	default:
		break;
+5 −3
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ enum xgene_enet_rm {
#define RINGADDRL_POS		5
#define RINGADDRL_LEN		27
#define RINGADDRH_POS		0
#define RINGADDRH_LEN		6
#define RINGADDRH_LEN		7
#define RINGSIZE_POS		23
#define RINGSIZE_LEN		3
#define RINGTYPE_POS		19
@@ -94,9 +94,9 @@ enum xgene_enet_rm {
#define RINGMODE_POS		20
#define RINGMODE_LEN		3
#define RECOMTIMEOUTL_POS	28
#define RECOMTIMEOUTL_LEN	3
#define RECOMTIMEOUTL_LEN	4
#define RECOMTIMEOUTH_POS	0
#define RECOMTIMEOUTH_LEN	2
#define RECOMTIMEOUTH_LEN	3
#define NUMMSGSINQ_POS		1
#define NUMMSGSINQ_LEN		16
#define ACCEPTLERR		BIT(19)
@@ -201,6 +201,8 @@ enum xgene_enet_rm {
#define USERINFO_LEN			32
#define FPQNUM_POS			32
#define FPQNUM_LEN			12
#define ELERR_POS                       46
#define ELERR_LEN                       2
#define NV_POS				50
#define NV_LEN				1
#define LL_POS				51
+55 −20
Original line number Diff line number Diff line
@@ -443,8 +443,8 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,

	skb_tx_timestamp(skb);

	pdata->stats.tx_packets++;
	pdata->stats.tx_bytes += skb->len;
	tx_ring->tx_packets++;
	tx_ring->tx_bytes += skb->len;

	pdata->ring_ops->wr_cmd(tx_ring, count);
	return NETDEV_TX_OK;
@@ -483,12 +483,12 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
	skb = buf_pool->rx_skb[skb_index];

	/* checking for error */
	status = GET_VAL(LERR, le64_to_cpu(raw_desc->m0));
	status = (GET_VAL(ELERR, le64_to_cpu(raw_desc->m0)) << LERR_LEN) ||
		  GET_VAL(LERR, le64_to_cpu(raw_desc->m0));
	if (unlikely(status > 2)) {
		dev_kfree_skb_any(skb);
		xgene_enet_parse_error(rx_ring, netdev_priv(rx_ring->ndev),
				       status);
		pdata->stats.rx_dropped++;
		ret = -EIO;
		goto out;
	}
@@ -506,8 +506,8 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
		xgene_enet_skip_csum(skb);
	}

	pdata->stats.rx_packets++;
	pdata->stats.rx_bytes += datalen;
	rx_ring->rx_packets++;
	rx_ring->rx_bytes += datalen;
	napi_gro_receive(&rx_ring->napi, skb);
out:
	if (--rx_ring->nbufpool == 0) {
@@ -630,7 +630,7 @@ static int xgene_enet_register_irq(struct net_device *ndev)
		ring = pdata->rx_ring[i];
		irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
		ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
				       IRQF_SHARED, ring->irq_name, ring);
				       0, ring->irq_name, ring);
		if (ret) {
			netdev_err(ndev, "Failed to request irq %s\n",
				   ring->irq_name);
@@ -641,7 +641,7 @@ static int xgene_enet_register_irq(struct net_device *ndev)
		ring = pdata->tx_ring[i]->cp_ring;
		irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
		ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
				       IRQF_SHARED, ring->irq_name, ring);
				       0, ring->irq_name, ring);
		if (ret) {
			netdev_err(ndev, "Failed to request irq %s\n",
				   ring->irq_name);
@@ -1114,12 +1114,31 @@ static struct rtnl_link_stats64 *xgene_enet_get_stats64(
{
	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
	struct rtnl_link_stats64 *stats = &pdata->stats;
	struct xgene_enet_desc_ring *ring;
	int i;

	stats->rx_errors += stats->rx_length_errors +
			    stats->rx_crc_errors +
			    stats->rx_frame_errors +
			    stats->rx_fifo_errors;
	memcpy(storage, &pdata->stats, sizeof(struct rtnl_link_stats64));
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
	for (i = 0; i < pdata->txq_cnt; i++) {
		ring = pdata->tx_ring[i];
		if (ring) {
			stats->tx_packets += ring->tx_packets;
			stats->tx_bytes += ring->tx_bytes;
		}
	}

	for (i = 0; i < pdata->rxq_cnt; i++) {
		ring = pdata->rx_ring[i];
		if (ring) {
			stats->rx_packets += ring->rx_packets;
			stats->rx_bytes += ring->rx_bytes;
			stats->rx_errors += ring->rx_length_errors +
				ring->rx_crc_errors +
				ring->rx_frame_errors +
				ring->rx_fifo_errors;
			stats->rx_dropped += ring->rx_dropped;
		}
	}
	memcpy(storage, stats, sizeof(struct rtnl_link_stats64));

	return storage;
}
@@ -1234,6 +1253,13 @@ static int xgene_enet_get_irqs(struct xgene_enet_pdata *pdata)
	for (i = 0; i < max_irqs; i++) {
		ret = platform_get_irq(pdev, i);
		if (ret <= 0) {
			if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
				max_irqs = i;
				pdata->rxq_cnt = max_irqs / 2;
				pdata->txq_cnt = max_irqs / 2;
				pdata->cq_cnt = max_irqs / 2;
				break;
			}
			dev_err(dev, "Unable to get ENET IRQ\n");
			ret = ret ? : -ENXIO;
			return ret;
@@ -1437,19 +1463,28 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
		pdata->port_ops = &xgene_xgport_ops;
		pdata->cle_ops = &xgene_cle3in_ops;
		pdata->rm = RM0;
		if (!pdata->rxq_cnt) {
			pdata->rxq_cnt = XGENE_NUM_RX_RING;
			pdata->txq_cnt = XGENE_NUM_TX_RING;
			pdata->cq_cnt = XGENE_NUM_TXC_RING;
		}
		break;
	}

	if (pdata->enet_id == XGENE_ENET1) {
		switch (pdata->port_id) {
		case 0:
			if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
				pdata->cpu_bufnum = X2_START_CPU_BUFNUM_0;
				pdata->eth_bufnum = X2_START_ETH_BUFNUM_0;
				pdata->bp_bufnum = X2_START_BP_BUFNUM_0;
				pdata->ring_num = START_RING_NUM_0;
			} else {
				pdata->cpu_bufnum = START_CPU_BUFNUM_0;
				pdata->eth_bufnum = START_ETH_BUFNUM_0;
				pdata->bp_bufnum = START_BP_BUFNUM_0;
				pdata->ring_num = START_RING_NUM_0;
			}
			break;
		case 1:
			if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
Loading