* [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12
@ 2016-02-12 14:32 Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode Tom Lendacky
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:32 UTC (permalink / raw)
To: netdev; +Cc: David Miller
The following updates and fixes are included in this driver update series:
- Disable VLAN filtering in promiscuous mode
- Change from using napi_complete to napi_complete_done
- Use __napi_schedule_irqoff when running in interrupt context
- Verify ethtool speed setting is valid for the selected speedset
- Enable PFC based on the pfc_en setting
- Fix the mapping of priorities to traffic classes
- Do traffic class setup when DCB nl callbacks are invoked
- Check Rx queue fifos before stopping Rx queue DMA
- Switch from disable_irq to masking interrupts for auto-negotiation
This patch series is based on net-next.
---
Tom Lendacky (9):
amd-xgbe: Disable VLAN filtering when in promiscuous mode
amd-xgbe: Change from napi_complete to napi_complete_done
amd-xgbe: Use __napi_schedule_irqoff
amd-xgbe: Verify forced speed matches the active speedset
amd-xgbe: Enable/disable PFC per traffic class
amd-xgbe: Fix the mapping of priorities to traffic classes
amd-xgbe: Do traffic class setup when called through dcbnl
amd-xgbe: Check Rx queue fifos before stopping Rx DMA
amd-xgbe: Mask auto-negotiation interrupts in ISR
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 10 -
drivers/net/ethernet/amd/xgbe/xgbe-dcb.c | 39 ++-
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 391 ++++++++++++++++----------
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 33 +-
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 16 +
drivers/net/ethernet/amd/xgbe/xgbe-main.c | 6
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 53 ++--
drivers/net/ethernet/amd/xgbe/xgbe.h | 11 -
8 files changed, 342 insertions(+), 217 deletions(-)
--
Tom Lendacky
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
@ 2016-02-12 14:32 ` Tom Lendacky
2016-02-17 1:19 ` David Miller
2016-02-12 14:32 ` [PATCH net-next v1 2/9] amd-xgbe: Change from napi_complete to napi_complete_done Tom Lendacky
` (7 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:32 UTC (permalink / raw)
To: netdev; +Cc: David Miller
When the hardware is placed in promiscuous mode it will still perform
VLAN filtering and therefore may not pass all packets to the driver.
Disable all VLAN filtering when entering promiscuous mode and restore
VLAN filtering upon exit from promiscuous mode. In order to avoid adding
forward declarations, move the VLAN related functions earlier in the
file.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 232 ++++++++++++++++--------------
1 file changed, 120 insertions(+), 112 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index f6a7161..f988392 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -702,6 +702,116 @@ static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata)
return 0;
}
+static int xgbe_enable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
+{
+ /* Put the VLAN tag in the Rx descriptor */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
+
+ /* Don't check the VLAN type */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
+
+ /* Check only C-TAG (0x8100) packets */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
+
+ /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
+
+ /* Enable VLAN tag stripping */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
+
+ return 0;
+}
+
+static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
+
+ return 0;
+}
+
+static int xgbe_enable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
+{
+ /* Enable VLAN filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
+
+ /* Enable VLAN Hash Table filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
+
+ /* Disable VLAN tag inverse matching */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
+
+ /* Only filter on the lower 12-bits of the VLAN tag */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
+
+ /* In order for the VLAN Hash Table filtering to be effective,
+ * the VLAN tag identifier in the VLAN Tag Register must not
+ * be zero. Set the VLAN tag identifier to "1" to enable the
+ * VLAN Hash Table filtering. This implies that a VLAN tag of
+ * 1 will always pass filtering.
+ */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
+
+ return 0;
+}
+
+static int xgbe_disable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
+{
+ /* Disable VLAN filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
+
+ return 0;
+}
+
+#ifndef CRCPOLY_LE
+#define CRCPOLY_LE 0xedb88320
+#endif
+static u32 xgbe_vid_crc32_le(__le16 vid_le)
+{
+ u32 poly = CRCPOLY_LE;
+ u32 crc = ~0;
+ u32 temp = 0;
+ unsigned char *data = (unsigned char *)&vid_le;
+ unsigned char data_byte = 0;
+ int i, bits;
+
+ bits = get_bitmask_order(VLAN_VID_MASK);
+ for (i = 0; i < bits; i++) {
+ if ((i % 8) == 0)
+ data_byte = data[i / 8];
+
+ temp = ((crc & 1) ^ data_byte) & 1;
+ crc >>= 1;
+ data_byte >>= 1;
+
+ if (temp)
+ crc ^= poly;
+ }
+
+ return crc;
+}
+
+static int xgbe_update_vlan_hash_table(struct xgbe_prv_data *pdata)
+{
+ u32 crc;
+ u16 vid;
+ __le16 vid_le;
+ u16 vlan_hash_table = 0;
+
+ /* Generate the VLAN Hash Table value */
+ for_each_set_bit(vid, pdata->active_vlans, VLAN_N_VID) {
+ /* Get the CRC32 value of the VLAN ID */
+ vid_le = cpu_to_le16(vid);
+ crc = bitrev32(~xgbe_vid_crc32_le(vid_le)) >> 28;
+
+ vlan_hash_table |= (1 << crc);
+ }
+
+ /* Set the VLAN Hash Table filtering register */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
+
+ return 0;
+}
+
static int xgbe_set_promiscuous_mode(struct xgbe_prv_data *pdata,
unsigned int enable)
{
@@ -714,6 +824,14 @@ static int xgbe_set_promiscuous_mode(struct xgbe_prv_data *pdata,
enable ? "entering" : "leaving");
XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, val);
+ /* Hardware will still perform VLAN filtering in promiscuous mode */
+ if (enable) {
+ xgbe_disable_rx_vlan_filtering(pdata);
+ } else {
+ if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+ xgbe_enable_rx_vlan_filtering(pdata);
+ }
+
return 0;
}
@@ -944,116 +1062,6 @@ static int xgbe_enable_rx_csum(struct xgbe_prv_data *pdata)
return 0;
}
-static int xgbe_enable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
-{
- /* Put the VLAN tag in the Rx descriptor */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
-
- /* Don't check the VLAN type */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
-
- /* Check only C-TAG (0x8100) packets */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
-
- /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
-
- /* Enable VLAN tag stripping */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
-
- return 0;
-}
-
-static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
-{
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
-
- return 0;
-}
-
-static int xgbe_enable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
-{
- /* Enable VLAN filtering */
- XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
-
- /* Enable VLAN Hash Table filtering */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
-
- /* Disable VLAN tag inverse matching */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
-
- /* Only filter on the lower 12-bits of the VLAN tag */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
-
- /* In order for the VLAN Hash Table filtering to be effective,
- * the VLAN tag identifier in the VLAN Tag Register must not
- * be zero. Set the VLAN tag identifier to "1" to enable the
- * VLAN Hash Table filtering. This implies that a VLAN tag of
- * 1 will always pass filtering.
- */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
-
- return 0;
-}
-
-static int xgbe_disable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
-{
- /* Disable VLAN filtering */
- XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
-
- return 0;
-}
-
-#ifndef CRCPOLY_LE
-#define CRCPOLY_LE 0xedb88320
-#endif
-static u32 xgbe_vid_crc32_le(__le16 vid_le)
-{
- u32 poly = CRCPOLY_LE;
- u32 crc = ~0;
- u32 temp = 0;
- unsigned char *data = (unsigned char *)&vid_le;
- unsigned char data_byte = 0;
- int i, bits;
-
- bits = get_bitmask_order(VLAN_VID_MASK);
- for (i = 0; i < bits; i++) {
- if ((i % 8) == 0)
- data_byte = data[i / 8];
-
- temp = ((crc & 1) ^ data_byte) & 1;
- crc >>= 1;
- data_byte >>= 1;
-
- if (temp)
- crc ^= poly;
- }
-
- return crc;
-}
-
-static int xgbe_update_vlan_hash_table(struct xgbe_prv_data *pdata)
-{
- u32 crc;
- u16 vid;
- __le16 vid_le;
- u16 vlan_hash_table = 0;
-
- /* Generate the VLAN Hash Table value */
- for_each_set_bit(vid, pdata->active_vlans, VLAN_N_VID) {
- /* Get the CRC32 value of the VLAN ID */
- vid_le = cpu_to_le16(vid);
- crc = bitrev32(~xgbe_vid_crc32_le(vid_le)) >> 28;
-
- vlan_hash_table |= (1 << crc);
- }
-
- /* Set the VLAN Hash Table filtering register */
- XGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
-
- return 0;
-}
-
static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata)
{
struct xgbe_ring_desc *rdesc = rdata->rdesc;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 2/9] amd-xgbe: Change from napi_complete to napi_complete_done
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode Tom Lendacky
@ 2016-02-12 14:32 ` Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 3/9] amd-xgbe: Use __napi_schedule_irqoff Tom Lendacky
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:32 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Change from using napi_complete to napi_complete_done to allow for the
use of gro_flush_timeout in tuning network processing.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 8a9b493..2aebbe2 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -2062,7 +2062,7 @@ static int xgbe_one_poll(struct napi_struct *napi, int budget)
/* If we processed everything, we are done */
if (processed < budget) {
/* Turn off polling */
- napi_complete(napi);
+ napi_complete_done(napi, processed);
/* Enable Tx and Rx interrupts */
enable_irq(channel->dma_irq);
@@ -2104,7 +2104,7 @@ static int xgbe_all_poll(struct napi_struct *napi, int budget)
/* If we processed everything, we are done */
if (processed < budget) {
/* Turn off polling */
- napi_complete(napi);
+ napi_complete_done(napi, processed);
/* Enable Tx and Rx interrupts */
xgbe_enable_rx_tx_ints(pdata);
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 3/9] amd-xgbe: Use __napi_schedule_irqoff
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 2/9] amd-xgbe: Change from napi_complete to napi_complete_done Tom Lendacky
@ 2016-02-12 14:32 ` Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 4/9] amd-xgbe: Verify forced speed matches the active speedset Tom Lendacky
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:32 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Change from calling __napi_schedule to __napi_schedule_irqoff when running
in interrupt context or when called by netpoll with interrupts already
disabled. The Tx timer function will continue to use __napi_schedule.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 2aebbe2..b0ff700 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -356,7 +356,7 @@ static irqreturn_t xgbe_isr(int irq, void *data)
xgbe_disable_rx_tx_ints(pdata);
/* Turn on polling */
- __napi_schedule(&pdata->napi);
+ __napi_schedule_irqoff(&pdata->napi);
}
}
@@ -409,7 +409,7 @@ static irqreturn_t xgbe_dma_isr(int irq, void *data)
disable_irq_nosync(channel->dma_irq);
/* Turn on polling */
- __napi_schedule(&channel->napi);
+ __napi_schedule_irqoff(&channel->napi);
}
return IRQ_HANDLED;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 4/9] amd-xgbe: Verify forced speed matches the active speedset
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (2 preceding siblings ...)
2016-02-12 14:32 ` [PATCH net-next v1 3/9] amd-xgbe: Use __napi_schedule_irqoff Tom Lendacky
@ 2016-02-12 14:32 ` Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 5/9] amd-xgbe: Enable/disable PFC per traffic class Tom Lendacky
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:32 UTC (permalink / raw)
To: netdev; +Cc: David Miller
When using ethtool to set the speed for the device, verify that the
specified speed is valid within the active speedset.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
index 6040293..11d9f0c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -318,8 +318,20 @@ static int xgbe_set_settings(struct net_device *netdev,
if (cmd->autoneg == AUTONEG_DISABLE) {
switch (speed) {
case SPEED_10000:
+ break;
case SPEED_2500:
+ if (pdata->speed_set != XGBE_SPEEDSET_2500_10000) {
+ netdev_err(netdev, "unsupported speed %u\n",
+ speed);
+ return -EINVAL;
+ }
+ break;
case SPEED_1000:
+ if (pdata->speed_set != XGBE_SPEEDSET_1000_10000) {
+ netdev_err(netdev, "unsupported speed %u\n",
+ speed);
+ return -EINVAL;
+ }
break;
default:
netdev_err(netdev, "unsupported speed %u\n", speed);
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 5/9] amd-xgbe: Enable/disable PFC per traffic class
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (3 preceding siblings ...)
2016-02-12 14:32 ` [PATCH net-next v1 4/9] amd-xgbe: Verify forced speed matches the active speedset Tom Lendacky
@ 2016-02-12 14:33 ` Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 6/9] amd-xgbe: Fix the mapping of priorities to traffic classes Tom Lendacky
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:33 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Currently the PFC flow control is enabled on all traffic classes if
one or more traffic classes request it. The PFC enable setting of the
traffic class should be used to determine whether to enable or disable
flow control for the traffic class.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 36 ++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index f988392..c1620c1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -518,13 +518,45 @@ static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
{
+ struct ieee_pfc *pfc = pdata->pfc;
+ struct ieee_ets *ets = pdata->ets;
unsigned int max_q_count, q_count;
unsigned int reg, reg_val;
unsigned int i;
/* Set MTL flow control */
- for (i = 0; i < pdata->rx_q_count; i++)
- XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 1);
+ for (i = 0; i < pdata->rx_q_count; i++) {
+ unsigned int ehfc = 0;
+
+ if (pfc && ets) {
+ unsigned int prio;
+
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) {
+ unsigned int tc;
+
+ /* Does this queue handle the priority? */
+ if (pdata->prio2q_map[prio] != i)
+ continue;
+
+ /* Get the Traffic Class for this priority */
+ tc = ets->prio_tc[prio];
+
+ /* Check if flow control should be enabled */
+ if (pfc->pfc_en & (1 << tc)) {
+ ehfc = 1;
+ break;
+ }
+ }
+ } else {
+ ehfc = 1;
+ }
+
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, ehfc);
+
+ netif_dbg(pdata, drv, pdata->netdev,
+ "flow control %s for RXq%u\n",
+ ehfc ? "enabled" : "disabled", i);
+ }
/* Set MAC flow control */
max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 6/9] amd-xgbe: Fix the mapping of priorities to traffic classes
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (4 preceding siblings ...)
2016-02-12 14:33 ` [PATCH net-next v1 5/9] amd-xgbe: Enable/disable PFC per traffic class Tom Lendacky
@ 2016-02-12 14:33 ` Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 7/9] amd-xgbe: Do traffic class setup when called through dcbnl Tom Lendacky
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:33 UTC (permalink / raw)
To: netdev; +Cc: David Miller
The driver is checking the pfc_en field of the ieee_pfc structure to
determine whether to associate a priority with a traffic class. This is
incorrect since the pfc_en field is for determining if PFC is enabled
for a traffic class.
The association of priority to traffic class does not depend on whether
the traffic class is enabled for PFC, so remove that check. Also, the
mapping of priorities to traffic classes should be done when configuring
the traffic classes and not the PFC support so move the priority to traffic
class association from xgbe_config_dcb_pfc to xgbe_config_dcb_tc.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 50 +++++++++++++-----------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index c1620c1..93661bc 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1332,7 +1332,8 @@ static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
{
struct ieee_ets *ets = pdata->ets;
unsigned int total_weight, min_weight, weight;
- unsigned int i;
+ unsigned int mask, reg, reg_val;
+ unsigned int i, prio;
if (!ets)
return;
@@ -1349,6 +1350,25 @@ static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
min_weight = 1;
for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
+ /* Map the priorities to the traffic class */
+ mask = 0;
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) {
+ if (ets->prio_tc[prio] == i)
+ mask |= (1 << prio);
+ }
+ mask &= 0xff;
+
+ netif_dbg(pdata, drv, pdata->netdev, "TC%u PRIO mask=%#x\n",
+ i, mask);
+ reg = MTL_TCPM0R + (MTL_TCPM_INC * (i / MTL_TCPM_TC_PER_REG));
+ reg_val = XGMAC_IOREAD(pdata, reg);
+
+ reg_val &= ~(0xff << ((i % MTL_TCPM_TC_PER_REG) << 3));
+ reg_val |= (mask << ((i % MTL_TCPM_TC_PER_REG) << 3));
+
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+
+ /* Set the traffic class algorithm */
switch (ets->tc_tsa[i]) {
case IEEE_8021QAZ_TSA_STRICT:
netif_dbg(pdata, drv, pdata->netdev,
@@ -1373,34 +1393,6 @@ static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata)
{
- struct ieee_pfc *pfc = pdata->pfc;
- struct ieee_ets *ets = pdata->ets;
- unsigned int mask, reg, reg_val;
- unsigned int tc, prio;
-
- if (!pfc || !ets)
- return;
-
- for (tc = 0; tc < pdata->hw_feat.tc_cnt; tc++) {
- mask = 0;
- for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) {
- if ((pfc->pfc_en & (1 << prio)) &&
- (ets->prio_tc[prio] == tc))
- mask |= (1 << prio);
- }
- mask &= 0xff;
-
- netif_dbg(pdata, drv, pdata->netdev, "TC%u PFC mask=%#x\n",
- tc, mask);
- reg = MTL_TCPM0R + (MTL_TCPM_INC * (tc / MTL_TCPM_TC_PER_REG));
- reg_val = XGMAC_IOREAD(pdata, reg);
-
- reg_val &= ~(0xff << ((tc % MTL_TCPM_TC_PER_REG) << 3));
- reg_val |= (mask << ((tc % MTL_TCPM_TC_PER_REG) << 3));
-
- XGMAC_IOWRITE(pdata, reg, reg_val);
- }
-
xgbe_config_flow_control(pdata);
}
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 7/9] amd-xgbe: Do traffic class setup when called through dcbnl
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (5 preceding siblings ...)
2016-02-12 14:33 ` [PATCH net-next v1 6/9] amd-xgbe: Fix the mapping of priorities to traffic classes Tom Lendacky
@ 2016-02-12 14:33 ` Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 8/9] amd-xgbe: Check Rx queue fifos before stopping Rx DMA Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 9/9] amd-xgbe: Mask auto-negotiation interrupts in ISR Tom Lendacky
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:33 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Currently the netdev traffic class setup is only performed when invoked
through the ndo_setup_tc interface. However, the same setup should be
performed when the dcbnl interface (ieee_setets) is invoked. Rework the
netdev traffic class setup to be invokable through either interface and
also provide the priority to traffic class mapping if available.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dcb.c | 39 ++++++++++++++++++++++--------
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 33 +++++++++++++++++++++++++
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 21 ++--------------
drivers/net/ethernet/amd/xgbe/xgbe.h | 6 +++--
4 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c b/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c
index a6b9899..895d356 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -146,6 +146,7 @@ static int xgbe_dcb_ieee_setets(struct net_device *netdev,
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
unsigned int i, tc_ets, tc_ets_weight;
+ u8 max_tc = 0;
tc_ets = 0;
tc_ets_weight = 0;
@@ -157,12 +158,9 @@ static int xgbe_dcb_ieee_setets(struct net_device *netdev,
netif_dbg(pdata, drv, netdev, "PRIO%u: TC=%hhu\n", i,
ets->prio_tc[i]);
- if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) &&
- (i >= pdata->hw_feat.tc_cnt))
- return -EINVAL;
-
- if (ets->prio_tc[i] >= pdata->hw_feat.tc_cnt)
- return -EINVAL;
+ max_tc = max_t(u8, max_tc, ets->prio_tc[i]);
+ if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]))
+ max_tc = max_t(u8, max_tc, i);
switch (ets->tc_tsa[i]) {
case IEEE_8021QAZ_TSA_STRICT:
@@ -171,15 +169,28 @@ static int xgbe_dcb_ieee_setets(struct net_device *netdev,
tc_ets = 1;
tc_ets_weight += ets->tc_tx_bw[i];
break;
-
default:
+ netif_err(pdata, drv, netdev,
+ "unsupported TSA algorithm (%hhu)\n",
+ ets->tc_tsa[i]);
return -EINVAL;
}
}
+ /* Check maximum traffic class requested */
+ if (max_tc >= pdata->hw_feat.tc_cnt) {
+ netif_err(pdata, drv, netdev,
+ "exceeded number of supported traffic classes\n");
+ return -EINVAL;
+ }
+
/* Weights must add up to 100% */
- if (tc_ets && (tc_ets_weight != 100))
+ if (tc_ets && (tc_ets_weight != 100)) {
+ netif_err(pdata, drv, netdev,
+ "sum of ETS algorithm weights is not 100 (%u)\n",
+ tc_ets_weight);
return -EINVAL;
+ }
if (!pdata->ets) {
pdata->ets = devm_kzalloc(pdata->dev, sizeof(*pdata->ets),
@@ -188,6 +199,7 @@ static int xgbe_dcb_ieee_setets(struct net_device *netdev,
return -ENOMEM;
}
+ pdata->num_tcs = max_tc + 1;
memcpy(pdata->ets, ets, sizeof(*pdata->ets));
pdata->hw_if.config_dcb_tc(pdata);
@@ -221,6 +233,13 @@ static int xgbe_dcb_ieee_setpfc(struct net_device *netdev,
"cap=%hhu, en=%#hhx, mbc=%hhu, delay=%hhu\n",
pfc->pfc_cap, pfc->pfc_en, pfc->mbc, pfc->delay);
+ /* Check PFC for supported number of traffic classes */
+ if (pfc->pfc_en & ~((1 << pdata->hw_feat.tc_cnt) - 1)) {
+ netif_err(pdata, drv, netdev,
+ "PFC requested for unsupported traffic class\n");
+ return -EINVAL;
+ }
+
if (!pdata->pfc) {
pdata->pfc = devm_kzalloc(pdata->dev, sizeof(*pdata->pfc),
GFP_KERNEL);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 93661bc..92bc031 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1328,6 +1328,36 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
return 0;
}
+static void xgbe_config_tc(struct xgbe_prv_data *pdata)
+{
+ unsigned int offset, queue, prio;
+ u8 i;
+
+ netdev_reset_tc(pdata->netdev);
+ if (!pdata->num_tcs)
+ return;
+
+ netdev_set_num_tc(pdata->netdev, pdata->num_tcs);
+
+ for (i = 0, queue = 0, offset = 0; i < pdata->num_tcs; i++) {
+ while ((queue < pdata->tx_q_count) &&
+ (pdata->q2tc_map[queue] == i))
+ queue++;
+
+ netif_dbg(pdata, drv, pdata->netdev, "TC%u using TXq%u-%u\n",
+ i, offset, queue - 1);
+ netdev_set_tc_queue(pdata->netdev, i, queue - offset, offset);
+ offset = queue;
+ }
+
+ if (!pdata->ets)
+ return;
+
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++)
+ netdev_set_prio_tc_map(pdata->netdev, prio,
+ pdata->ets->prio_tc[prio]);
+}
+
static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
{
struct ieee_ets *ets = pdata->ets;
@@ -1389,6 +1419,8 @@ static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
break;
}
}
+
+ xgbe_config_tc(pdata);
}
static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata)
@@ -2913,6 +2945,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
hw_if->get_tx_tstamp = xgbe_get_tx_tstamp;
/* For Data Center Bridging config */
+ hw_if->config_tc = xgbe_config_tc;
hw_if->config_dcb_tc = xgbe_config_dcb_tc;
hw_if->config_dcb_pfc = xgbe_config_dcb_pfc;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index b0ff700..fb0a5f0 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1629,27 +1629,12 @@ static void xgbe_poll_controller(struct net_device *netdev)
static int xgbe_setup_tc(struct net_device *netdev, u8 tc)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
- unsigned int offset, queue;
- u8 i;
- if (tc && (tc != pdata->hw_feat.tc_cnt))
+ if (tc > pdata->hw_feat.tc_cnt)
return -EINVAL;
- if (tc) {
- netdev_set_num_tc(netdev, tc);
- for (i = 0, queue = 0, offset = 0; i < tc; i++) {
- while ((queue < pdata->tx_q_count) &&
- (pdata->q2tc_map[queue] == i))
- queue++;
-
- netif_dbg(pdata, drv, netdev, "TC%u using TXq%u-%u\n",
- i, offset, queue - 1);
- netdev_set_tc_queue(netdev, i, queue - offset, offset);
- offset = queue;
- }
- } else {
- netdev_reset_tc(netdev);
- }
+ pdata->num_tcs = tc;
+ pdata->hw_if.config_tc(pdata);
return 0;
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index e234b99..ca28354 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -673,6 +673,7 @@ struct xgbe_hw_if {
u64 (*get_tx_tstamp)(struct xgbe_prv_data *);
/* For Data Center Bridging config */
+ void (*config_tc)(struct xgbe_prv_data *);
void (*config_dcb_tc)(struct xgbe_prv_data *);
void (*config_dcb_pfc)(struct xgbe_prv_data *);
@@ -880,6 +881,7 @@ struct xgbe_prv_data {
struct ieee_pfc *pfc;
unsigned int q2tc_map[XGBE_MAX_QUEUES];
unsigned int prio2q_map[IEEE_8021QAZ_MAX_TCS];
+ u8 num_tcs;
/* Hardware features of the device */
struct xgbe_hw_features hw_feat;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 8/9] amd-xgbe: Check Rx queue fifos before stopping Rx DMA
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (6 preceding siblings ...)
2016-02-12 14:33 ` [PATCH net-next v1 7/9] amd-xgbe: Do traffic class setup when called through dcbnl Tom Lendacky
@ 2016-02-12 14:33 ` Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 9/9] amd-xgbe: Mask auto-negotiation interrupts in ISR Tom Lendacky
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:33 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Check to be sure that the Rx queue fifos are empty before stopping the
Rx DMA channels.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 10 ++++++---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 30 +++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index b6fa891..bbef959 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -768,12 +768,16 @@
#define MTL_Q_TQDR 0x08
#define MTL_Q_RQOMR 0x40
#define MTL_Q_RQMPOCR 0x44
-#define MTL_Q_RQDR 0x4c
+#define MTL_Q_RQDR 0x48
#define MTL_Q_RQFCR 0x50
#define MTL_Q_IER 0x70
#define MTL_Q_ISR 0x74
/* MTL queue register entry bit positions and sizes */
+#define MTL_Q_RQDR_PRXQ_INDEX 16
+#define MTL_Q_RQDR_PRXQ_WIDTH 14
+#define MTL_Q_RQDR_RXQSTS_INDEX 4
+#define MTL_Q_RQDR_RXQSTS_WIDTH 2
#define MTL_Q_RQFCR_RFA_INDEX 1
#define MTL_Q_RQFCR_RFA_WIDTH 6
#define MTL_Q_RQFCR_RFD_INDEX 17
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 92bc031..c41cc50 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -2659,6 +2659,32 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
}
}
+static void xgbe_prepare_rx_stop(struct xgbe_prv_data *pdata,
+ unsigned int queue)
+{
+ unsigned int rx_status;
+ unsigned long rx_timeout;
+
+ /* The Rx engine cannot be stopped if it is actively processing
+ * packets. Wait for the Rx queue to empty the Rx fifo. Don't
+ * wait forever though...
+ */
+ rx_timeout = jiffies + (XGBE_DMA_STOP_TIMEOUT * HZ);
+ while (time_before(jiffies, rx_timeout)) {
+ rx_status = XGMAC_MTL_IOREAD(pdata, queue, MTL_Q_RQDR);
+ if ((XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, PRXQ) == 0) &&
+ (XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, RXQSTS) == 0))
+ break;
+
+ usleep_range(500, 1000);
+ }
+
+ if (!time_before(jiffies, rx_timeout))
+ netdev_info(pdata->netdev,
+ "timed out waiting for Rx queue %u to empty\n",
+ queue);
+}
+
static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
{
struct xgbe_channel *channel;
@@ -2697,6 +2723,10 @@ static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
+ /* Prepare for Rx DMA channel stop */
+ for (i = 0; i < pdata->rx_q_count; i++)
+ xgbe_prepare_rx_stop(pdata, i);
+
/* Disable each Rx queue */
XGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next v1 9/9] amd-xgbe: Mask auto-negotiation interrupts in ISR
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
` (7 preceding siblings ...)
2016-02-12 14:33 ` [PATCH net-next v1 8/9] amd-xgbe: Check Rx queue fifos before stopping Rx DMA Tom Lendacky
@ 2016-02-12 14:33 ` Tom Lendacky
8 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-12 14:33 UTC (permalink / raw)
To: netdev; +Cc: David Miller
Currently the auto-negotiation interrupt handling disables the irq
instead of masking off the interrupts. This was done because the phy
library was originally used to read and write the PCS registers, which
could not be performed in interrupt context. Now that the phy library is
no longer used to read and write the PCS registers the interrupts can be
masked off in the interrupt service routine eliminating the need to call
disable_irq/enable_irq. This also requires changing the protection mutex
to a spinlock.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 10 +++--
drivers/net/ethernet/amd/xgbe/xgbe-main.c | 6 ++-
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 53 ++++++++++++++++-------------
drivers/net/ethernet/amd/xgbe/xgbe.h | 5 ++-
4 files changed, 41 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index c41cc50..feb3fdd 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1025,6 +1025,7 @@ static int xgbe_config_rx_mode(struct xgbe_prv_data *pdata)
static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
int mmd_reg)
{
+ unsigned long flags;
unsigned int mmd_address;
int mmd_data;
@@ -1042,10 +1043,10 @@ static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
* register offsets must therefore be adjusted by left shifting the
* offset 2 bits and reading 32 bits of data.
*/
- mutex_lock(&pdata->xpcs_mutex);
+ spin_lock_irqsave(&pdata->xpcs_lock, flags);
XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
mmd_data = XPCS_IOREAD(pdata, (mmd_address & 0xff) << 2);
- mutex_unlock(&pdata->xpcs_mutex);
+ spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
return mmd_data;
}
@@ -1054,6 +1055,7 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
int mmd_reg, int mmd_data)
{
unsigned int mmd_address;
+ unsigned long flags;
if (mmd_reg & MII_ADDR_C45)
mmd_address = mmd_reg & ~MII_ADDR_C45;
@@ -1069,10 +1071,10 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
* register offsets must therefore be adjusted by left shifting the
* offset 2 bits and reading 32 bits of data.
*/
- mutex_lock(&pdata->xpcs_mutex);
+ spin_lock_irqsave(&pdata->xpcs_lock, flags);
XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
XPCS_IOWRITE(pdata, (mmd_address & 0xff) << 2, mmd_data);
- mutex_unlock(&pdata->xpcs_mutex);
+ spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
}
static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index 618d952..3eee320 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -363,7 +363,7 @@ static int xgbe_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, netdev);
spin_lock_init(&pdata->lock);
- mutex_init(&pdata->xpcs_mutex);
+ spin_lock_init(&pdata->xpcs_lock);
mutex_init(&pdata->rss_mutex);
spin_lock_init(&pdata->tstamp_lock);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
index 4460580..84c5d29 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
@@ -6,7 +6,7 @@
*
* License 1: GPLv2
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
*
* This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@
*
* License 2: Modified BSD
*
- * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -626,10 +626,22 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");
- /* Interrupt reason must be read and cleared outside of IRQ context */
- disable_irq_nosync(pdata->an_irq);
+ /* Disable AN interrupts */
+ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
+
+ /* Save the interrupt(s) that fired */
+ pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
- queue_work(pdata->an_workqueue, &pdata->an_irq_work);
+ if (pdata->an_int) {
+ /* Clear the interrupt(s) that fired and process them */
+ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
+
+ queue_work(pdata->an_workqueue, &pdata->an_irq_work);
+ } else {
+ /* Enable AN interrupts */
+ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
+ XGBE_AN_INT_MASK);
+ }
return IRQ_HANDLED;
}
@@ -673,34 +685,26 @@ static void xgbe_an_state_machine(struct work_struct *work)
struct xgbe_prv_data,
an_work);
enum xgbe_an cur_state = pdata->an_state;
- unsigned int int_reg, int_mask;
mutex_lock(&pdata->an_mutex);
- /* Read the interrupt */
- int_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
- if (!int_reg)
+ if (!pdata->an_int)
goto out;
next_int:
- if (int_reg & XGBE_AN_PG_RCV) {
+ if (pdata->an_int & XGBE_AN_PG_RCV) {
pdata->an_state = XGBE_AN_PAGE_RECEIVED;
- int_mask = XGBE_AN_PG_RCV;
- } else if (int_reg & XGBE_AN_INC_LINK) {
+ pdata->an_int &= ~XGBE_AN_PG_RCV;
+ } else if (pdata->an_int & XGBE_AN_INC_LINK) {
pdata->an_state = XGBE_AN_INCOMPAT_LINK;
- int_mask = XGBE_AN_INC_LINK;
- } else if (int_reg & XGBE_AN_INT_CMPLT) {
+ pdata->an_int &= ~XGBE_AN_INC_LINK;
+ } else if (pdata->an_int & XGBE_AN_INT_CMPLT) {
pdata->an_state = XGBE_AN_COMPLETE;
- int_mask = XGBE_AN_INT_CMPLT;
+ pdata->an_int &= ~XGBE_AN_INT_CMPLT;
} else {
pdata->an_state = XGBE_AN_ERROR;
- int_mask = 0;
}
- /* Clear the interrupt to be processed */
- int_reg &= ~int_mask;
- XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, int_reg);
-
pdata->an_result = pdata->an_state;
again:
@@ -740,14 +744,14 @@ again:
}
if (pdata->an_state == XGBE_AN_NO_LINK) {
- int_reg = 0;
+ pdata->an_int = 0;
XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
} else if (pdata->an_state == XGBE_AN_ERROR) {
netdev_err(pdata->netdev,
"error during auto-negotiation, state=%u\n",
cur_state);
- int_reg = 0;
+ pdata->an_int = 0;
XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
}
@@ -765,11 +769,12 @@ again:
if (cur_state != pdata->an_state)
goto again;
- if (int_reg)
+ if (pdata->an_int)
goto next_int;
out:
- enable_irq(pdata->an_irq);
+ /* Enable AN interrupts on the way out */
+ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_INT_MASK);
mutex_unlock(&pdata->an_mutex);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index ca28354..98d9d63 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -774,8 +774,8 @@ struct xgbe_prv_data {
/* Overall device lock */
spinlock_t lock;
- /* XPCS indirect addressing mutex */
- struct mutex xpcs_mutex;
+ /* XPCS indirect addressing lock */
+ spinlock_t xpcs_lock;
/* RSS addressing mutex */
struct mutex rss_mutex;
@@ -927,6 +927,7 @@ struct xgbe_prv_data {
u32 serdes_dfe_tap_ena[XGBE_SPEEDS];
/* Auto-negotiation state machine support */
+ unsigned int an_int;
struct mutex an_mutex;
enum xgbe_an an_result;
enum xgbe_an an_state;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode
2016-02-12 14:32 ` [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode Tom Lendacky
@ 2016-02-17 1:19 ` David Miller
2016-02-17 16:09 ` Tom Lendacky
0 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2016-02-17 1:19 UTC (permalink / raw)
To: thomas.lendacky; +Cc: netdev
From: Tom Lendacky <thomas.lendacky@amd.com>
Date: Fri, 12 Feb 2016 08:32:24 -0600
> +#ifndef CRCPOLY_LE
> +#define CRCPOLY_LE 0xedb88320
> +#endif
> +static u32 xgbe_vid_crc32_le(__le16 vid_le)
Please do not implement yet another copy of a CRC implementation.
Make use of the various versions the kernel provides already instead,
add Kconfig dependencies as needed.
Thanks.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode
2016-02-17 1:19 ` David Miller
@ 2016-02-17 16:09 ` Tom Lendacky
2016-02-17 16:31 ` David Miller
0 siblings, 1 reply; 14+ messages in thread
From: Tom Lendacky @ 2016-02-17 16:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On 02/16/2016 07:19 PM, David Miller wrote:
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Date: Fri, 12 Feb 2016 08:32:24 -0600
>
>> +#ifndef CRCPOLY_LE
>> +#define CRCPOLY_LE 0xedb88320
>> +#endif
>> +static u32 xgbe_vid_crc32_le(__le16 vid_le)
>
> Please do not implement yet another copy of a CRC implementation.
>
> Make use of the various versions the kernel provides already instead,
> add Kconfig dependencies as needed.
I can't use the existing kernel implementations because there aren't
any that support the 12-bit length of the VLAN VID (lengths are all
at the byte level). I created this function (back when I added VLAN
filtering support in 2014 - it's only being moved in this patch)
because of this 12-bit length.
I do use the kernel functions in other areas, I just can't use them
here.
Thanks,
Tom
>
> Thanks.
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode
2016-02-17 16:09 ` Tom Lendacky
@ 2016-02-17 16:31 ` David Miller
2016-02-17 16:35 ` Tom Lendacky
0 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2016-02-17 16:31 UTC (permalink / raw)
To: thomas.lendacky; +Cc: netdev
From: Tom Lendacky <thomas.lendacky@amd.com>
Date: Wed, 17 Feb 2016 10:09:34 -0600
> On 02/16/2016 07:19 PM, David Miller wrote:
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Date: Fri, 12 Feb 2016 08:32:24 -0600
>>
>>> +#ifndef CRCPOLY_LE
>>> +#define CRCPOLY_LE 0xedb88320
>>> +#endif
>>> +static u32 xgbe_vid_crc32_le(__le16 vid_le)
>>
>> Please do not implement yet another copy of a CRC implementation.
>>
>> Make use of the various versions the kernel provides already instead,
>> add Kconfig dependencies as needed.
>
> I can't use the existing kernel implementations because there aren't
> any that support the 12-bit length of the VLAN VID (lengths are all
> at the byte level). I created this function (back when I added VLAN
> filtering support in 2014 - it's only being moved in this patch)
> because of this 12-bit length.
>
> I do use the kernel functions in other areas, I just can't use them
> here.
This crummy ifdef looks terrible though, is it even needed?
Please remove it.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode
2016-02-17 16:31 ` David Miller
@ 2016-02-17 16:35 ` Tom Lendacky
0 siblings, 0 replies; 14+ messages in thread
From: Tom Lendacky @ 2016-02-17 16:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On 02/17/2016 10:31 AM, David Miller wrote:
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Date: Wed, 17 Feb 2016 10:09:34 -0600
>
>> On 02/16/2016 07:19 PM, David Miller wrote:
>>> From: Tom Lendacky <thomas.lendacky@amd.com>
>>> Date: Fri, 12 Feb 2016 08:32:24 -0600
>>>
>>>> +#ifndef CRCPOLY_LE
>>>> +#define CRCPOLY_LE 0xedb88320
>>>> +#endif
>>>> +static u32 xgbe_vid_crc32_le(__le16 vid_le)
>>>
>>> Please do not implement yet another copy of a CRC implementation.
>>>
>>> Make use of the various versions the kernel provides already instead,
>>> add Kconfig dependencies as needed.
>>
>> I can't use the existing kernel implementations because there aren't
>> any that support the 12-bit length of the VLAN VID (lengths are all
>> at the byte level). I created this function (back when I added VLAN
>> filtering support in 2014 - it's only being moved in this patch)
>> because of this 12-bit length.
>>
>> I do use the kernel functions in other areas, I just can't use them
>> here.
>
> This crummy ifdef looks terrible though, is it even needed?
I probably added it in case the #defines in the crc32defs.h were ever
made public.
>
> Please remove it.
Will do. I'll send out a v2 with the ifdef removed.
Thanks,
Tom
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-02-17 16:35 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-12 14:32 [PATCH net-next v1 0/9] amd-xgbe: AMD XGBE driver updates 2016-02-12 Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 1/9] amd-xgbe: Disable VLAN filtering when in promiscuous mode Tom Lendacky
2016-02-17 1:19 ` David Miller
2016-02-17 16:09 ` Tom Lendacky
2016-02-17 16:31 ` David Miller
2016-02-17 16:35 ` Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 2/9] amd-xgbe: Change from napi_complete to napi_complete_done Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 3/9] amd-xgbe: Use __napi_schedule_irqoff Tom Lendacky
2016-02-12 14:32 ` [PATCH net-next v1 4/9] amd-xgbe: Verify forced speed matches the active speedset Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 5/9] amd-xgbe: Enable/disable PFC per traffic class Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 6/9] amd-xgbe: Fix the mapping of priorities to traffic classes Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 7/9] amd-xgbe: Do traffic class setup when called through dcbnl Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 8/9] amd-xgbe: Check Rx queue fifos before stopping Rx DMA Tom Lendacky
2016-02-12 14:33 ` [PATCH net-next v1 9/9] amd-xgbe: Mask auto-negotiation interrupts in ISR Tom Lendacky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).