[PATCH v2 net-next] ionic: git_ts_info bit shifters

2021-04-13 Thread Shannon Nelson
All the uses of HWTSTAMP_FILTER_* values need to be
bit shifters, not straight values.

v2: fixed subject and added Cc Dan and SoB Allen

Fixes: f8ba81da73fc ("ionic: add ethtool support for PTP")
Cc: Dan Carpenter 
Signed-off-by: Shannon Nelson 
Signed-off-by: Allen Hubbe 
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 26 +--
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 71db1e2c7d8a..6583be570e45 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -888,55 +888,55 @@ static int ionic_get_ts_info(struct net_device *netdev,
 
mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_NTP_ALL;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_NTP_ALL);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
 
return 0;
 }
-- 
2.17.1



[PATCH] ionic: git_ts_info bit shifters

2021-04-13 Thread Shannon Nelson
All the uses of HWTSTAMP_FILTER_* values need to be
bit shifters, not straight values.

Fixes: f8ba81da73fc ("ionic: add ethtool support for PTP")
Signed-off-by: Shannon Nelson 
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 26 +--
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 71db1e2c7d8a..6583be570e45 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -888,55 +888,55 @@ static int ionic_get_ts_info(struct net_device *netdev,
 
mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_NTP_ALL;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_NTP_ALL);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_SYNC;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_SYNC);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
 
mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
-   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_EVENT;
+   info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
 
return 0;
 }
-- 
2.17.1



Re: [PATCH net-next] ionic: return -EFAULT if copy_to_user() fails

2021-04-13 Thread Shannon Nelson

On 4/13/21 3:47 AM, Dan Carpenter wrote:

The copy_to_user() function returns the number of bytes that it wasn't
able to copy.  We want to return -EFAULT to the user.

Fixes: fee6efce565d ("ionic: add hw timestamp support files")
Signed-off-by: Dan Carpenter 


Acked-by: Shannon Nelson 


---
  drivers/net/ethernet/pensando/ionic/ionic_phc.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c 
b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
index 86ae5011ac9b..d7d8d5e81ea0 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -225,7 +225,9 @@ int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct 
ifreq *ifr)
memcpy(&config, &lif->phc->ts_config, sizeof(config));
mutex_unlock(&lif->phc->config_lock);
  
-	return copy_to_user(ifr->ifr_data, &config, sizeof(config));

+   if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
+   return -EFAULT;
+   return 0;
  }
  
  static u64 ionic_hwstamp_read(struct ionic *ionic,




Re: [PATCH net-next 0/8] ionic: hwstamp tweaks

2021-04-12 Thread Shannon Nelson

On 4/11/21 8:38 AM, Richard Cochran wrote:

On Wed, Apr 07, 2021 at 04:19:53PM -0700, Shannon Nelson wrote:

A few little changes after review comments and
additional internal testing.

This series is a delta against the previously posted one.  Please
follow the process by re-basing your changes into the original series,
putting a "v2" into the Subject line, and adding a brief change log
into the cover letter.

Thanks,
Richard


If the original patches hadn't already been pulled into net-next, this 
is what I would have done.  My understanding is that once the patches 
have been pulled into the repo that we need to do delta patches, not new 
versions of the same patch, as folks don't normally like changing 
published tree history.


sln



[PATCH net-next 8/8] ionic: extend ts_config set locking

2021-04-07 Thread Shannon Nelson
Make sure the configuration is locked before
operating on it for the replay.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_phc.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c 
b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
index 2bb749097d9e..177dbf89affd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -79,6 +79,8 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif 
*lif,
if (!lif->phc || !lif->phc->ptp)
return -EOPNOTSUPP;
 
+   mutex_lock(&lif->phc->config_lock);
+
if (new_ts) {
config = new_ts;
} else {
@@ -96,12 +98,16 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif 
*lif,
}
 
tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
-   if (tx_mode < 0)
-   return tx_mode;
+   if (tx_mode < 0) {
+   err = tx_mode;
+   goto err_queues;
+   }
 
mask = cpu_to_le64(BIT_ULL(tx_mode));
-   if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
-   return -ERANGE;
+   if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) {
+   err = -ERANGE;
+   goto err_queues;
+   }
 
rx_filt = ionic_hwstamp_rx_filt(config->rx_filter);
rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
@@ -116,8 +122,6 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif 
*lif,
dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
config->rx_filter, rx_filt, rx_all);
 
-   mutex_lock(&lif->phc->config_lock);
-
if (tx_mode) {
err = ionic_lif_create_hwstamp_txq(lif);
if (err)
-- 
2.17.1



[PATCH net-next 7/8] ionic: add ts_config replay

2021-04-07 Thread Shannon Nelson
Split the call into ionic_lif_hwstamp_set() to have two
separate interfaces, one from the ioctl() for changing the
configuration and one for replaying the current configuration
after a FW RESET.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  2 +-
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  6 ++
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 84 ---
 3 files changed, 60 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index eae774c0a2d9..af3a5368529c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2993,7 +2993,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
 
/* restore the hardware timestamping queues */
-   ionic_lif_hwstamp_set(lif, NULL);
+   ionic_lif_hwstamp_replay(lif);
 
return;
 
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index ea3b086af179..346506f01715 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -302,6 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
 int ionic_lif_size(struct ionic *ionic);
 
 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
+int ionic_lif_hwstamp_replay(struct ionic_lif *lif);
 int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr);
 int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr);
 ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter);
@@ -310,6 +311,11 @@ void ionic_lif_unregister_phc(struct ionic_lif *lif);
 void ionic_lif_alloc_phc(struct ionic_lif *lif);
 void ionic_lif_free_phc(struct ionic_lif *lif);
 #else
+static inline int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq 
*ifr)
 {
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c 
b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
index 5d5da61284e7..2bb749097d9e 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -64,10 +64,12 @@ static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
}
 }
 
-int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
+  struct hwtstamp_config *new_ts)
 {
struct ionic *ionic = lif->ionic;
-   struct hwtstamp_config config;
+   struct hwtstamp_config *config;
+   struct hwtstamp_config ts;
int tx_mode = 0;
u64 rx_filt = 0;
int err, err2;
@@ -77,18 +79,23 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct 
ifreq *ifr)
if (!lif->phc || !lif->phc->ptp)
return -EOPNOTSUPP;
 
-   if (ifr) {
-   if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
-   return -EFAULT;
+   if (new_ts) {
+   config = new_ts;
} else {
-   /* if called with ifr == NULL, behave as if called with the
-* current ts_config from the initial cleared state.
+   /* If called with new_ts == NULL, replay the previous request
+* primarily for recovery after a FW_RESET.
+* We saved the previous configuration request info, so copy
+* the previous request for reference, clear the current state
+* to match the device's reset state, and run with it.
 */
-   memcpy(&config, &lif->phc->ts_config, sizeof(config));
-   memset(&lif->phc->ts_config, 0, sizeof(config));
+   config = &ts;
+   memcpy(config, &lif->phc->ts_config, sizeof(*config));
+   memset(&lif->phc->ts_config, 0, sizeof(lif->phc->ts_config));
+   lif->phc->ts_config_tx_mode = 0;
+   lif->phc->ts_config_rx_filt = 0;
}
 
-   tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
+   tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
if (tx_mode < 0)
return tx_mode;
 
@@ -96,18 +103,18 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct 
ifreq *ifr)
if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
return -ERANGE;
 
-   rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
-   rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
+   rx_filt = ionic_hwstamp_rx_filt(config->rx_filter);
+   rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;

[PATCH net-next 6/8] ionic: ignore EBUSY on queue start

2021-04-07 Thread Shannon Nelson
When starting the queues in the link-check, don't go into
the BROKEN state if the return was EBUSY.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 8cf6477b9899..eae774c0a2d9 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -135,7 +135,7 @@ static void ionic_link_status_check(struct ionic_lif *lif)
if (netdev->flags & IFF_UP && netif_running(netdev)) {
mutex_lock(&lif->queue_lock);
err = ionic_start_queues(lif);
-   if (err) {
+   if (err && err != -EBUSY) {
netdev_err(lif->netdev,
   "Failed to start queues: %d\n", err);
set_bit(IONIC_LIF_F_BROKEN, lif->state);
-- 
2.17.1



[PATCH net-next 5/8] ionic: re-start ptp after queues up

2021-04-07 Thread Shannon Nelson
When returning after a firmware reset, re-start the
PTP after we've restarted the general queues.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 4e22e50922cd..8cf6477b9899 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2987,14 +2987,14 @@ static void ionic_lif_handle_fw_up(struct ionic_lif 
*lif)
goto err_txrx_free;
}
 
-   /* restore the hardware timestamping queues */
-   ionic_lif_hwstamp_set(lif, NULL);
-
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
ionic_link_status_check_request(lif, CAN_SLEEP);
netif_device_attach(lif->netdev);
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
 
+   /* restore the hardware timestamping queues */
+   ionic_lif_hwstamp_set(lif, NULL);
+
return;
 
 err_txrx_free:
-- 
2.17.1



[PATCH net-next 4/8] ionic: add SKBTX_IN_PROGRESS

2021-04-07 Thread Shannon Nelson
Set the SKBTX_IN_PROGRESS when offloading the Tx timestamp.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 765050a5f7a8..08934888575c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1203,6 +1203,7 @@ static netdev_tx_t ionic_start_hwstamp_xmit(struct 
sk_buff *skb,
if (unlikely(!ionic_q_has_space(q, ndescs)))
goto err_out_drop;
 
+   skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP;
if (skb_is_gso(skb))
err = ionic_tx_tso(q, skb);
else
-- 
2.17.1



[PATCH net-next 3/8] ionic: check for valid tx_mode on SKBTX_HW_TSTAMP xmit

2021-04-07 Thread Shannon Nelson
Make sure the device is in a Tx offload mode before calling the
hwstamp offload xmit.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 3478b0f2495f..765050a5f7a8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1233,7 +1233,7 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct 
net_device *netdev)
}
 
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
-   if (lif->hwstamp_txq)
+   if (lif->hwstamp_txq && lif->phc->ts_config_tx_mode)
return ionic_start_hwstamp_xmit(skb, netdev);
 
if (unlikely(queue_index >= lif->nxqs))
-- 
2.17.1



[PATCH net-next 2/8] ionic: remove unnecessary compat ifdef

2021-04-07 Thread Shannon Nelson
We don't need to look for HAVE_HWSTAMP_TX_ONESTEP_P2P in the
upstream kernel.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_phc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c 
b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
index 86ae5011ac9b..5d5da61284e7 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -18,10 +18,8 @@ static int ionic_hwstamp_tx_mode(int config_tx_type)
return IONIC_TXSTAMP_ON;
case HWTSTAMP_TX_ONESTEP_SYNC:
return IONIC_TXSTAMP_ONESTEP_SYNC;
-#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
case HWTSTAMP_TX_ONESTEP_P2P:
return IONIC_TXSTAMP_ONESTEP_P2P;
-#endif
default:
return -ERANGE;
}
-- 
2.17.1



[PATCH net-next 0/8] ionic: hwstamp tweaks

2021-04-07 Thread Shannon Nelson
A few little changes after review comments and
additional internal testing.

Shannon Nelson (8):
  ionic: fix up a couple of code style nits
  ionic: remove unnecessary compat ifdef
  ionic: check for valid tx_mode on SKBTX_HW_TSTAMP xmit
  ionic: add SKBTX_IN_PROGRESS
  ionic: re-start ptp after queues up
  ionic: ignore EBUSY on queue start
  ionic: add ts_config replay
  ionic: extend ts_config set locking

 .../net/ethernet/pensando/ionic/ionic_lif.c   |  18 ++--
 .../net/ethernet/pensando/ionic/ionic_lif.h   |   6 ++
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 102 +++---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  |   3 +-
 4 files changed, 79 insertions(+), 50 deletions(-)

-- 
2.17.1



[PATCH net-next 1/8] ionic: fix up a couple of code style nits

2021-04-07 Thread Shannon Nelson
Clean up variable declarations.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index ee56fed12e07..4e22e50922cd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2015,9 +2015,8 @@ static void ionic_txrx_free(struct ionic_lif *lif)
 
 static int ionic_txrx_alloc(struct ionic_lif *lif)
 {
-   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
-   unsigned int flags;
-   unsigned int i;
+   unsigned int comp_sz, desc_sz, num_desc, sg_desc_sz;
+   unsigned int flags, i;
int err = 0;
 
num_desc = lif->ntxq_descs;
@@ -2584,12 +2583,11 @@ static void ionic_swap_queues(struct ionic_qcq *a, 
struct ionic_qcq *b)
 int ionic_reconfigure_queues(struct ionic_lif *lif,
 struct ionic_queue_params *qparam)
 {
-   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+   unsigned int comp_sz, desc_sz, num_desc, sg_desc_sz;
struct ionic_qcq **tx_qcqs = NULL;
struct ionic_qcq **rx_qcqs = NULL;
-   unsigned int flags;
+   unsigned int flags, i;
int err = -ENOMEM;
-   unsigned int i;
 
/* allocate temporary qcq arrays to hold new queue structs */
if (qparam->nxqs != lif->nxqs || qparam->ntxq_descs != lif->ntxq_descs) 
{
-- 
2.17.1



Re: [PATCH net-next 05/12] ionic: add hw timestamp support files

2021-04-06 Thread Shannon Nelson

On 4/6/21 5:27 PM, Richard Cochran wrote:

On Tue, Apr 06, 2021 at 04:18:00PM -0700, Shannon Nelson wrote:

On 4/5/21 11:17 AM, Richard Cochran wrote:

On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:

On 4/4/21 4:05 PM, Richard Cochran wrote:

This check is unneeded, because the ioctl layer never passes NULL here.

Yes, the ioctl layer never calls this with NULL, but we call it from within
the driver when we spin operations back up after a FW reset.

So why not avoid the special case and pass a proper request?

We do this because our firmware reset path is a special case that we have to
handle, and we do so by replaying the previous configuration request.
Passing the NULL request gives the code the ability to watch for this case
while keeping the special case handling simple: the code that drives the
replay logic doesn't need to know the hwstamp details, it just needs to
signal the replay and let the hwstamp code keep track of its own data and
request history.

I can update the comment to make that replay case more obvious.

No, please, I am asking you to provide a hwtstamp_config from your
driver.  What is so hard about that?



What I think you are asking is that we not extend the current assumption 
that *ifr will always be a useful pointer, a perfectly reasonable 
request.  Our ioctl() handler follows this as expected. It is our 
internal usage that might look like an extension.


We'd like to keep the replay related code and data to a minimum, and 
this current implementation is a simple way to do so, keeping the state 
and config info within the ptp side.


I suppose one alternative is that we pull the copy_from_user() bits into 
ionic_ioctl() and hand a hwtstamp_config struct pointer to 
ionic_lif_hwstamp_set().  In our reset case we can either hand a NULL 
pointer to ionic_lif_hwstamp_set() or add a reset parameter to the call 
where ionic_lif_hwstamp_set() simply won't inspect the hwtstamp_config 
pointer.


Another alternative would be to split the top layer of 
ionic_lif_hwstamp_set() into two different functions, one called by the 
ioctl handler with an *ifr, the other called by the fw reset logic 
without an *ifr, that both call into the remaining with a 
hwtstamp_config pointer.  This seems somewhat similar to the ixgbe approach.


Either way, in the end it seems like extra code to get to the same result.

sln



Re: [PATCH net-next 05/12] ionic: add hw timestamp support files

2021-04-06 Thread Shannon Nelson

On 4/5/21 11:17 AM, Richard Cochran wrote:

On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:

On 4/4/21 4:05 PM, Richard Cochran wrote:

This check is unneeded, because the ioctl layer never passes NULL here.

Yes, the ioctl layer never calls this with NULL, but we call it from within
the driver when we spin operations back up after a FW reset.

So why not avoid the special case and pass a proper request?


We do this because our firmware reset path is a special case that we 
have to handle, and we do so by replaying the previous configuration 
request.  Passing the NULL request gives the code the ability to watch 
for this case while keeping the special case handling simple: the code 
that drives the replay logic doesn't need to know the hwstamp details, 
it just needs to signal the replay and let the hwstamp code keep track 
of its own data and request history.


I can update the comment to make that replay case more obvious.

sln





Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling

2021-04-06 Thread Shannon Nelson

On 4/5/21 11:20 AM, Richard Cochran wrote:

On Mon, Apr 05, 2021 at 09:28:44AM -0700, Shannon Nelson wrote:

On 4/4/21 4:41 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:


@@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct 
net_device *netdev)
return NETDEV_TX_OK;
}
+   if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
+   if (lif->hwstamp_txq)
+   return ionic_start_hwstamp_xmit(skb, netdev);

The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.

Once the hwstamp queues are up, we leave them there for future use until the
interface is stopped,

Fine, but


assuming that the stack isn't going to send us
SKBTX_HW_STAMP after it has disabled the offload.

you can't assume that.  This is an important point, especially
considering the possibiliy of stacked HW time stamp providers.  I'm
working on a patch set that will allow the user to switch between MAC
and PHY time stamping at run time.

Thanks,
Richard


Interesting... I doubt that our particular MAC and PHY will ever be 
separate, but it makes sense to watch for this in the general case. I've 
got an update coming for this.


Thanks,
sln



Re: [PATCH net-next 12/12] ionic: advertise support for hardware timestamps

2021-04-05 Thread Shannon Nelson

On 4/4/21 4:43 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:10AM -0700, Shannon Nelson wrote:

Let the network stack know we've got support for timestamping
the packets.

Actually, you already advertised the support to user space in Patch 10,
so this present patch should go before that one (or together).

Thanks,
Richard


Yes, I supposed they could have gone together.  However, I believe that 
in a bisection this will only slightly confuse the user space tools, but 
won't cause any kernel pain.


sln



Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling

2021-04-05 Thread Shannon Nelson

On 4/4/21 4:41 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:


@@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct 
net_device *netdev)
return NETDEV_TX_OK;
}
  
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))

+   if (lif->hwstamp_txq)
+   return ionic_start_hwstamp_xmit(skb, netdev);

The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.


Once the hwstamp queues are up, we leave them there for future use until 
the interface is stopped, assuming that the stack isn't going to send us 
SKBTX_HW_STAMP after it has disabled the offload.




In addition, the code should set

skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

once the above tests pass.


I can add that in a followup patch.

Thanks,
sln



Thanks,
Richard






Re: [PATCH net-next 05/12] ionic: add hw timestamp support files

2021-04-05 Thread Shannon Nelson

On 4/4/21 4:21 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:


+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+   struct ionic *ionic = lif->ionic;
+   struct hwtstamp_config config;
+   int tx_mode = 0;
+   u64 rx_filt = 0;
+   int err, err2;
+   bool rx_all;
+   __le64 mask;
+
+   if (!lif->phc || !lif->phc->ptp)
+   return -EOPNOTSUPP;
+
+   if (ifr) {
+   if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+   return -EFAULT;
+   } else {
+   /* if called with ifr == NULL, behave as if called with the
+* current ts_config from the initial cleared state.
+*/
+   memcpy(&config, &lif->phc->ts_config, sizeof(config));
+   memset(&lif->phc->ts_config, 0, sizeof(config));
+   }
+
+   tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
+   if (tx_mode < 0)
+   return tx_mode;
+
+   mask = cpu_to_le64(BIT_ULL(tx_mode));
+   if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
+   return -ERANGE;
+
+   rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
+   rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
+
+   mask = cpu_to_le64(rx_filt);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
+   rx_filt = 0;
+   rx_all = true;
+   config.rx_filter = HWTSTAMP_FILTER_ALL;
+   }
+
+   dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
+   config.rx_filter, rx_filt, rx_all);
+
+   mutex_lock(&lif->phc->config_lock);
+
+   if (tx_mode) {
+   err = ionic_lif_create_hwstamp_txq(lif);

This function NDE yet.  It first appears in Patch #6.  Please make
sure each patch compiles.  That way, bisection always works.

Thanks,
Richard


This patch simply gets the file into the repo, it isn't yet mentioned in 
the Makefile so there is no broken compile.  This was just as a way of 
making patch 6 a little smaller.


sln



Re: [PATCH net-next 02/12] ionic: add handling of larger descriptors

2021-04-05 Thread Shannon Nelson

On 4/4/21 3:50 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:00AM -0700, Shannon Nelson wrote:

@@ -1722,11 +1722,15 @@ static void ionic_txrx_free(struct ionic_lif *lif)
  
  static int ionic_txrx_alloc(struct ionic_lif *lif)

  {
-   unsigned int sg_desc_sz;
+   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
unsigned int flags;
unsigned int i;

Coding Style nit: List of ints wants alphabetically order,
List can also fir 'flags' and 'i' with the others.


@@ -2246,9 +2258,9 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct 
ionic_qcq *b)
  int ionic_reconfigure_queues(struct ionic_lif *lif,
 struct ionic_queue_params *qparam)
  {
+   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
struct ionic_qcq **tx_qcqs = NULL;
struct ionic_qcq **rx_qcqs = NULL;
-   unsigned int sg_desc_sz;
unsigned int flags;

Ditto.

Thanks,
Richard


I can tweak this is a followup patch.  Thanks for your review time.
sln



Re: [PATCH net-next 05/12] ionic: add hw timestamp support files

2021-04-05 Thread Shannon Nelson

On 4/4/21 4:05 PM, Richard Cochran wrote:

On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:

@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
+
+#include 
+#include 
+
+#include "ionic.h"
+#include "ionic_bus.h"
+#include "ionic_lif.h"
+#include "ionic_ethtool.h"
+
+static int ionic_hwstamp_tx_mode(int config_tx_type)
+{
+   switch (config_tx_type) {
+   case HWTSTAMP_TX_OFF:
+   return IONIC_TXSTAMP_OFF;
+   case HWTSTAMP_TX_ON:
+   return IONIC_TXSTAMP_ON;
+   case HWTSTAMP_TX_ONESTEP_SYNC:
+   return IONIC_TXSTAMP_ONESTEP_SYNC;
+#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
+   case HWTSTAMP_TX_ONESTEP_P2P:
+   return IONIC_TXSTAMP_ONESTEP_P2P;
+#endif

This ifdef is not needed.  (I guess you have to support older kernel
versions, but my understanding of the policy is that new code
shouldn't carry such stuff).


Yep, good catch - that's a carry over from our out-of-tree driver. I'll 
follow up with a patch to remove that bit of cruft.





+   default:
+   return -ERANGE;
+   }
+}



+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+   struct ionic *ionic = lif->ionic;
+   struct hwtstamp_config config;
+   int tx_mode = 0;
+   u64 rx_filt = 0;
+   int err, err2;
+   bool rx_all;
+   __le64 mask;
+
+   if (!lif->phc || !lif->phc->ptp)
+   return -EOPNOTSUPP;
+
+   if (ifr) {
+   if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+   return -EFAULT;
+   } else {
+   /* if called with ifr == NULL, behave as if called with the
+* current ts_config from the initial cleared state.
+*/

This check is unneeded, because the ioctl layer never passes NULL here.


Yes, the ioctl layer never calls this with NULL, but we call it from 
within the driver when we spin operations back up after a FW reset.


Thanks,
sln




+   memcpy(&config, &lif->phc->ts_config, sizeof(config));
+   memset(&lif->phc->ts_config, 0, sizeof(config));
+   }

Thanks,
Richard




Re: [PATCH net-next 00/12] ionic: add PTP and hw clock support

2021-04-01 Thread Shannon Nelson

On 4/1/21 2:02 PM, Andrew Lunn wrote:

On Thu, Apr 01, 2021 at 10:55:58AM -0700, Shannon Nelson wrote:

This patchset adds support for accessing the DSC hardware clock and
for offloading PTP timestamping.

Hi Shannon

Please always Cc: the PTP maintainer for PTP patches.
Richard Cochran 

Andrew


Thanks for the heads-up, Andrew, I will do so on any followups.
sln



[PATCH net-next 12/12] ionic: advertise support for hardware timestamps

2021-04-01 Thread Shannon Nelson
Let the network stack know we've got support for timestamping
the packets.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 25 +++
 1 file changed, 25 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index e14c93fbbd68..ee56fed12e07 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1540,6 +1540,9 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
 
ctx.cmd.lif_setattr.features = ionic_netdev_features_to_nic(features);
 
+   if (lif->phc)
+   ctx.cmd.lif_setattr.features |= 
cpu_to_le64(IONIC_ETH_HW_TIMESTAMP);
+
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
@@ -1587,6 +1590,8 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
dev_dbg(dev, "feature ETH_HW_TSO_UDP\n");
if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
dev_dbg(dev, "feature ETH_HW_TSO_UDP_CSUM\n");
+   if (lif->hw_features & IONIC_ETH_HW_TIMESTAMP)
+   dev_dbg(dev, "feature ETH_HW_TIMESTAMP\n");
 
return 0;
 }
@@ -2260,6 +2265,20 @@ static int ionic_stop(struct net_device *netdev)
return 0;
 }
 
+static int ionic_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int 
cmd)
+{
+   struct ionic_lif *lif = netdev_priv(netdev);
+
+   switch (cmd) {
+   case SIOCSHWTSTAMP:
+   return ionic_lif_hwstamp_set(lif, ifr);
+   case SIOCGHWTSTAMP:
+   return ionic_lif_hwstamp_get(lif, ifr);
+   default:
+   return -EOPNOTSUPP;
+   }
+}
+
 static int ionic_get_vf_config(struct net_device *netdev,
   int vf, struct ifla_vf_info *ivf)
 {
@@ -2508,6 +2527,7 @@ static int ionic_set_vf_link_state(struct net_device 
*netdev, int vf, int set)
 static const struct net_device_ops ionic_netdev_ops = {
.ndo_open   = ionic_open,
.ndo_stop   = ionic_stop,
+   .ndo_do_ioctl   = ionic_do_ioctl,
.ndo_start_xmit = ionic_start_xmit,
.ndo_get_stats64= ionic_get_stats64,
.ndo_set_rx_mode= ionic_ndo_set_rx_mode,
@@ -3331,6 +3351,8 @@ int ionic_lif_register(struct ionic_lif *lif)
 {
int err;
 
+   ionic_lif_register_phc(lif);
+
INIT_WORK(&lif->ionic->nb_work, ionic_lif_notify_work);
 
lif->ionic->nb.notifier_call = ionic_lif_notify;
@@ -3343,6 +3365,7 @@ int ionic_lif_register(struct ionic_lif *lif)
err = register_netdev(lif->netdev);
if (err) {
dev_err(lif->ionic->dev, "Cannot register net device, 
aborting\n");
+   ionic_lif_unregister_phc(lif);
return err;
}
 
@@ -3364,6 +3387,8 @@ void ionic_lif_unregister(struct ionic_lif *lif)
if (lif->netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(lif->netdev);
 
+   ionic_lif_unregister_phc(lif);
+
lif->registered = false;
 }
 
-- 
2.17.1



[PATCH net-next 11/12] ionic: ethtool ptp stats

2021-04-01 Thread Shannon Nelson
Add the new hwstamp stats to our ethtool stats output.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_stats.c | 38 +--
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c 
b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
index ed9cf93d9acd..58a854666c62 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
@@ -130,6 +130,8 @@ static const struct ionic_stat_desc ionic_tx_stats_desc[] = 
{
IONIC_TX_STAT_DESC(frags),
IONIC_TX_STAT_DESC(tso),
IONIC_TX_STAT_DESC(tso_bytes),
+   IONIC_TX_STAT_DESC(hwstamp_valid),
+   IONIC_TX_STAT_DESC(hwstamp_invalid),
IONIC_TX_STAT_DESC(csum_none),
IONIC_TX_STAT_DESC(csum),
IONIC_TX_STAT_DESC(vlan_inserted),
@@ -143,6 +145,8 @@ static const struct ionic_stat_desc ionic_rx_stats_desc[] = 
{
IONIC_RX_STAT_DESC(csum_none),
IONIC_RX_STAT_DESC(csum_complete),
IONIC_RX_STAT_DESC(csum_error),
+   IONIC_RX_STAT_DESC(hwstamp_valid),
+   IONIC_RX_STAT_DESC(hwstamp_invalid),
IONIC_RX_STAT_DESC(dropped),
IONIC_RX_STAT_DESC(vlan_stripped),
 };
@@ -188,6 +192,8 @@ static void ionic_add_lif_txq_stats(struct ionic_lif *lif, 
int q_num,
stats->tx_tso_bytes += txstats->tso_bytes;
stats->tx_csum_none += txstats->csum_none;
stats->tx_csum += txstats->csum;
+   stats->tx_hwstamp_valid += txstats->hwstamp_valid;
+   stats->tx_hwstamp_invalid += txstats->hwstamp_invalid;
 }
 
 static void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num,
@@ -200,6 +206,8 @@ static void ionic_add_lif_rxq_stats(struct ionic_lif *lif, 
int q_num,
stats->rx_csum_none += rxstats->csum_none;
stats->rx_csum_complete += rxstats->csum_complete;
stats->rx_csum_error += rxstats->csum_error;
+   stats->rx_hwstamp_valid += rxstats->hwstamp_valid;
+   stats->rx_hwstamp_invalid += rxstats->hwstamp_invalid;
 }
 
 static void ionic_get_lif_stats(struct ionic_lif *lif,
@@ -215,6 +223,12 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
ionic_add_lif_rxq_stats(lif, q_num, stats);
}
 
+   if (lif->hwstamp_txq)
+   ionic_add_lif_txq_stats(lif, lif->hwstamp_txq->q.index, stats);
+
+   if (lif->hwstamp_rxq)
+   ionic_add_lif_rxq_stats(lif, lif->hwstamp_rxq->q.index, stats);
+
ionic_get_stats64(lif->netdev, &ns);
stats->hw_tx_dropped = ns.tx_dropped;
stats->hw_rx_dropped = ns.rx_dropped;
@@ -227,14 +241,18 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
 {
u64 total = 0, tx_queues = MAX_Q(lif), rx_queues = MAX_Q(lif);
 
-   /* lif stats */
+   if (lif->hwstamp_txq)
+   tx_queues += 1;
+
+   if (lif->hwstamp_rxq)
+   rx_queues += 1;
+
total += IONIC_NUM_LIF_STATS;
+   total += IONIC_NUM_PORT_STATS;
+
total += tx_queues * IONIC_NUM_TX_STATS;
total += rx_queues * IONIC_NUM_RX_STATS;
 
-   /* port stats */
-   total += IONIC_NUM_PORT_STATS;
-
if (test_bit(IONIC_LIF_F_UP, lif->state) &&
test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
/* tx debug stats */
@@ -318,8 +336,14 @@ static void ionic_sw_stats_get_strings(struct ionic_lif 
*lif, u8 **buf)
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
ionic_sw_stats_get_tx_strings(lif, buf, q_num);
 
+   if (lif->hwstamp_txq)
+   ionic_sw_stats_get_tx_strings(lif, buf, 
lif->hwstamp_txq->q.index);
+
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
ionic_sw_stats_get_rx_strings(lif, buf, q_num);
+
+   if (lif->hwstamp_rxq)
+   ionic_sw_stats_get_rx_strings(lif, buf, 
lif->hwstamp_rxq->q.index);
 }
 
 static void ionic_sw_stats_get_txq_values(struct ionic_lif *lif, u64 **buf,
@@ -434,8 +458,14 @@ static void ionic_sw_stats_get_values(struct ionic_lif 
*lif, u64 **buf)
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
ionic_sw_stats_get_txq_values(lif, buf, q_num);
 
+   if (lif->hwstamp_txq)
+   ionic_sw_stats_get_txq_values(lif, buf, 
lif->hwstamp_txq->q.index);
+
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
ionic_sw_stats_get_rxq_values(lif, buf, q_num);
+
+   if (lif->hwstamp_rxq)
+   ionic_sw_stats_get_rxq_values(lif, buf, 
lif->hwstamp_rxq->q.index);
 }
 
 const struct ionic_stats_group_intf ionic_stats_groups[] = {
-- 
2.17.1



[PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling

2021-04-01 Thread Shannon Nelson
The Tx and Rx timestamped packets are handled through separate
queues.  Here we set them up, service them, and tear them down
along with the normal Tx and Rx queues.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   2 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  51 ++-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 126 +++---
 .../net/ethernet/pensando/ionic/ionic_txrx.h  |   3 +
 4 files changed, 157 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 28994e01fa0a..c25cf9b744c5 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -220,11 +220,11 @@ struct ionic_queue {
unsigned int index;
unsigned int num_descs;
unsigned int max_sg_elems;
+   u64 features;
u64 dbell_count;
u64 stop;
u64 wake;
u64 drop;
-   u64 features;
struct ionic_dev *idev;
unsigned int type;
unsigned int hw_index;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 26c066ed74c4..e14c93fbbd68 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1145,9 +1145,12 @@ static int ionic_adminq_napi(struct napi_struct *napi, 
int budget)
struct ionic_dev *idev = &lif->ionic->idev;
unsigned long irqflags;
unsigned int flags = 0;
+   int rx_work = 0;
+   int tx_work = 0;
int n_work = 0;
int a_work = 0;
int work_done;
+   int credits;
 
if (lif->notifyqcq && lif->notifyqcq->flags & IONIC_QCQ_F_INITED)
n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
@@ -1159,7 +1162,15 @@ static int ionic_adminq_napi(struct napi_struct *napi, 
int budget)
  ionic_adminq_service, NULL, NULL);
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 
-   work_done = max(n_work, a_work);
+   if (lif->hwstamp_rxq)
+   rx_work = ionic_cq_service(&lif->hwstamp_rxq->cq, budget,
+  ionic_rx_service, NULL, NULL);
+
+   if (lif->hwstamp_txq)
+   tx_work = ionic_cq_service(&lif->hwstamp_txq->cq, budget,
+  ionic_tx_service, NULL, NULL);
+
+   work_done = max(max(n_work, a_work), max(rx_work, tx_work));
if (work_done < budget && napi_complete_done(napi, work_done)) {
flags |= IONIC_INTR_CRED_UNMASK;
intr->rearm_count++;
@@ -1167,9 +1178,8 @@ static int ionic_adminq_napi(struct napi_struct *napi, 
int budget)
 
if (work_done || flags) {
flags |= IONIC_INTR_CRED_RESET_COALESCE;
-   ionic_intr_credits(idev->intr_ctrl,
-  intr->index,
-  n_work + a_work, flags);
+   credits = n_work + a_work + rx_work + tx_work;
+   ionic_intr_credits(idev->intr_ctrl, intr->index, credits, 
flags);
}
 
return work_done;
@@ -1529,6 +1539,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
int err;
 
ctx.cmd.lif_setattr.features = ionic_netdev_features_to_nic(features);
+
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
@@ -1951,6 +1962,17 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
}
}
lif->rx_mode = 0;
+
+   if (lif->hwstamp_txq) {
+   ionic_lif_qcq_deinit(lif, lif->hwstamp_txq);
+   ionic_tx_flush(&lif->hwstamp_txq->cq);
+   ionic_tx_empty(&lif->hwstamp_txq->q);
+   }
+
+   if (lif->hwstamp_rxq) {
+   ionic_lif_qcq_deinit(lif, lif->hwstamp_rxq);
+   ionic_rx_empty(&lif->hwstamp_rxq->q);
+   }
 }
 
 static void ionic_txrx_free(struct ionic_lif *lif)
@@ -2122,8 +2144,26 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
}
}
 
+   if (lif->hwstamp_rxq) {
+   ionic_rx_fill(&lif->hwstamp_rxq->q);
+   err = ionic_qcq_enable(lif->hwstamp_rxq);
+   if (err)
+   goto err_out_hwstamp_rx;
+   }
+
+   if (lif->hwstamp_txq) {
+   err = ionic_qcq_enable(lif->hwstamp_txq);
+   if (err)
+   goto err_out_hwstamp_tx;
+   }
+
return 0;
 
+err_out_hwstamp_tx:
+   if (lif->hwstamp_rxq)
+   derr = ionic_qcq_disable(lif->hwstamp_rxq, (derr != 
-ETIMEDOUT));
+err_out_hwstamp_rx:
+   i = lif->n

[PATCH net-next 10/12] ionic: add ethtool support for PTP

2021-04-01 Thread Shannon Nelson
Add the get_ts_info() callback for ethtool support of
timestamping information.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 93 +++
 1 file changed, 93 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index b1e78b452fad..71db1e2c7d8a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -849,6 +849,98 @@ static int ionic_get_module_eeprom(struct net_device 
*netdev,
return 0;
 }
 
+static int ionic_get_ts_info(struct net_device *netdev,
+struct ethtool_ts_info *info)
+{
+   struct ionic_lif *lif = netdev_priv(netdev);
+   struct ionic *ionic = lif->ionic;
+   __le64 mask;
+
+   if (!lif->phc || !lif->phc->ptp)
+   return ethtool_op_get_ts_info(netdev, info);
+
+   info->phc_index = ptp_clock_index(lif->phc->ptp);
+
+   info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+   SOF_TIMESTAMPING_RX_SOFTWARE |
+   SOF_TIMESTAMPING_SOFTWARE |
+   SOF_TIMESTAMPING_TX_HARDWARE |
+   SOF_TIMESTAMPING_RX_HARDWARE |
+   SOF_TIMESTAMPING_RAW_HARDWARE;
+
+   /* tx modes */
+
+   info->tx_types = BIT(HWTSTAMP_TX_OFF) |
+BIT(HWTSTAMP_TX_ON);
+
+   mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_SYNC));
+   if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
+   info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC);
+
+   mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_P2P));
+   if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
+   info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_P2P);
+
+   /* rx filters */
+
+   info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+  BIT(HWTSTAMP_FILTER_ALL);
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_NTP_ALL;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_SYNC;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
+
+   mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+   info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_EVENT;
+
+   return 0;
+}
+
 static int ionic_nway_reset(struct net_device *netdev)
 {
struct ionic_lif *lif = netdev_priv(netdev);
@@ -906,6 +998,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {

[PATCH net-next 08/12] ionic: set up hw timestamp queues

2021-04-01 Thread Shannon Nelson
We do hardware timestamping through a separate Tx queue,
and optionally through a separate Rx queue.  These queues
are allocated, freed, and tracked separately from the basic
queue arrays.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 266 +-
 1 file changed, 261 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index ced80de4d92a..26c066ed74c4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -684,11 +684,11 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
if (!lif->rxqcqs)
goto err_out;
 
-   lif->txqstats = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif,
+   lif->txqstats = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif + 1,
 sizeof(*lif->txqstats), GFP_KERNEL);
if (!lif->txqstats)
goto err_out;
-   lif->rxqstats = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif,
+   lif->rxqstats = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif + 1,
 sizeof(*lif->rxqstats), GFP_KERNEL);
if (!lif->rxqstats)
goto err_out;
@@ -832,27 +832,250 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, 
struct ionic_qcq *qcq)
 
 int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
 {
+   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+   unsigned int txq_i, flags;
+   struct ionic_qcq *txq;
+   u64 features;
+   int err;
+
+   mutex_lock(&lif->queue_lock);
+
+   if (lif->hwstamp_txq)
+   goto out;
+
+   features = IONIC_Q_F_2X_CQ_DESC | IONIC_TXQ_F_HWSTAMP;
+
+   num_desc = IONIC_MIN_TXRX_DESC;
+   desc_sz = sizeof(struct ionic_txq_desc);
+   comp_sz = 2 * sizeof(struct ionic_txq_comp);
+
+   if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
+   lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz == sizeof(struct 
ionic_txq_sg_desc_v1))
+   sg_desc_sz = sizeof(struct ionic_txq_sg_desc_v1);
+   else
+   sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
+
+   txq_i = lif->ionic->ntxqs_per_lif;
+   flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
+
+   err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
+ num_desc, desc_sz, comp_sz, sg_desc_sz,
+ lif->kern_pid, &txq);
+   if (err)
+   goto err_qcq_alloc;
+
+   txq->q.features = features;
+
+   ionic_link_qcq_interrupts(lif->adminqcq, txq);
+   ionic_debugfs_add_qcq(lif, txq);
+
+   lif->hwstamp_txq = txq;
+
+   if (netif_running(lif->netdev)) {
+   err = ionic_lif_txq_init(lif, txq);
+   if (err)
+   goto err_qcq_init;
+
+   if (test_bit(IONIC_LIF_F_UP, lif->state)) {
+   err = ionic_qcq_enable(txq);
+   if (err)
+   goto err_qcq_enable;
+   }
+   }
+
+out:
+   mutex_unlock(&lif->queue_lock);
+
return 0;
+
+err_qcq_enable:
+   ionic_lif_qcq_deinit(lif, txq);
+err_qcq_init:
+   lif->hwstamp_txq = NULL;
+   ionic_debugfs_del_qcq(txq);
+   ionic_qcq_free(lif, txq);
+   devm_kfree(lif->ionic->dev, txq);
+err_qcq_alloc:
+   mutex_unlock(&lif->queue_lock);
+   return err;
 }
 
 int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
 {
+   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+   unsigned int rxq_i, flags;
+   struct ionic_qcq *rxq;
+   u64 features;
+   int err;
+
+   mutex_lock(&lif->queue_lock);
+
+   if (lif->hwstamp_rxq)
+   goto out;
+
+   features = IONIC_Q_F_2X_CQ_DESC | IONIC_RXQ_F_HWSTAMP;
+
+   num_desc = IONIC_MIN_TXRX_DESC;
+   desc_sz = sizeof(struct ionic_rxq_desc);
+   comp_sz = 2 * sizeof(struct ionic_rxq_comp);
+   sg_desc_sz = sizeof(struct ionic_rxq_sg_desc);
+
+   rxq_i = lif->ionic->nrxqs_per_lif;
+   flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG;
+
+   err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
+ num_desc, desc_sz, comp_sz, sg_desc_sz,
+ lif->kern_pid, &rxq);
+   if (err)
+   goto err_qcq_alloc;
+
+   rxq->q.features = features;
+
+   ionic_link_qcq_interrupts(lif->adminqcq, rxq);
+   ionic_debugfs_add_qcq(lif, rxq);
+
+   lif->hwstamp_rxq = rxq;
+
+   if (netif_running(lif->netdev)) {
+   err = ionic_lif_rxq_init(lif, rxq);
+   if (err)
+  

[PATCH net-next 00/12] ionic: add PTP and hw clock support

2021-04-01 Thread Shannon Nelson
This patchset adds support for accessing the DSC hardware clock and
for offloading PTP timestamping.

Tx packet timestamping happens through a separate Tx queue set up with
expanded completion descriptors that can report the timestamp.

Rx timestamping can happen either on all queues, or on a separate
timestamping queue when specific filtering is requested.  Again, the
timestamps are reported with the expanded completion descriptors.

The timestamping offload ability is advertised but not enabled until an
OS service asks for it.  At that time the driver's queues are reconfigured
to use the different completion descriptors and the private processing
queues as needed.

Reading the raw clock value comes through a new pair of values in the
device info registers in BAR0.  These high and low values are interpreted
with help from new clock mask, mult, and shift values in the device
identity information.

First we add the ability to detect new queue features, then the handling
of the new descriptor sizes.  After adding the new interface structures,
we start adding the support code, saving the advertising to the stack
for last.

Shannon Nelson (12):
  ionic: add new queue features to interface
  ionic: add handling of larger descriptors
  ionic: add hw timestamp structs to interface
  ionic: split adminq post and wait calls
  ionic: add hw timestamp support files
  ionic: link in the new hw timestamp code
  ionic: add rx filtering for hw timestamp steering
  ionic: set up hw timestamp queues
  ionic: add and enable tx and rx timestamp handling
  ionic: add ethtool support for PTP
  ionic: ethtool ptp stats
  ionic: advertise support for hardware timestamps

 drivers/net/ethernet/pensando/ionic/Makefile  |   1 +
 drivers/net/ethernet/pensando/ionic/ionic.h   |   6 +
 .../net/ethernet/pensando/ionic/ionic_dev.c   |   2 +
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   3 +
 .../ethernet/pensando/ionic/ionic_ethtool.c   |  93 +++
 .../net/ethernet/pensando/ionic/ionic_if.h| 214 ++-
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 439 -
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  75 +++
 .../net/ethernet/pensando/ionic/ionic_main.c  |  17 +-
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 589 ++
 .../ethernet/pensando/ionic/ionic_rx_filter.c |  21 +
 .../ethernet/pensando/ionic/ionic_rx_filter.h |   1 +
 .../net/ethernet/pensando/ionic/ionic_stats.c |  38 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 138 +++-
 .../net/ethernet/pensando/ionic/ionic_txrx.h  |   3 +
 15 files changed, 1565 insertions(+), 75 deletions(-)
 create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_phc.c

-- 
2.17.1



[PATCH net-next 07/12] ionic: add rx filtering for hw timestamp steering

2021-04-01 Thread Shannon Nelson
Add handling of the new Rx packet classification filter type.
This simple bit of classification allows for steering packets
to a separate Rx queue for processing.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../ethernet/pensando/ionic/ionic_rx_filter.c | 21 +++
 .../ethernet/pensando/ionic/ionic_rx_filter.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c 
b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
index cd0076fc3044..d71316d9ded2 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
@@ -140,6 +140,9 @@ int ionic_rx_filter_save(struct ionic_lif *lif, u32 
flow_id, u16 rxq_index,
case IONIC_RX_FILTER_MATCH_MAC_VLAN:
key = le16_to_cpu(ac->mac_vlan.vlan);
break;
+   case IONIC_RX_FILTER_STEER_PKTCLASS:
+   key = 0;
+   break;
default:
return -EINVAL;
}
@@ -210,3 +213,21 @@ struct ionic_rx_filter *ionic_rx_filter_by_addr(struct 
ionic_lif *lif,
 
return NULL;
 }
+
+struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif)
+{
+   struct ionic_rx_filter *f;
+   struct hlist_head *head;
+   unsigned int key;
+
+   key = hash_32(0, IONIC_RX_FILTER_HASH_BITS);
+   head = &lif->rx_filters.by_hash[key];
+
+   hlist_for_each_entry(f, head, by_hash) {
+   if (le16_to_cpu(f->cmd.match) != IONIC_RX_FILTER_STEER_PKTCLASS)
+   continue;
+   return f;
+   }
+
+   return NULL;
+}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h 
b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
index cf8f4c0a961c..1ead48be3c83 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
@@ -31,5 +31,6 @@ int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, 
u16 rxq_index,
 u32 hash, struct ionic_admin_ctx *ctx);
 struct ionic_rx_filter *ionic_rx_filter_by_vlan(struct ionic_lif *lif, u16 
vid);
 struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif, const 
u8 *addr);
+struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif);
 
 #endif /* _IONIC_RX_FILTER_H_ */
-- 
2.17.1



[PATCH net-next 06/12] ionic: link in the new hw timestamp code

2021-04-01 Thread Shannon Nelson
These are changes to compile and link the new code, but no
new feature support is available or advertised yet.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/Makefile  |  1 +
 drivers/net/ethernet/pensando/ionic/ionic.h   |  4 ++
 .../net/ethernet/pensando/ionic/ionic_dev.c   |  2 +
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 25 +++
 .../net/ethernet/pensando/ionic/ionic_lif.h   | 72 +++
 .../net/ethernet/pensando/ionic/ionic_main.c  |  2 +
 7 files changed, 107 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/Makefile 
b/drivers/net/ethernet/pensando/ionic/Makefile
index 8d3c2d3cb10d..4e7642a2d25f 100644
--- a/drivers/net/ethernet/pensando/ionic/Makefile
+++ b/drivers/net/ethernet/pensando/ionic/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_IONIC) := ionic.o
 ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o ionic_dev.o \
   ionic_debugfs.o ionic_lif.o ionic_rx_filter.o ionic_ethtool.o \
   ionic_txrx.o ionic_stats.o ionic_fw.o
+ionic-$(CONFIG_PTP_1588_CLOCK) += ionic_phc.o
diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h 
b/drivers/net/ethernet/pensando/ionic/ionic.h
index 18e92103c711..66204106f83e 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h
@@ -20,6 +20,10 @@ struct ionic_lif;
 
 #define DEVCMD_TIMEOUT  10
 
+#define IONIC_PHC_UPDATE_NS100 /* 10s in nanoseconds */
+#define NORMAL_PPB 10  /* one billion parts per 
billion */
+#define SCALED_PPM (100ull << 16)  /* 2^16 million parts per 
2^16 million */
+
 struct ionic_vf {
u16  index;
u8   macaddr[6];
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index 0e8e88c69e1c..1dfe962e22e0 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -79,6 +79,8 @@ int ionic_dev_setup(struct ionic *ionic)
idev->intr_status = bar->vaddr + IONIC_BAR0_INTR_STATUS_OFFSET;
idev->intr_ctrl = bar->vaddr + IONIC_BAR0_INTR_CTRL_OFFSET;
 
+   idev->hwstamp_regs = &idev->dev_info_regs->hwstamp;
+
sig = ioread32(&idev->dev_info_regs->signature);
if (sig != IONIC_DEV_INFO_SIGNATURE) {
dev_err(dev, "Incompatible firmware signature %x", sig);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 25c52c042246..28994e01fa0a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -136,6 +136,7 @@ struct ionic_devinfo {
 struct ionic_dev {
union ionic_dev_info_regs __iomem *dev_info_regs;
union ionic_dev_cmd_regs __iomem *dev_cmd_regs;
+   struct ionic_hwstamp_regs __iomem *hwstamp_regs;
 
atomic_long_t last_check_time;
unsigned long last_hb_time;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 9a61b2bbb652..ced80de4d92a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -830,6 +830,31 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, 
struct ionic_qcq *qcq)
return 0;
 }
 
+int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
+{
+   return 0;
+}
+
+int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
+{
+   return 0;
+}
+
+int ionic_lif_config_hwstamp_rxq_all(struct ionic_lif *lif, bool rx_all)
+{
+   return 0;
+}
+
+int ionic_lif_set_hwstamp_txmode(struct ionic_lif *lif, u16 txstamp_mode)
+{
+   return 0;
+}
+
+int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
+{
+   return 0;
+}
+
 static bool ionic_notifyq_service(struct ionic_cq *cq,
  struct ionic_cq_info *cq_info)
 {
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 93d3058aed77..ea3b086af179 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -4,6 +4,9 @@
 #ifndef _IONIC_LIF_H_
 #define _IONIC_LIF_H_
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include "ionic_rx_filter.h"
@@ -36,6 +39,8 @@ struct ionic_tx_stats {
u64 crc32_csum;
u64 sg_cntr[IONIC_MAX_NUM_SG_CNTR];
u64 dma_map_err;
+   u64 hwstamp_valid;
+   u64 hwstamp_invalid;
 };
 
 struct ionic_rx_stats {
@@ -49,6 +54,8 @@ struct ionic_rx_stats {
u64 csum_error;
u64 dma_map_err;
u64 alloc_err;
+   u64 hwstamp_valid;
+   u64 hwstamp_invalid;
 };
 
 #define IONIC_QCQ_F_INITED BIT(0)
@@ -125,6 +132,10 @@ struct ionic_lif_sw_s

[PATCH net-next 04/12] ionic: split adminq post and wait calls

2021-04-01 Thread Shannon Nelson
Split the wait part out of adminq_post_wait() into a separate
function so that a caller can have finer grain control over
the sequencing of operations and locking.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic.h  |  2 ++
 drivers/net/ethernet/pensando/ionic/ionic_main.c | 15 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h 
b/drivers/net/ethernet/pensando/ionic/ionic.h
index 084a924431d5..18e92103c711 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h
@@ -64,6 +64,8 @@ struct ionic_admin_ctx {
union ionic_adminq_comp comp;
 };
 
+int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
+int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, int 
err);
 int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
 int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
 int ionic_set_dma_mask(struct ionic *ionic);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c 
b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index c4b2906a2ae6..8c27fbe0e312 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
@@ -256,7 +256,7 @@ static void ionic_adminq_cb(struct ionic_queue *q,
complete_all(&ctx->work);
 }
 
-static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx 
*ctx)
+int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 {
struct ionic_desc_info *desc_info;
unsigned long irqflags;
@@ -295,14 +295,12 @@ static int ionic_adminq_post(struct ionic_lif *lif, 
struct ionic_admin_ctx *ctx)
return err;
 }
 
-int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
+int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, int 
err)
 {
struct net_device *netdev = lif->netdev;
unsigned long remaining;
const char *name;
-   int err;
 
-   err = ionic_adminq_post(lif, ctx);
if (err) {
if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
@@ -317,6 +315,15 @@ int ionic_adminq_post_wait(struct ionic_lif *lif, struct 
ionic_admin_ctx *ctx)
return ionic_adminq_check_err(lif, ctx, (remaining == 0));
 }
 
+int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
+{
+   int err;
+
+   err = ionic_adminq_post(lif, ctx);
+
+   return ionic_adminq_wait(lif, ctx, err);
+}
+
 static void ionic_dev_cmd_clean(struct ionic *ionic)
 {
union __iomem ionic_dev_cmd_regs *regs = ionic->idev.dev_cmd_regs;
-- 
2.17.1



[PATCH net-next 02/12] ionic: add handling of larger descriptors

2021-04-01 Thread Shannon Nelson
In preparating for hardware timestamping, we need to support
large Tx and Rx completion descriptors.  Here we add the new
queue feature ids and handling for the completion descriptor
sizes.

We only are adding support for the Rx 2x sized completion
descriptors in the general Rx queues for now as we will be
using it for PTP Rx support, and we don't have an immediate
use for the large descriptors in the general Tx queues yet;
it will be used in a special Tx queues added in one of the
next few patches.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_if.h| 12 +++
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 75 ---
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  3 +
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 12 ++-
 4 files changed, 73 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h 
b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 23043ce0a5d8..1299630fcde8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -354,12 +354,24 @@ enum ionic_logical_qtype {
  * @IONIC_QIDENT_F_SG:  Queue has scatter/gather ring
  * @IONIC_QIDENT_F_EQ:  Queue can use event queue
  * @IONIC_QIDENT_F_CMB: Queue is in cmb bar
+ * @IONIC_Q_F_2X_DESC:  Double main descriptor size
+ * @IONIC_Q_F_2X_CQ_DESC:   Double cq descriptor size
+ * @IONIC_Q_F_2X_SG_DESC:   Double sg descriptor size
+ * @IONIC_Q_F_4X_DESC:  Quadruple main descriptor size
+ * @IONIC_Q_F_4X_CQ_DESC:   Quadruple cq descriptor size
+ * @IONIC_Q_F_4X_SG_DESC:   Quadruple sg descriptor size
  */
 enum ionic_q_feature {
IONIC_QIDENT_F_CQ   = BIT_ULL(0),
IONIC_QIDENT_F_SG   = BIT_ULL(1),
IONIC_QIDENT_F_EQ   = BIT_ULL(2),
IONIC_QIDENT_F_CMB  = BIT_ULL(3),
+   IONIC_Q_F_2X_DESC   = BIT_ULL(4),
+   IONIC_Q_F_2X_CQ_DESC= BIT_ULL(5),
+   IONIC_Q_F_2X_SG_DESC= BIT_ULL(6),
+   IONIC_Q_F_4X_DESC   = BIT_ULL(7),
+   IONIC_Q_F_4X_CQ_DESC= BIT_ULL(8),
+   IONIC_Q_F_4X_SG_DESC= BIT_ULL(9),
 };
 
 /**
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 1b89549b243b..9a61b2bbb652 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1722,11 +1722,15 @@ static void ionic_txrx_free(struct ionic_lif *lif)
 
 static int ionic_txrx_alloc(struct ionic_lif *lif)
 {
-   unsigned int sg_desc_sz;
+   unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
unsigned int flags;
unsigned int i;
int err = 0;
 
+   num_desc = lif->ntxq_descs;
+   desc_sz = sizeof(struct ionic_txq_desc);
+   comp_sz = sizeof(struct ionic_txq_comp);
+
if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz ==
  sizeof(struct ionic_txq_sg_desc_v1))
@@ -1739,10 +1743,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
flags |= IONIC_QCQ_F_INTR;
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
- lif->ntxq_descs,
- sizeof(struct ionic_txq_desc),
- sizeof(struct ionic_txq_comp),
- sg_desc_sz,
+ num_desc, desc_sz, comp_sz, sg_desc_sz,
  lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
@@ -1759,16 +1760,24 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
}
 
flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG | IONIC_QCQ_F_INTR;
+
+   num_desc = lif->nrxq_descs;
+   desc_sz = sizeof(struct ionic_rxq_desc);
+   comp_sz = sizeof(struct ionic_rxq_comp);
+   sg_desc_sz = sizeof(struct ionic_rxq_sg_desc);
+
+   if (lif->rxq_features & IONIC_Q_F_2X_CQ_DESC)
+   comp_sz *= 2;
+
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
- lif->nrxq_descs,
- sizeof(struct ionic_rxq_desc),
- sizeof(struct ionic_rxq_comp),
- sizeof(struct ionic_rxq_sg_desc),
+ num_desc, desc_sz, comp_sz, sg_desc_sz,
  lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
 
+   lif-

[PATCH net-next 01/12] ionic: add new queue features to interface

2021-04-01 Thread Shannon Nelson
Add queue feature extensions to prepare for features that
can be queue specific, in addition to the general queue
features already defined.  While we're here, change the
existing feature ids from #defines to enum.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_if.h| 27 ++-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  3 +++
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 0c0533737b2b..68e5e7a97801 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -222,6 +222,7 @@ struct ionic_queue {
u64 stop;
u64 wake;
u64 drop;
+   u64 features;
struct ionic_dev *idev;
unsigned int type;
unsigned int hw_index;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h 
b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 88210142395d..23043ce0a5d8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -345,6 +345,23 @@ enum ionic_logical_qtype {
IONIC_QTYPE_MAX = 16,
 };
 
+/**
+ * enum ionic_q_feature - Common Features for most queue types
+ *
+ * Common features use bits 0-15. Per-queue-type features use higher bits.
+ *
+ * @IONIC_QIDENT_F_CQ:  Queue has completion ring
+ * @IONIC_QIDENT_F_SG:  Queue has scatter/gather ring
+ * @IONIC_QIDENT_F_EQ:  Queue can use event queue
+ * @IONIC_QIDENT_F_CMB: Queue is in cmb bar
+ */
+enum ionic_q_feature {
+   IONIC_QIDENT_F_CQ   = BIT_ULL(0),
+   IONIC_QIDENT_F_SG   = BIT_ULL(1),
+   IONIC_QIDENT_F_EQ   = BIT_ULL(2),
+   IONIC_QIDENT_F_CMB  = BIT_ULL(3),
+};
+
 /**
  * struct ionic_lif_logical_qtype - Descriptor of logical to HW queue type
  * @qtype:  Hardware Queue Type
@@ -529,7 +546,7 @@ struct ionic_q_identify_comp {
  * union ionic_q_identity - queue identity information
  * @version:Queue type version that can be used with FW
  * @supported:  Bitfield of queue versions, first bit = ver 0
- * @features:   Queue features
+ * @features:   Queue features (enum ionic_q_feature, etc)
  * @desc_sz:Descriptor size
  * @comp_sz:Completion descriptor size
  * @sg_desc_sz: Scatter/Gather descriptor size
@@ -541,10 +558,6 @@ union ionic_q_identity {
u8  version;
u8  supported;
u8  rsvd[6];
-#define IONIC_QIDENT_F_CQ  0x01/* queue has completion ring */
-#define IONIC_QIDENT_F_SG  0x02/* queue has scatter/gather ring */
-#define IONIC_QIDENT_F_EQ  0x04/* queue can use event queue */
-#define IONIC_QIDENT_F_CMB 0x08/* queue is in cmb bar */
__le64  features;
__le16  desc_sz;
__le16  comp_sz;
@@ -585,6 +598,7 @@ union ionic_q_identity {
  * @ring_base:Queue ring base address
  * @cq_ring_base: Completion queue ring base address
  * @sg_ring_base: Scatter/Gather ring base address
+ * @features: Mask of queue features to enable, if not in the flags above.
  */
 struct ionic_q_init_cmd {
u8 opcode;
@@ -608,7 +622,8 @@ struct ionic_q_init_cmd {
__le64 ring_base;
__le64 cq_ring_base;
__le64 sg_ring_base;
-   u8 rsvd2[20];
+   u8 rsvd2[12];
+   __le64 features;
 } __packed;
 
 /**
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a51be25723a5..1b89549b243b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -731,6 +731,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct 
ionic_qcq *qcq)
.ring_base = cpu_to_le64(q->base_pa),
.cq_ring_base = cpu_to_le64(cq->base_pa),
.sg_ring_base = cpu_to_le64(q->sg_base_pa),
+   .features = cpu_to_le64(q->features),
},
};
unsigned int intr_index;
@@ -791,6 +792,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct 
ionic_qcq *qcq)
.ring_base = cpu_to_le64(q->base_pa),
.cq_ring_base = cpu_to_le64(cq->base_pa),
.sg_ring_base = cpu_to_le64(q->sg_base_pa),
+   .features = cpu_to_le64(q->features),
},
};
int err;
@@ -2214,6 +2216,7 @@ static const struct net_device_ops ionic_netdev_ops = {
 static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 {
/* only swapping the queues, not the napi, flags, or other stuff 

[PATCH net-next 03/12] ionic: add hw timestamp structs to interface

2021-04-01 Thread Shannon Nelson
The interface for hardware timestamping includes a new FW
request, device identity fields, Tx and Rx queue feature bits, a
new Rx filter type, the beginnings of Rx packet classifications,
and hardware timestamp registers.

If the IONIC_ETH_HW_TIMESTAMP bit is shown in the
ionic_lif_config features bit string, then we have support
for the hw clock registers.  If the IONIC_RXQ_F_HWSTAMP and
IONIC_TXQ_F_HWSTAMP features are shown in the ionic_q_identity
features, then the queues can support HW timestamps on packets.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   1 +
 .../net/ethernet/pensando/ionic/ionic_if.h| 175 +-
 2 files changed, 170 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 68e5e7a97801..25c52c042246 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -59,6 +59,7 @@ static_assert(sizeof(struct ionic_dev_getattr_cmd) == 64);
 static_assert(sizeof(struct ionic_dev_getattr_comp) == 16);
 static_assert(sizeof(struct ionic_dev_setattr_cmd) == 64);
 static_assert(sizeof(struct ionic_dev_setattr_comp) == 16);
+static_assert(sizeof(struct ionic_lif_setphc_cmd) == 64);
 
 /* Port commands */
 static_assert(sizeof(struct ionic_port_identify_cmd) == 64);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h 
b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 1299630fcde8..0478b48d9895 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -34,6 +34,7 @@ enum ionic_cmd_opcode {
IONIC_CMD_LIF_RESET = 22,
IONIC_CMD_LIF_GETATTR   = 23,
IONIC_CMD_LIF_SETATTR   = 24,
+   IONIC_CMD_LIF_SETPHC= 25,
 
IONIC_CMD_RX_MODE_SET   = 30,
IONIC_CMD_RX_FILTER_ADD = 31,
@@ -269,6 +270,9 @@ union ionic_drv_identity {
  *value in usecs to device units using:
  *device units = usecs * mult / div
  * @eq_count: Number of shared event queues
+ * @hwstamp_mask: Bitmask for subtraction of hardware tick values.
+ * @hwstamp_mult: Hardware tick to nanosecond multiplier.
+ * @hwstamp_shift:Hardware tick to nanosecond divisor (power of two).
  */
 union ionic_dev_identity {
struct {
@@ -283,6 +287,9 @@ union ionic_dev_identity {
__le32 intr_coal_mult;
__le32 intr_coal_div;
__le32 eq_count;
+   __le64 hwstamp_mask;
+   __le32 hwstamp_mult;
+   __le32 hwstamp_shift;
};
__le32 words[478];
 };
@@ -374,6 +381,39 @@ enum ionic_q_feature {
IONIC_Q_F_4X_SG_DESC= BIT_ULL(9),
 };
 
+/**
+ * enum ionic_rxq_feature - RXQ-specific Features
+ *
+ * Per-queue-type features use bits 16 and higher.
+ *
+ * @IONIC_RXQ_F_HWSTAMP:   Queue supports Hardware Timestamping
+ */
+enum ionic_rxq_feature {
+   IONIC_RXQ_F_HWSTAMP = BIT_ULL(16),
+};
+
+/**
+ * enum ionic_txq_feature - TXQ-specific Features
+ *
+ * Per-queue-type features use bits 16 and higher.
+ *
+ * @IONIC_TXQ_F_HWSTAMP:   Queue supports Hardware Timestamping
+ */
+enum ionic_txq_feature {
+   IONIC_TXQ_F_HWSTAMP = BIT(16),
+};
+
+/**
+ * struct ionic_hwstamp_bits - Hardware timestamp decoding bits
+ * @IONIC_HWSTAMP_INVALID:  Invalid hardware timestamp value
+ * @IONIC_HWSTAMP_CQ_NEGOFFSET: Timestamp field negative offset
+ *  from the base cq descriptor.
+ */
+enum ionic_hwstamp_bits {
+   IONIC_HWSTAMP_INVALID   = ~0ull,
+   IONIC_HWSTAMP_CQ_NEGOFFSET  = 8,
+};
+
 /**
  * struct ionic_lif_logical_qtype - Descriptor of logical to HW queue type
  * @qtype:  Hardware Queue Type
@@ -434,6 +474,8 @@ union ionic_lif_config {
  * @max_mcast_filters:  Number of perfect multicast addresses supported
  * @min_frame_size: Minimum size of frames to be sent
  * @max_frame_size: Maximum size of frames to be sent
+ * @hwstamp_tx_modes:   Bitmask of BIT_ULL(enum ionic_txstamp_mode)
+ * @hwstamp_rx_filters: Bitmask of enum ionic_pkt_class
  * @config: LIF config struct with features, mtu, mac, q counts
  *
  * @rdma:RDMA identify structure
@@ -467,7 +509,10 @@ union ionic_lif_identity {
__le16 rss_ind_tbl_sz;
__le32 min_frame_size;
__le32 max_frame_size;
-   u8 rsvd2[106];
+   u8 rsvd2[2];
+   __le64 hwstamp_tx_modes;
+   __le64 hwstamp_rx_filters;
+   u8 rsvd3[88];
union ionic_lif_config config

[PATCH net-next 05/12] ionic: add hw timestamp support files

2021-04-01 Thread Shannon Nelson
This adds the file of code for supporting Tx and Rx hardware
timestamps and the raw clock interface, but does not yet link
it in for compiling or use.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 589 ++
 1 file changed, 589 insertions(+)
 create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_phc.c

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c 
b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
new file mode 100644
index ..86ae5011ac9b
--- /dev/null
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
+
+#include 
+#include 
+
+#include "ionic.h"
+#include "ionic_bus.h"
+#include "ionic_lif.h"
+#include "ionic_ethtool.h"
+
+static int ionic_hwstamp_tx_mode(int config_tx_type)
+{
+   switch (config_tx_type) {
+   case HWTSTAMP_TX_OFF:
+   return IONIC_TXSTAMP_OFF;
+   case HWTSTAMP_TX_ON:
+   return IONIC_TXSTAMP_ON;
+   case HWTSTAMP_TX_ONESTEP_SYNC:
+   return IONIC_TXSTAMP_ONESTEP_SYNC;
+#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
+   case HWTSTAMP_TX_ONESTEP_P2P:
+   return IONIC_TXSTAMP_ONESTEP_P2P;
+#endif
+   default:
+   return -ERANGE;
+   }
+}
+
+static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
+{
+   switch (config_rx_filter) {
+   case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+   return IONIC_PKT_CLS_PTP1_ALL;
+   case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+   return IONIC_PKT_CLS_PTP1_SYNC;
+   case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+   return IONIC_PKT_CLS_PTP1_SYNC | IONIC_PKT_CLS_PTP1_DREQ;
+
+   case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+   return IONIC_PKT_CLS_PTP2_L4_ALL;
+   case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+   return IONIC_PKT_CLS_PTP2_L4_SYNC;
+   case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+   return IONIC_PKT_CLS_PTP2_L4_SYNC | IONIC_PKT_CLS_PTP2_L4_DREQ;
+
+   case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+   return IONIC_PKT_CLS_PTP2_L2_ALL;
+   case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+   return IONIC_PKT_CLS_PTP2_L2_SYNC;
+   case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+   return IONIC_PKT_CLS_PTP2_L2_SYNC | IONIC_PKT_CLS_PTP2_L2_DREQ;
+
+   case HWTSTAMP_FILTER_PTP_V2_EVENT:
+   return IONIC_PKT_CLS_PTP2_ALL;
+   case HWTSTAMP_FILTER_PTP_V2_SYNC:
+   return IONIC_PKT_CLS_PTP2_SYNC;
+   case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+   return IONIC_PKT_CLS_PTP2_SYNC | IONIC_PKT_CLS_PTP2_DREQ;
+
+   case HWTSTAMP_FILTER_NTP_ALL:
+   return IONIC_PKT_CLS_NTP_ALL;
+
+   default:
+   return 0;
+   }
+}
+
+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+   struct ionic *ionic = lif->ionic;
+   struct hwtstamp_config config;
+   int tx_mode = 0;
+   u64 rx_filt = 0;
+   int err, err2;
+   bool rx_all;
+   __le64 mask;
+
+   if (!lif->phc || !lif->phc->ptp)
+   return -EOPNOTSUPP;
+
+   if (ifr) {
+   if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+   return -EFAULT;
+   } else {
+   /* if called with ifr == NULL, behave as if called with the
+* current ts_config from the initial cleared state.
+*/
+   memcpy(&config, &lif->phc->ts_config, sizeof(config));
+   memset(&lif->phc->ts_config, 0, sizeof(config));
+   }
+
+   tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
+   if (tx_mode < 0)
+   return tx_mode;
+
+   mask = cpu_to_le64(BIT_ULL(tx_mode));
+   if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
+   return -ERANGE;
+
+   rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
+   rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
+
+   mask = cpu_to_le64(rx_filt);
+   if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
+   rx_filt = 0;
+   rx_all = true;
+   config.rx_filter = HWTSTAMP_FILTER_ALL;
+   }
+
+   dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
+   config.rx_filter, rx_filt, rx_all);
+
+   mutex_lock(&lif->phc->config_lock);
+
+   if (tx_mode) {
+   err = ionic_lif_create_hwstamp_txq(lif);
+   if (err)
+   goto err_queues;
+   }
+
+   if (rx_filt) {
+   err = ionic_lif_create_hwstamp_rxq(lif);
+   if (err)
+   goto err_queues;
+   }
+
+   if (tx_mode != lif->phc->ts_

[PATCH net-next 4/4] ionic: pull per-q stats work out of queue loops

2021-03-30 Thread Shannon Nelson
Abstract out the per-queue data collection work into separate
functions from the per-queue loops in the stats reporting,
similar to what Alex did for the data label strings in
commit acebe5b6107c ("ionic: Update driver to use ethtool_sprintf")

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_stats.c | 219 ++
 1 file changed, 125 insertions(+), 94 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c 
b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
index 308b4ac6c57b..ed9cf93d9acd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
@@ -177,31 +177,42 @@ static const struct ionic_stat_desc 
ionic_dbg_napi_stats_desc[] = {
 
 #define MAX_Q(lif)   ((lif)->netdev->real_num_tx_queues)
 
+static void ionic_add_lif_txq_stats(struct ionic_lif *lif, int q_num,
+   struct ionic_lif_sw_stats *stats)
+{
+   struct ionic_tx_stats *txstats = &lif->txqstats[q_num];
+
+   stats->tx_packets += txstats->pkts;
+   stats->tx_bytes += txstats->bytes;
+   stats->tx_tso += txstats->tso;
+   stats->tx_tso_bytes += txstats->tso_bytes;
+   stats->tx_csum_none += txstats->csum_none;
+   stats->tx_csum += txstats->csum;
+}
+
+static void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num,
+   struct ionic_lif_sw_stats *stats)
+{
+   struct ionic_rx_stats *rxstats = &lif->rxqstats[q_num];
+
+   stats->rx_packets += rxstats->pkts;
+   stats->rx_bytes += rxstats->bytes;
+   stats->rx_csum_none += rxstats->csum_none;
+   stats->rx_csum_complete += rxstats->csum_complete;
+   stats->rx_csum_error += rxstats->csum_error;
+}
+
 static void ionic_get_lif_stats(struct ionic_lif *lif,
struct ionic_lif_sw_stats *stats)
 {
-   struct ionic_tx_stats *txstats;
-   struct ionic_rx_stats *rxstats;
struct rtnl_link_stats64 ns;
int q_num;
 
memset(stats, 0, sizeof(*stats));
 
for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
-   txstats = &lif->txqstats[q_num];
-   stats->tx_packets += txstats->pkts;
-   stats->tx_bytes += txstats->bytes;
-   stats->tx_tso += txstats->tso;
-   stats->tx_tso_bytes += txstats->tso_bytes;
-   stats->tx_csum_none += txstats->csum_none;
-   stats->tx_csum += txstats->csum;
-
-   rxstats = &lif->rxqstats[q_num];
-   stats->rx_packets += rxstats->pkts;
-   stats->rx_bytes += rxstats->bytes;
-   stats->rx_csum_none += rxstats->csum_none;
-   stats->rx_csum_complete += rxstats->csum_complete;
-   stats->rx_csum_error += rxstats->csum_error;
+   ionic_add_lif_txq_stats(lif, q_num, stats);
+   ionic_add_lif_rxq_stats(lif, q_num, stats);
}
 
ionic_get_stats64(lif->netdev, &ns);
@@ -214,16 +225,12 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
 
 static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
 {
-   u64 total = 0;
+   u64 total = 0, tx_queues = MAX_Q(lif), rx_queues = MAX_Q(lif);
 
/* lif stats */
total += IONIC_NUM_LIF_STATS;
-
-   /* tx stats */
-   total += MAX_Q(lif) * IONIC_NUM_TX_STATS;
-
-   /* rx stats */
-   total += MAX_Q(lif) * IONIC_NUM_RX_STATS;
+   total += tx_queues * IONIC_NUM_TX_STATS;
+   total += rx_queues * IONIC_NUM_RX_STATS;
 
/* port stats */
total += IONIC_NUM_PORT_STATS;
@@ -231,13 +238,13 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
if (test_bit(IONIC_LIF_F_UP, lif->state) &&
test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
/* tx debug stats */
-   total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
+   total += tx_queues * (IONIC_NUM_DBG_CQ_STATS +
  IONIC_NUM_TX_Q_STATS +
  IONIC_NUM_DBG_INTR_STATS +
  IONIC_MAX_NUM_SG_CNTR);
 
/* rx debug stats */
-   total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
+   total += rx_queues * (IONIC_NUM_DBG_CQ_STATS +
  IONIC_NUM_DBG_INTR_STATS +
  IONIC_NUM_DBG_NAPI_STATS +
  IONIC_MAX_NUM_NAPI_CNTR);
@@ -315,13 +322,99 @@ static void ionic_sw_stats_get_strings(struct ionic_lif 
*lif, u8 **buf)
ionic_sw_stats_get_rx_strings(lif, buf, q_num);
 }
 
+static void ionic_sw_stats_get_txq_values(struct ionic_lif *lif, u64 **buf,
+ 

[PATCH net-next 0/4] ionic: code cleanup for heartbeat, dma error counts, sizeof, stats

2021-03-30 Thread Shannon Nelson
These patches are a few more bits of code cleanup found in
testing and review: count all our dma error instances, make
better use of sizeof, fix a race in our device heartbeat check,
and clean up code formatting in the ethtool stats collection.

Shannon Nelson (4):
  ionic: count dma errors
  ionic: fix sizeof usage
  ionic: avoid races in ionic_heartbeat_check
  ionic: pull per-q stats work out of queue loops

 .../net/ethernet/pensando/ionic/ionic_dev.c   |  93 +---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   7 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |   8 +-
 .../net/ethernet/pensando/ionic/ionic_stats.c | 219 ++
 .../net/ethernet/pensando/ionic/ionic_txrx.c  |   9 +-
 5 files changed, 199 insertions(+), 137 deletions(-)

-- 
2.17.1



[PATCH net-next 1/4] ionic: count dma errors

2021-03-30 Thread Shannon Nelson
Increment our dma-error counter in a couple of spots
that were missed before.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 5985f7c504a9..42d29cd2ca47 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -609,6 +609,7 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct 
sk_buff *skb,
struct ionic_desc_info *desc_info)
 {
struct ionic_buf_info *buf_info = desc_info->bufs;
+   struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct device *dev = q->dev;
dma_addr_t dma_addr;
unsigned int nfrags;
@@ -616,8 +617,10 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct 
sk_buff *skb,
int frag_idx;
 
dma_addr = ionic_tx_map_single(q, skb->data, skb_headlen(skb));
-   if (dma_mapping_error(dev, dma_addr))
+   if (dma_mapping_error(dev, dma_addr)) {
+   stats->dma_map_err++;
return -EIO;
+   }
buf_info->dma_addr = dma_addr;
buf_info->len = skb_headlen(skb);
buf_info++;
@@ -626,8 +629,10 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct 
sk_buff *skb,
nfrags = skb_shinfo(skb)->nr_frags;
for (frag_idx = 0; frag_idx < nfrags; frag_idx++, frag++) {
dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag));
-   if (dma_mapping_error(dev, dma_addr))
+   if (dma_mapping_error(dev, dma_addr)) {
+   stats->dma_map_err++;
goto dma_fail;
+   }
buf_info->dma_addr = dma_addr;
buf_info->len = skb_frag_size(frag);
buf_info++;
-- 
2.17.1



[PATCH net-next 2/4] ionic: fix sizeof usage

2021-03-30 Thread Shannon Nelson
Use the actual pointer that we care about as the subject of the
sizeof, rather than a struct name.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 889d234e2ffa..a51be25723a5 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -676,20 +676,20 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
 
err = -ENOMEM;
lif->txqcqs = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif,
-  sizeof(struct ionic_qcq *), GFP_KERNEL);
+  sizeof(*lif->txqcqs), GFP_KERNEL);
if (!lif->txqcqs)
goto err_out;
lif->rxqcqs = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif,
-  sizeof(struct ionic_qcq *), GFP_KERNEL);
+  sizeof(*lif->rxqcqs), GFP_KERNEL);
if (!lif->rxqcqs)
goto err_out;
 
lif->txqstats = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif,
-sizeof(struct ionic_tx_stats), GFP_KERNEL);
+sizeof(*lif->txqstats), GFP_KERNEL);
if (!lif->txqstats)
goto err_out;
lif->rxqstats = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif,
-sizeof(struct ionic_rx_stats), GFP_KERNEL);
+sizeof(*lif->rxqstats), GFP_KERNEL);
if (!lif->rxqstats)
goto err_out;
 
-- 
2.17.1



[PATCH net-next 3/4] ionic: avoid races in ionic_heartbeat_check

2021-03-30 Thread Shannon Nelson
Rework the heartbeat checks to be sure that we're getting an
atomic operation.  Through testing we found occasions where a
separate thread could clash with this check and cause erroneous
heartbeat check results.

Signed-off-by: Allen Hubbe 
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.c   | 93 ---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  7 +-
 2 files changed, 63 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index 0532f7cf086d..0e8e88c69e1c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -24,6 +24,9 @@ static void ionic_watchdog_cb(struct timer_list *t)
return;
 
hb = ionic_heartbeat_check(ionic);
+   dev_dbg(ionic->dev, "%s: hb %d running %d UP %d\n",
+   __func__, hb, netif_running(lif->netdev),
+   test_bit(IONIC_LIF_F_UP, lif->state));
 
if (hb >= 0 &&
!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
@@ -91,9 +94,17 @@ int ionic_dev_setup(struct ionic *ionic)
return -EFAULT;
}
 
-   idev->last_fw_status = 0xff;
timer_setup(&ionic->watchdog_timer, ionic_watchdog_cb, 0);
ionic->watchdog_period = IONIC_WATCHDOG_SECS * HZ;
+
+   /* set times to ensure the first check will proceed */
+   atomic_long_set(&idev->last_check_time, jiffies - 2 * HZ);
+   idev->last_hb_time = jiffies - 2 * ionic->watchdog_period;
+   /* init as ready, so no transition if the first check succeeds */
+   idev->last_fw_hb = 0;
+   idev->fw_hb_ready = true;
+   idev->fw_status_ready = true;
+
mod_timer(&ionic->watchdog_timer,
  round_jiffies(jiffies + ionic->watchdog_period));
 
@@ -107,29 +118,38 @@ int ionic_dev_setup(struct ionic *ionic)
 int ionic_heartbeat_check(struct ionic *ionic)
 {
struct ionic_dev *idev = &ionic->idev;
-   unsigned long hb_time;
+   unsigned long check_time, last_check_time;
+   bool fw_status_ready, fw_hb_ready;
u8 fw_status;
-   u32 hb;
+   u32 fw_hb;
 
-   /* wait a little more than one second before testing again */
-   hb_time = jiffies;
-   if (time_before(hb_time, (idev->last_hb_time + ionic->watchdog_period)))
+   /* wait a least one second before testing again */
+   check_time = jiffies;
+   last_check_time = atomic_long_read(&idev->last_check_time);
+do_check_time:
+   if (time_before(check_time, last_check_time + HZ))
return 0;
+   if (!atomic_long_try_cmpxchg_relaxed(&idev->last_check_time,
+&last_check_time, check_time)) {
+   /* if called concurrently, only the first should proceed. */
+   dev_dbg(ionic->dev, "%s: do_check_time again\n", __func__);
+   goto do_check_time;
+   }
 
/* firmware is useful only if the running bit is set and
 * fw_status != 0xff (bad PCI read)
 */
fw_status = ioread8(&idev->dev_info_regs->fw_status);
-   if (fw_status != 0xff)
-   fw_status &= IONIC_FW_STS_F_RUNNING;  /* use only the run bit */
+   fw_status_ready = (fw_status != 0xff) && (fw_status & 
IONIC_FW_STS_F_RUNNING);
 
/* is this a transition? */
-   if (fw_status != idev->last_fw_status &&
-   idev->last_fw_status != 0xff) {
+   if (fw_status_ready != idev->fw_status_ready) {
struct ionic_lif *lif = ionic->lif;
bool trigger = false;
 
-   if (!fw_status || fw_status == 0xff) {
+   idev->fw_status_ready = fw_status_ready;
+
+   if (!fw_status_ready) {
dev_info(ionic->dev, "FW stopped %u\n", fw_status);
if (lif && !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
trigger = true;
@@ -143,44 +163,47 @@ int ionic_heartbeat_check(struct ionic *ionic)
struct ionic_deferred_work *work;
 
work = kzalloc(sizeof(*work), GFP_ATOMIC);
-   if (!work) {
-   dev_err(ionic->dev, "LIF reset trigger 
dropped\n");
-   } else {
+   if (work) {
work->type = IONIC_DW_TYPE_LIF_RESET;
-   if (fw_status & IONIC_FW_STS_F_RUNNING &&
-   fw_status != 0xff)
-   work->fw_status = 1;
+   work->fw_status = fw_status_ready;

[PATCH net-next 5/7] ionic: block actions during fw reset

2021-03-18 Thread Shannon Nelson
Block some actions while the FW is in a reset activity
and the queues are not configured.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 4 
 drivers/net/ethernet/pensando/ionic/ionic_dev.c | 8 +---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 7 ++-
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c 
b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
index b0d8499d373b..e4a5416adc80 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
@@ -184,6 +184,10 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int 
num_vfs)
struct device *dev = ionic->dev;
int ret = 0;
 
+   if (ionic->lif &&
+   test_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state))
+   return -EBUSY;
+
if (num_vfs > 0) {
ret = pci_enable_sriov(pdev, num_vfs);
if (ret) {
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index b951bf5bbdc4..0532f7cf086d 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -14,18 +14,20 @@
 static void ionic_watchdog_cb(struct timer_list *t)
 {
struct ionic *ionic = from_timer(ionic, t, watchdog_timer);
+   struct ionic_lif *lif = ionic->lif;
int hb;
 
mod_timer(&ionic->watchdog_timer,
  round_jiffies(jiffies + ionic->watchdog_period));
 
-   if (!ionic->lif)
+   if (!lif)
return;
 
hb = ionic_heartbeat_check(ionic);
 
-   if (hb >= 0)
-   ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP);
+   if (hb >= 0 &&
+   !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
+   ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
 }
 
 void ionic_init_devinfo(struct ionic *ionic)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 18fcba4fc413..4f4ca183830b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1477,7 +1477,8 @@ static void ionic_tx_timeout_work(struct work_struct *ws)
 {
struct ionic_lif *lif = container_of(ws, struct ionic_lif, 
tx_timeout_work);
 
-   netdev_info(lif->netdev, "Tx Timeout recovery\n");
+   if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
+   return;
 
/* if we were stopped before this scheduled job was launched,
 * don't bother the queues as they are already stopped.
@@ -1493,6 +1494,7 @@ static void ionic_tx_timeout(struct net_device *netdev, 
unsigned int txqueue)
 {
struct ionic_lif *lif = netdev_priv(netdev);
 
+   netdev_info(lif->netdev, "Tx Timeout triggered - txq %d\n", txqueue);
schedule_work(&lif->tx_timeout_work);
 }
 
@@ -1834,6 +1836,9 @@ static int ionic_start_queues(struct ionic_lif *lif)
 {
int err;
 
+   if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
+   return -EBUSY;
+
if (test_and_set_bit(IONIC_LIF_F_UP, lif->state))
return 0;
 
-- 
2.17.1



[PATCH net-next 4/7] ionic: update ethtool support bits for BASET

2021-03-18 Thread Shannon Nelson
Add support in get_link_ksettings for a couple of
new BASET connections.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 8 
 drivers/net/ethernet/pensando/ionic/ionic_if.h  | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 9df4b9df7a82..b1e78b452fad 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -207,6 +207,14 @@ static int ionic_get_link_ksettings(struct net_device 
*netdev,
ethtool_link_ksettings_add_link_mode(ks, supported,
 1baseER_Full);
break;
+   case IONIC_XCVR_PID_SFP_10GBASE_T:
+   ethtool_link_ksettings_add_link_mode(ks, supported,
+1baseT_Full);
+   break;
+   case IONIC_XCVR_PID_SFP_1000BASE_T:
+   ethtool_link_ksettings_add_link_mode(ks, supported,
+1000baseT_Full);
+   break;
case IONIC_XCVR_PID_UNKNOWN:
/* This means there's no module plugged in */
break;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h 
b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 40bd72bb5148..88210142395d 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -,6 +,8 @@ enum ionic_xcvr_pid {
IONIC_XCVR_PID_QSFP_100G_CWDM4  = 69,
IONIC_XCVR_PID_QSFP_100G_PSM4   = 70,
IONIC_XCVR_PID_SFP_25GBASE_ACC  = 71,
+   IONIC_XCVR_PID_SFP_10GBASE_T= 72,
+   IONIC_XCVR_PID_SFP_1000BASE_T   = 73,
 };
 
 /**
-- 
2.17.1



[PATCH net-next 6/7] ionic: stop watchdog when in broken state

2021-03-18 Thread Shannon Nelson
Up to now we've been ignoring any error return from the
queue starting in the link status check, so we fix that here.
If the driver had to reset and couldn't get things running
properly again, for example after a Tx Timeout and the FW is
not responding to commands, don't let the link watchdog try
to restart the queues.  At this point the user can try to DOWN
and UP the device to clear the errors.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 25 +--
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  1 +
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 4f4ca183830b..9b3afedbc083 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -120,17 +120,31 @@ static void ionic_link_status_check(struct ionic_lif *lif)
if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state))
return;
 
+   /* Don't put carrier back up if we're in a broken state */
+   if (test_bit(IONIC_LIF_F_BROKEN, lif->state)) {
+   clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state);
+   return;
+   }
+
link_status = le16_to_cpu(lif->info->status.link_status);
link_up = link_status == IONIC_PORT_OPER_STATUS_UP;
 
if (link_up) {
+   int err = 0;
+
if (netdev->flags & IFF_UP && netif_running(netdev)) {
mutex_lock(&lif->queue_lock);
-   ionic_start_queues(lif);
+   err = ionic_start_queues(lif);
+   if (err) {
+   netdev_err(lif->netdev,
+  "Failed to start queues: %d\n", err);
+   set_bit(IONIC_LIF_F_BROKEN, lif->state);
+   netif_carrier_off(lif->netdev);
+   }
mutex_unlock(&lif->queue_lock);
}
 
-   if (!netif_carrier_ok(netdev)) {
+   if (!err && !netif_carrier_ok(netdev)) {
ionic_port_identify(lif->ionic);
netdev_info(netdev, "Link up - %d Gbps\n",
le32_to_cpu(lif->info->status.link_speed) / 
1000);
@@ -1836,6 +1850,9 @@ static int ionic_start_queues(struct ionic_lif *lif)
 {
int err;
 
+   if (test_bit(IONIC_LIF_F_BROKEN, lif->state))
+   return -EIO;
+
if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
return -EBUSY;
 
@@ -1857,6 +1874,10 @@ static int ionic_open(struct net_device *netdev)
struct ionic_lif *lif = netdev_priv(netdev);
int err;
 
+   /* If recovering from a broken state, clear the bit and we'll try again 
*/
+   if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
+   netdev_info(netdev, "clearing broken state\n");
+
err = ionic_txrx_alloc(lif);
if (err)
return err;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 8ffda32a0a7d..be5cc89b2bd9 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -139,6 +139,7 @@ enum ionic_lif_state_flags {
IONIC_LIF_F_LINK_CHECK_REQUESTED,
IONIC_LIF_F_FW_RESET,
IONIC_LIF_F_SPLIT_INTR,
+   IONIC_LIF_F_BROKEN,
IONIC_LIF_F_TX_DIM_INTR,
IONIC_LIF_F_RX_DIM_INTR,
 
-- 
2.17.1



[PATCH net-next 7/7] ionic: protect adminq from early destroy

2021-03-18 Thread Shannon Nelson
Don't destroy the adminq while there is an outstanding request.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 14 ++--
 .../net/ethernet/pensando/ionic/ionic_main.c  | 22 ++-
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 9b3afedbc083..889d234e2ffa 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -393,6 +393,8 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct 
ionic_qcq *qcq)
 static void ionic_qcqs_free(struct ionic_lif *lif)
 {
struct device *dev = lif->ionic->dev;
+   struct ionic_qcq *adminqcq;
+   unsigned long irqflags;
 
if (lif->notifyqcq) {
ionic_qcq_free(lif, lif->notifyqcq);
@@ -401,9 +403,14 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
}
 
if (lif->adminqcq) {
-   ionic_qcq_free(lif, lif->adminqcq);
-   devm_kfree(dev, lif->adminqcq);
+   spin_lock_irqsave(&lif->adminq_lock, irqflags);
+   adminqcq = READ_ONCE(lif->adminqcq);
lif->adminqcq = NULL;
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
+   if (adminqcq) {
+   ionic_qcq_free(lif, adminqcq);
+   devm_kfree(dev, adminqcq);
+   }
}
 
if (lif->rxqcqs) {
@@ -886,6 +893,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int 
budget)
struct ionic_intr_info *intr = napi_to_cq(napi)->bound_intr;
struct ionic_lif *lif = napi_to_cq(napi)->lif;
struct ionic_dev *idev = &lif->ionic->idev;
+   unsigned long irqflags;
unsigned int flags = 0;
int n_work = 0;
int a_work = 0;
@@ -895,9 +903,11 @@ static int ionic_adminq_napi(struct napi_struct *napi, int 
budget)
n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
  ionic_notifyq_service, NULL, NULL);
 
+   spin_lock_irqsave(&lif->adminq_lock, irqflags);
if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED)
a_work = ionic_cq_service(&lif->adminqcq->cq, budget,
  ionic_adminq_service, NULL, NULL);
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 
work_done = max(n_work, a_work);
if (work_done < budget && napi_complete_done(napi, work_done)) {
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c 
b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index 14ece909a451..c4b2906a2ae6 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
@@ -187,10 +187,17 @@ static const char *ionic_opcode_to_str(enum 
ionic_cmd_opcode opcode)
 
 static void ionic_adminq_flush(struct ionic_lif *lif)
 {
-   struct ionic_queue *q = &lif->adminqcq->q;
struct ionic_desc_info *desc_info;
+   unsigned long irqflags;
+   struct ionic_queue *q;
+
+   spin_lock_irqsave(&lif->adminq_lock, irqflags);
+   if (!lif->adminqcq) {
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
+   return;
+   }
 
-   spin_lock(&lif->adminq_lock);
+   q = &lif->adminqcq->q;
 
while (q->tail_idx != q->head_idx) {
desc_info = &q->info[q->tail_idx];
@@ -199,7 +206,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
desc_info->cb_arg = NULL;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
}
-   spin_unlock(&lif->adminq_lock);
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 }
 
 static int ionic_adminq_check_err(struct ionic_lif *lif,
@@ -252,15 +259,18 @@ static void ionic_adminq_cb(struct ionic_queue *q,
 static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx 
*ctx)
 {
struct ionic_desc_info *desc_info;
+   unsigned long irqflags;
struct ionic_queue *q;
int err = 0;
 
-   if (!lif->adminqcq)
+   spin_lock_irqsave(&lif->adminq_lock, irqflags);
+   if (!lif->adminqcq) {
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return -EIO;
+   }
 
q = &lif->adminqcq->q;
 
-   spin_lock(&lif->adminq_lock);
if (!ionic_q_has_space(q, 1)) {
err = -ENOSPC;
goto err_out;
@@ -280,7 +290,7 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct 
ionic_admin_ctx *ctx)
ionic_q_post(q, true, ionic_adminq_cb, ctx);
 
 err_out:
-   spin_unlock(&lif->adminq_lock);
+   spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 
return err;
 }
-- 
2.17.1



[PATCH net-next 3/7] ionic: fix unchecked reference

2021-03-18 Thread Shannon Nelson
We can get to the counter without going through the pointer
that the robot complained about.

Reported-by: kernel test robot 
Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 83ec3c664790..18fcba4fc413 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -888,7 +888,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int 
budget)
work_done = max(n_work, a_work);
if (work_done < budget && napi_complete_done(napi, work_done)) {
flags |= IONIC_INTR_CRED_UNMASK;
-   lif->adminqcq->cq.bound_intr->rearm_count++;
+   intr->rearm_count++;
}
 
if (work_done || flags) {
-- 
2.17.1



[PATCH net-next 1/7] ionic: code cleanup details

2021-03-18 Thread Shannon Nelson
Catch a couple of missing macro name uses, fix a couple
of misspellings, etc.

Signed-off-by: Shannon Nelson 
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   |  8 ++
 .../net/ethernet/pensando/ionic/ionic_if.h| 26 +--
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 23 +++-
 3 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 0832bedcb3b4..9df4b9df7a82 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -29,11 +29,9 @@ static void ionic_get_stats_strings(struct ionic_lif *lif, 
u8 *buf)
 static void ionic_get_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *buf)
 {
-   struct ionic_lif *lif;
+   struct ionic_lif *lif = netdev_priv(netdev);
u32 i;
 
-   lif = netdev_priv(netdev);
-
memset(buf, 0, stats->n_stats * sizeof(*buf));
for (i = 0; i < ionic_num_stats_grps; i++)
ionic_stats_groups[i].get_values(lif, &buf);
@@ -264,12 +262,10 @@ static int ionic_set_link_ksettings(struct net_device 
*netdev,
const struct ethtool_link_ksettings *ks)
 {
struct ionic_lif *lif = netdev_priv(netdev);
+   struct ionic_dev *idev = &lif->ionic->idev;
struct ionic *ionic = lif->ionic;
-   struct ionic_dev *idev;
int err = 0;
 
-   idev = &lif->ionic->idev;
-
/* set autoneg */
if (ks->base.autoneg != idev->port_info->config.an_enable) {
mutex_lock(&ionic->dev_cmd_lock);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h 
b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 31ccfcdc2b0a..40bd72bb5148 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -320,7 +320,7 @@ struct ionic_lif_identify_comp {
 /**
  * enum ionic_lif_capability - LIF capabilities
  * @IONIC_LIF_CAP_ETH: LIF supports Ethernet
- * @IONIC_LIF_CAP_RDMA:LIF support RDMA
+ * @IONIC_LIF_CAP_RDMA:LIF supports RDMA
  */
 enum ionic_lif_capability {
IONIC_LIF_CAP_ETH= BIT(0),
@@ -404,7 +404,7 @@ union ionic_lif_config {
  * @max_ucast_filters:  Number of perfect unicast addresses supported
  * @max_mcast_filters:  Number of perfect multicast addresses supported
  * @min_frame_size: Minimum size of frames to be sent
- * @max_frame_size: Maximim size of frames to be sent
+ * @max_frame_size: Maximum size of frames to be sent
  * @config: LIF config struct with features, mtu, mac, q counts
  *
  * @rdma:RDMA identify structure
@@ -692,7 +692,7 @@ enum ionic_txq_desc_opcode {
  *  checksums are also updated.
  *
  *   IONIC_TXQ_DESC_OPCODE_TSO:
- *  Device preforms TCP segmentation offload
+ *  Device performs TCP segmentation offload
  *  (TSO).  @hdr_len is the number of bytes
  *  to the end of TCP header (the offset to
  *  the TCP payload).  @mss is the desired
@@ -982,13 +982,13 @@ struct ionic_rxq_comp {
 };
 
 enum ionic_pkt_type {
-   IONIC_PKT_TYPE_NON_IP = 0x000,
-   IONIC_PKT_TYPE_IPV4   = 0x001,
-   IONIC_PKT_TYPE_IPV4_TCP   = 0x003,
-   IONIC_PKT_TYPE_IPV4_UDP   = 0x005,
-   IONIC_PKT_TYPE_IPV6   = 0x008,
-   IONIC_PKT_TYPE_IPV6_TCP   = 0x018,
-   IONIC_PKT_TYPE_IPV6_UDP   = 0x028,
+   IONIC_PKT_TYPE_NON_IP   = 0x00,
+   IONIC_PKT_TYPE_IPV4 = 0x01,
+   IONIC_PKT_TYPE_IPV4_TCP = 0x03,
+   IONIC_PKT_TYPE_IPV4_UDP = 0x05,
+   IONIC_PKT_TYPE_IPV6 = 0x08,
+   IONIC_PKT_TYPE_IPV6_TCP = 0x18,
+   IONIC_PKT_TYPE_IPV6_UDP = 0x28,
/* below types are only used if encap offloads are enabled on lif */
IONIC_PKT_TYPE_ENCAP_NON_IP = 0x40,
IONIC_PKT_TYPE_ENCAP_IPV4   = 0x41,
@@ -1331,7 +1331,7 @@ enum ionic_stats_ctl_cmd {
  * @IONIC_PORT_ATTR_STATE:  Port state attribute
  * @IONIC_PORT_ATTR_SPEED:  Port speed attribute
  * @IONIC_PORT_ATTR_MTU:Port MTU attribute
- * @IONIC_PORT_ATTR_AUTONEG:Port autonegotation attribute
+ * @IONIC_PORT_ATTR_AUTONEG:Port autonegotiation attribute
  * @IONIC_PORT_ATTR_FEC:Port FEC attribute
  * @IONIC_PORT_ATTR_PAUSE:  Port pause attribute
  * @IONIC_PORT_ATTR_LOOPBACK:   Port loopback attribute
@@ -1951,8 +1951,8 @@ enum ionic_qos_sched_type {
  * @pfc_cos:   Priority-Flow Control class of service
  * @dwrr_weight:   QoS class scheduling weight
  * @strict_rlmt:   Rate limit for strict priority scheduling
- * @rw_dot1q_pcp:  Rewrite d

[PATCH net-next 0/7] ionic fixes

2021-03-18 Thread Shannon Nelson
These are a few little fixes and cleanups found while working
on other features and more testing.

Shannon Nelson (7):
  ionic: code cleanup details
  ionic: simplify the intr_index use in txq_init
  ionic: fix unchecked reference
  ionic: update ethtool support bits for BASET
  ionic: block actions during fw reset
  ionic: stop watchdog when in broken state
  ionic: protect adminq from early destroy

 .../ethernet/pensando/ionic/ionic_bus_pci.c   |  4 +
 .../net/ethernet/pensando/ionic/ionic_dev.c   |  8 +-
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 16 ++--
 .../net/ethernet/pensando/ionic/ionic_if.h| 28 +++
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 77 +--
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_main.c  | 22 --
 7 files changed, 105 insertions(+), 51 deletions(-)

-- 
2.17.1



[PATCH net-next 2/7] ionic: simplify the intr_index use in txq_init

2021-03-18 Thread Shannon Nelson
The qcq->intr.index was set when the queue was allocated,
there is no need to reach around to find it.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 7ee6d2dbbb34..83ec3c664790 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -715,10 +715,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, 
struct ionic_qcq *qcq)
unsigned int intr_index;
int err;
 
-   if (qcq->flags & IONIC_QCQ_F_INTR)
-   intr_index = qcq->intr.index;
-   else
-   intr_index = lif->rxqcqs[q->index]->intr.index;
+   intr_index = qcq->intr.index;
+
ctx.cmd.q_init.intr_index = cpu_to_le16(intr_index);
 
dev_dbg(dev, "txq_init.pid %d\n", ctx.cmd.q_init.pid);
-- 
2.17.1



[PATCH v2 net] ionic: linearize tso skb with too many frags

2021-03-16 Thread Shannon Nelson
We were linearizing non-TSO skbs that had too many frags, but
we weren't checking number of frags on TSO skbs.  This could
lead to a bad page reference when we received a TSO skb with
more frags than the Tx descriptor could support.

v2: use gso_segs rather than yet another division
don't rework the check on the nr_frags

Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 162a1ff1e9d2..4087311f7082 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1079,15 +1079,17 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, 
struct sk_buff *skb)
 {
int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
+   int ndescs;
int err;
 
-   /* If TSO, need roundup(skb->len/mss) descs */
+   /* Each desc is mss long max, so a descriptor for each gso_seg */
if (skb_is_gso(skb))
-   return (skb->len / skb_shinfo(skb)->gso_size) + 1;
+   ndescs = skb_shinfo(skb)->gso_segs;
+   else
+   ndescs = 1;
 
-   /* If non-TSO, just need 1 desc and nr_frags sg elems */
if (skb_shinfo(skb)->nr_frags <= sg_elems)
-   return 1;
+   return ndescs;
 
/* Too many frags, so linearize */
err = skb_linearize(skb);
@@ -1096,8 +1098,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, 
struct sk_buff *skb)
 
stats->linearize++;
 
-   /* Need 1 desc and zero sg elems */
-   return 1;
+   return ndescs;
 }
 
 static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)
-- 
2.17.1



Re: [PATCH net] ionic: linearize tso skb with too many frags

2021-03-16 Thread Shannon Nelson

On 3/16/21 2:54 PM, Jakub Kicinski wrote:

On Tue, 16 Mar 2021 11:52:43 -0700 Shannon Nelson wrote:

We were linearizing non-TSO skbs that had too many frags, but
we weren't checking number of frags on TSO skbs.  This could
lead to a bad page reference when we received a TSO skb with
more frags than the Tx descriptor could support.

Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
Signed-off-by: Shannon Nelson 
---
  .../net/ethernet/pensando/ionic/ionic_txrx.c  | 28 ++-
  1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 162a1ff1e9d2..462b0d106be4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1079,25 +1079,27 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, 
struct sk_buff *skb)
  {
int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
+   int ndescs;
int err;
  
-	/* If TSO, need roundup(skb->len/mss) descs */

+   /* If TSO, need roundup(skb->len/mss) descs
+* If non-TSO, just need 1 desc and nr_frags sg elems
+*/
if (skb_is_gso(skb))
-   return (skb->len / skb_shinfo(skb)->gso_size) + 1;
+   ndescs = (skb->len / skb_shinfo(skb)->gso_size) + 1;

Slightly unrelated but why not gso_segs? len / gso_size + 1 could be
over counting, not to mention that div is expensive.


Good catch - we can probably do that.



Are you segmenting in the driver? Why do you need #segs descriptors?


The device needs each descriptor to be no more than mss length, so there 
might be a number of descriptors for a large packet.





+   else
+   ndescs = 1;
  
-	/* If non-TSO, just need 1 desc and nr_frags sg elems */

-   if (skb_shinfo(skb)->nr_frags <= sg_elems)
-   return 1;
+   /* If too many frags, linearize */
+   if (skb_shinfo(skb)->nr_frags > sg_elems) {
+   err = skb_linearize(skb);
+   if (err)
+   return err;
  
-	/* Too many frags, so linearize */

-   err = skb_linearize(skb);
-   if (err)
-   return err;
-
-   stats->linearize++;
+   stats->linearize++;
+   }
  
-	/* Need 1 desc and zero sg elems */

-   return 1;
+   return ndescs;

I'd be tempted to push back on the refactoring here, you could've
just replaced return 1;s with return ndescs;s without changing
the indentation.. this will give all backporters a pause. But
not the end of the world, I guess.


I can tweak that a little.

I'll send a v2.

sln




  }
  
  static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)




[PATCH net] ionic: linearize tso skb with too many frags

2021-03-16 Thread Shannon Nelson
We were linearizing non-TSO skbs that had too many frags, but
we weren't checking number of frags on TSO skbs.  This could
lead to a bad page reference when we received a TSO skb with
more frags than the Tx descriptor could support.

Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 28 ++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 162a1ff1e9d2..462b0d106be4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1079,25 +1079,27 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, 
struct sk_buff *skb)
 {
int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
+   int ndescs;
int err;
 
-   /* If TSO, need roundup(skb->len/mss) descs */
+   /* If TSO, need roundup(skb->len/mss) descs
+* If non-TSO, just need 1 desc and nr_frags sg elems
+*/
if (skb_is_gso(skb))
-   return (skb->len / skb_shinfo(skb)->gso_size) + 1;
+   ndescs = (skb->len / skb_shinfo(skb)->gso_size) + 1;
+   else
+   ndescs = 1;
 
-   /* If non-TSO, just need 1 desc and nr_frags sg elems */
-   if (skb_shinfo(skb)->nr_frags <= sg_elems)
-   return 1;
+   /* If too many frags, linearize */
+   if (skb_shinfo(skb)->nr_frags > sg_elems) {
+   err = skb_linearize(skb);
+   if (err)
+   return err;
 
-   /* Too many frags, so linearize */
-   err = skb_linearize(skb);
-   if (err)
-   return err;
-
-   stats->linearize++;
+   stats->linearize++;
+   }
 
-   /* Need 1 desc and zero sg elems */
-   return 1;
+   return ndescs;
 }
 
 static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)
-- 
2.17.1



[PATCH net-next 3/4] ionic: simplify tx clean

2021-03-15 Thread Shannon Nelson
The descriptor mappings are set up the same way whether
or not it is a TSO, so we don't need separate logic for
the two cases.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 30 +--
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 1d27d6cad504..f841ccb5adfd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -654,35 +654,19 @@ static void ionic_tx_clean(struct ionic_queue *q,
   struct ionic_cq_info *cq_info,
   void *cb_arg)
 {
-   struct ionic_txq_sg_desc *sg_desc = desc_info->sg_desc;
struct ionic_buf_info *buf_info = desc_info->bufs;
-   struct ionic_txq_sg_elem *elem = sg_desc->elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
-   struct ionic_txq_desc *desc = desc_info->desc;
struct device *dev = q->dev;
-   u8 opcode, flags, nsge;
u16 queue_index;
unsigned int i;
-   u64 addr;
-
-   decode_txq_desc_cmd(le64_to_cpu(desc->cmd),
-   &opcode, &flags, &nsge, &addr);
 
-   if (opcode != IONIC_TXQ_DESC_OPCODE_TSO) {
-   dma_unmap_single(dev, (dma_addr_t)addr,
-le16_to_cpu(desc->len), DMA_TO_DEVICE);
-   for (i = 0; i < nsge; i++, elem++)
-   dma_unmap_page(dev, (dma_addr_t)le64_to_cpu(elem->addr),
-  le16_to_cpu(elem->len), DMA_TO_DEVICE);
-   } else {
-   if (flags & IONIC_TXQ_DESC_FLAG_TSO_EOT) {
-   dma_unmap_single(dev, (dma_addr_t)buf_info->dma_addr,
-buf_info->len, DMA_TO_DEVICE);
-   buf_info++;
-   for (i = 1; i < desc_info->nbufs; i++, buf_info++)
-   dma_unmap_page(dev, 
(dma_addr_t)buf_info->dma_addr,
-  buf_info->len, DMA_TO_DEVICE);
-   }
+   if (desc_info->nbufs) {
+   dma_unmap_single(dev, (dma_addr_t)buf_info->dma_addr,
+buf_info->len, DMA_TO_DEVICE);
+   buf_info++;
+   for (i = 1; i < desc_info->nbufs; i++, buf_info++)
+   dma_unmap_page(dev, (dma_addr_t)buf_info->dma_addr,
+  buf_info->len, DMA_TO_DEVICE);
}
 
if (cb_arg) {
-- 
2.17.1



[PATCH net-next 1/4] ionic: simplify TSO descriptor mapping

2021-03-15 Thread Shannon Nelson
One issue with the original TSO code was that it was working too
hard to deal with skb layouts that were never going to show up,
such as an skb->data that was longer than a single descriptor's
length.  The other issue was trying to arrange the fragment dma
mapping at the same time as figuring out the descriptors needed.
There was just too much going on at the same time.

Now we do the dma mapping first, which sets up the buffers with
skb->data in buf[0] and the remaining frags in buf[1..n-1].
Next we spread the bufs across the descriptors needed, where
each descriptor gets up to mss number of bytes.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   5 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 237 +-
 2 files changed, 117 insertions(+), 125 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 339824cfd618..d0c969a6d43e 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -179,8 +179,11 @@ struct ionic_buf_info {
struct page *page;
dma_addr_t dma_addr;
u32 page_offset;
+   u32 len;
 };
 
+#define IONIC_MAX_FRAGS(1 + IONIC_TX_MAX_SG_ELEMS_V1)
+
 struct ionic_desc_info {
union {
void *desc;
@@ -194,7 +197,7 @@ struct ionic_desc_info {
struct ionic_rxq_sg_desc *rxq_sgl_desc;
};
unsigned int nbufs;
-   struct ionic_buf_info bufs[IONIC_RX_MAX_SG_ELEMS + 1];
+   struct ionic_buf_info bufs[IONIC_MAX_FRAGS];
ionic_desc_cb cb;
void *cb_arg;
 };
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index c63e6e7aa47b..639000a2e495 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -605,12 +605,51 @@ static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q,
return dma_addr;
 }
 
+static int ionic_tx_map_tso(struct ionic_queue *q, struct sk_buff *skb,
+   struct ionic_buf_info *buf_info)
+{
+   struct device *dev = q->dev;
+   dma_addr_t dma_addr;
+   skb_frag_t *frag;
+   int frag_idx;
+
+   dma_addr = ionic_tx_map_single(q, skb->data, skb_headlen(skb));
+   if (dma_mapping_error(dev, dma_addr))
+   return -EIO;
+   buf_info->dma_addr = dma_addr;
+   buf_info->len = skb_headlen(skb);
+   buf_info++;
+
+   for (frag_idx = 0; frag_idx < skb_shinfo(skb)->nr_frags; frag_idx++, 
buf_info++) {
+   frag = &skb_shinfo(skb)->frags[frag_idx];
+   dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag));
+   if (dma_mapping_error(dev, dma_addr))
+   goto dma_fail;
+   buf_info->dma_addr = dma_addr;
+   buf_info->len = skb_frag_size(frag);
+   }
+
+   return 0;
+
+dma_fail:
+   /* unwind the frag mappings and the head mapping */
+   while (frag_idx > 0) {
+   frag_idx--;
+   buf_info--;
+   dma_unmap_page(dev, buf_info->dma_addr,
+  buf_info->len, DMA_TO_DEVICE);
+   }
+   dma_unmap_single(dev, buf_info->dma_addr, buf_info->len, DMA_TO_DEVICE);
+   return -EIO;
+}
+
 static void ionic_tx_clean(struct ionic_queue *q,
   struct ionic_desc_info *desc_info,
   struct ionic_cq_info *cq_info,
   void *cb_arg)
 {
struct ionic_txq_sg_desc *sg_desc = desc_info->sg_desc;
+   struct ionic_buf_info *buf_info = desc_info->bufs;
struct ionic_txq_sg_elem *elem = sg_desc->elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct ionic_txq_desc *desc = desc_info->desc;
@@ -623,20 +662,22 @@ static void ionic_tx_clean(struct ionic_queue *q,
decode_txq_desc_cmd(le64_to_cpu(desc->cmd),
&opcode, &flags, &nsge, &addr);
 
-   /* use unmap_single only if either this is not TSO,
-* or this is first descriptor of a TSO
-*/
-   if (opcode != IONIC_TXQ_DESC_OPCODE_TSO ||
-   flags & IONIC_TXQ_DESC_FLAG_TSO_SOT)
+   if (opcode != IONIC_TXQ_DESC_OPCODE_TSO) {
dma_unmap_single(dev, (dma_addr_t)addr,
 le16_to_cpu(desc->len), DMA_TO_DEVICE);
-   else
-   dma_unmap_page(dev, (dma_addr_t)addr,
-  le16_to_cpu(desc->len), DMA_TO_DEVICE);
-
-   for (i = 0; i < nsge; i++, elem++)
-   dma_unmap_page(dev, (dma_addr_t)le64_to_cpu(elem->addr),
-  le16_to_cpu(elem->len), DMA_TO_DEVICE);
+   for (i

[PATCH net-next 4/4] ionic: aggregate Tx byte counting calls

2021-03-15 Thread Shannon Nelson
Gather the Tx packet and byte counts and call
netdev_tx_completed_queue() only once per clean cycle.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 27 ---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index d0c969a6d43e..ca7e55455165 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -196,6 +196,7 @@ struct ionic_desc_info {
struct ionic_txq_sg_desc *txq_sg_desc;
struct ionic_rxq_sg_desc *rxq_sgl_desc;
};
+   unsigned int bytes;
unsigned int nbufs;
struct ionic_buf_info bufs[IONIC_MAX_FRAGS];
ionic_desc_cb cb;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index f841ccb5adfd..03e00a6c413a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -671,7 +671,6 @@ static void ionic_tx_clean(struct ionic_queue *q,
 
if (cb_arg) {
struct sk_buff *skb = cb_arg;
-   u32 len = skb->len;
 
queue_index = skb_get_queue_mapping(skb);
if (unlikely(__netif_subqueue_stopped(q->lif->netdev,
@@ -679,9 +678,11 @@ static void ionic_tx_clean(struct ionic_queue *q,
netif_wake_subqueue(q->lif->netdev, queue_index);
q->wake++;
}
-   dev_kfree_skb_any(skb);
+
+   desc_info->bytes = skb->len;
stats->clean++;
-   netdev_tx_completed_queue(q_to_ndq(q), 1, len);
+
+   dev_consume_skb_any(skb);
}
 }
 
@@ -690,6 +691,8 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct 
ionic_cq_info *cq_info)
struct ionic_txq_comp *comp = cq_info->txcq;
struct ionic_queue *q = cq->bound_q;
struct ionic_desc_info *desc_info;
+   int bytes = 0;
+   int pkts = 0;
u16 index;
 
if (!color_match(comp->color, cq->done_color))
@@ -700,13 +703,21 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct 
ionic_cq_info *cq_info)
 */
do {
desc_info = &q->info[q->tail_idx];
+   desc_info->bytes = 0;
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, cq_info, desc_info->cb_arg);
+   if (desc_info->cb_arg) {
+   pkts++;
+   bytes += desc_info->bytes;
+   }
desc_info->cb = NULL;
desc_info->cb_arg = NULL;
} while (index != le16_to_cpu(comp->comp_index));
 
+   if (pkts && bytes)
+   netdev_tx_completed_queue(q_to_ndq(q), pkts, bytes);
+
return true;
 }
 
@@ -725,15 +736,25 @@ void ionic_tx_flush(struct ionic_cq *cq)
 void ionic_tx_empty(struct ionic_queue *q)
 {
struct ionic_desc_info *desc_info;
+   int bytes = 0;
+   int pkts = 0;
 
/* walk the not completed tx entries, if any */
while (q->head_idx != q->tail_idx) {
desc_info = &q->info[q->tail_idx];
+   desc_info->bytes = 0;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, NULL, desc_info->cb_arg);
+   if (desc_info->cb_arg) {
+   pkts++;
+   bytes += desc_info->bytes;
+   }
desc_info->cb = NULL;
desc_info->cb_arg = NULL;
}
+
+   if (pkts && bytes)
+   netdev_tx_completed_queue(q_to_ndq(q), pkts, bytes);
 }
 
 static int ionic_tx_tcp_inner_pseudo_csum(struct sk_buff *skb)
-- 
2.17.1



[PATCH net-next 2/4] ionic: generic tx skb mapping

2021-03-15 Thread Shannon Nelson
Make the new ionic_tx_map_tso() usable by the non-TSO paths,
and pull the call up a level into ionic_tx() before calling
the csum or no-csum routines.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 142 +-
 1 file changed, 68 insertions(+), 74 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 639000a2e495..1d27d6cad504 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -605,11 +605,13 @@ static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q,
return dma_addr;
 }
 
-static int ionic_tx_map_tso(struct ionic_queue *q, struct sk_buff *skb,
-   struct ionic_buf_info *buf_info)
+static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb,
+   struct ionic_desc_info *desc_info)
 {
+   struct ionic_buf_info *buf_info = desc_info->bufs;
struct device *dev = q->dev;
dma_addr_t dma_addr;
+   unsigned int nfrags;
skb_frag_t *frag;
int frag_idx;
 
@@ -620,15 +622,19 @@ static int ionic_tx_map_tso(struct ionic_queue *q, struct 
sk_buff *skb,
buf_info->len = skb_headlen(skb);
buf_info++;
 
-   for (frag_idx = 0; frag_idx < skb_shinfo(skb)->nr_frags; frag_idx++, 
buf_info++) {
-   frag = &skb_shinfo(skb)->frags[frag_idx];
+   frag = skb_shinfo(skb)->frags;
+   nfrags = skb_shinfo(skb)->nr_frags;
+   for (frag_idx = 0; frag_idx < nfrags; frag_idx++, frag++) {
dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag));
if (dma_mapping_error(dev, dma_addr))
goto dma_fail;
buf_info->dma_addr = dma_addr;
buf_info->len = skb_frag_size(frag);
+   buf_info++;
}
 
+   desc_info->nbufs = 1 + nfrags;
+
return 0;
 
 dma_fail:
@@ -814,40 +820,29 @@ static void ionic_tx_tso_post(struct ionic_queue *q, 
struct ionic_txq_desc *desc
desc->hdr_len = cpu_to_le16(hdrlen);
desc->mss = cpu_to_le16(mss);
 
-   if (done) {
+   if (start) {
skb_tx_timestamp(skb);
netdev_tx_sent_queue(q_to_ndq(q), skb->len);
-   ionic_txq_post(q, !netdev_xmit_more(), ionic_tx_clean, skb);
+   ionic_txq_post(q, false, ionic_tx_clean, skb);
} else {
-   ionic_txq_post(q, false, ionic_tx_clean, NULL);
+   ionic_txq_post(q, done, NULL, NULL);
}
 }
 
-static struct ionic_txq_desc *ionic_tx_tso_next(struct ionic_queue *q,
-   struct ionic_txq_sg_elem **elem)
-{
-   struct ionic_txq_sg_desc *sg_desc = q->info[q->head_idx].txq_sg_desc;
-   struct ionic_txq_desc *desc = q->info[q->head_idx].txq_desc;
-
-   *elem = sg_desc->elems;
-   return desc;
-}
-
 static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
 {
-   struct ionic_buf_info buf_info[IONIC_MAX_FRAGS] = {{0}};
struct ionic_tx_stats *stats = q_to_tx_stats(q);
+   struct ionic_desc_info *desc_info;
+   struct ionic_buf_info *buf_info;
struct ionic_txq_sg_elem *elem;
struct ionic_txq_desc *desc;
unsigned int chunk_len;
unsigned int frag_rem;
-   unsigned int frag_idx;
unsigned int tso_rem;
unsigned int seg_rem;
dma_addr_t desc_addr;
dma_addr_t frag_addr;
unsigned int hdrlen;
-   unsigned int nfrags;
unsigned int len;
unsigned int mss;
bool start, done;
@@ -859,12 +854,14 @@ static int ionic_tx_tso(struct ionic_queue *q, struct 
sk_buff *skb)
bool encap;
int err;
 
-   if (unlikely(ionic_tx_map_tso(q, skb, buf_info)))
+   desc_info = &q->info[q->head_idx];
+   buf_info = desc_info->bufs;
+
+   if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
return -EIO;
 
len = skb->len;
mss = skb_shinfo(skb)->gso_size;
-   nfrags = skb_shinfo(skb)->nr_frags;
outer_csum = (skb_shinfo(skb)->gso_type & SKB_GSO_GRE_CSUM) ||
 (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM);
has_vlan = !!skb_vlan_tag_present(skb);
@@ -892,7 +889,6 @@ static int ionic_tx_tso(struct ionic_queue *q, struct 
sk_buff *skb)
tso_rem = len;
seg_rem = min(tso_rem, hdrlen + mss);
 
-   frag_idx = 0;
frag_addr = 0;
frag_rem = 0;
 
@@ -904,19 +900,20 @@ static int ionic_tx_tso(struct ionic_queue *q, struct 
sk_buff *skb)
desc_addr = 0;
desc_len = 0;
desc_nsge = 0;
-   /* loop until a full tcp segment can be created */
+   /* use fragments until we have enough to 

[PATCH net-next 0/4] ionic Tx updates

2021-03-15 Thread Shannon Nelson
Just as the Rx path recently got a face lift, it is time for the Tx path to
get some attention.  The original TSO-to-descriptor mapping was ugly and
convoluted and needed some deep work.  This series pulls the dma mapping
out of the descriptor frag mapping loop and makes the dma mapping more
generic for use in the non-TSO case.

Shannon Nelson (4):
  ionic: simplify TSO descriptor mapping
  ionic: generic tx skb mapping
  ionic: simplify tx clean
  ionic: aggregate Tx byte counting calls

 .../net/ethernet/pensando/ionic/ionic_dev.h   |   6 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 374 +-
 2 files changed, 186 insertions(+), 194 deletions(-)

-- 
2.17.1



Re: [PATCH net-next 2/6] ionic: implement Rx page reuse

2021-03-12 Thread Shannon Nelson

On 3/10/21 6:14 PM, Alexander Duyck wrote:

On Wed, Mar 10, 2021 at 11:28 AM Shannon Nelson  wrote:

Rework the Rx buffer allocations to use pages twice when using
normal MTU in order to cut down on buffer allocation and mapping
overhead.

Instead of tracking individual pages, in which we may have
wasted half the space when using standard 1500 MTU, we track
buffers which use half pages, so we can use the second half
of the page rather than allocate and map a new page once the
first buffer has been used.

Signed-off-by: Shannon Nelson 

So looking at the approach taken here it just seems like you are doing
the linear walk approach and getting 2 uses per 4K page. If you are
taking that route it might make more sense to just split the page and
use both pieces immediately to populate 2 entries instead of waiting
on the next loop through the ring. Then you could just split the page
into multiple buffers and fill your sg list using less total pages
rather than having 2K gaps between your entries. An added advantage
would be that you could simply merge the page fragments in the event
that you have something writing to the full 2K buffers and you cannot
use copybreak.


Thanks, Alex, for the detailed review.  I'll work with our internal 
performance guy to fold these comments into an update.

sln





---
  .../net/ethernet/pensando/ionic/ionic_dev.h   |  12 +-
  .../net/ethernet/pensando/ionic/ionic_txrx.c  | 215 +++---
  2 files changed, 138 insertions(+), 89 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 690768ff0143..0f877c86eba6 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -170,9 +170,15 @@ typedef void (*ionic_desc_cb)(struct ionic_queue *q,
   struct ionic_desc_info *desc_info,
   struct ionic_cq_info *cq_info, void *cb_arg);

-struct ionic_page_info {
+#define IONIC_PAGE_SIZEPAGE_SIZE
+#define IONIC_PAGE_SPLIT_SZ(PAGE_SIZE / 2)

This probably doesn't work out too well when the page size gets up to
64K. I don't know of too many networks that support a 32K MTU.. :)


+#define IONIC_PAGE_GFP_MASK(GFP_ATOMIC | __GFP_NOWARN |\
+__GFP_COMP | __GFP_MEMALLOC)
+
+struct ionic_buf_info {
 struct page *page;
 dma_addr_t dma_addr;
+   u32 page_offset;
  };

I'm not really sure the rename was needed. You are still just working
with a page aren't you? It would actually reduce the complexity of
this patch a bunch as you could drop the renaming changes.


  struct ionic_desc_info {
@@ -187,8 +193,8 @@ struct ionic_desc_info {
 struct ionic_txq_sg_desc *txq_sg_desc;
 struct ionic_rxq_sg_desc *rxq_sgl_desc;
 };
-   unsigned int npages;
-   struct ionic_page_info pages[IONIC_RX_MAX_SG_ELEMS + 1];
+   unsigned int nbufs;
+   struct ionic_buf_info bufs[IONIC_RX_MAX_SG_ELEMS + 1];
 ionic_desc_cb cb;
 void *cb_arg;
  };
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 70b997f302ac..3e13cfee9ecd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -54,7 +54,7 @@ static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue 
*q,
 if (frags)
 skb = napi_get_frags(&q_to_qcq(q)->napi);
 else
-   skb = netdev_alloc_skb_ip_align(netdev, len);
+   skb = napi_alloc_skb(&q_to_qcq(q)->napi, len);

 if (unlikely(!skb)) {
 net_warn_ratelimited("%s: SKB alloc failed on %s!\n",
@@ -66,8 +66,15 @@ static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue 
*q,
 return skb;
  }

+static void ionic_rx_buf_reset(struct ionic_buf_info *buf_info)
+{
+   buf_info->page = NULL;
+   buf_info->page_offset = 0;
+   buf_info->dma_addr = 0;
+}
+

Technically speaking you probably only need to reset the page value.
You could hold off on resetting the page_offset and dma_addr until you
actually are populating the page.


  static int ionic_rx_page_alloc(struct ionic_queue *q,
-  struct ionic_page_info *page_info)
+  struct ionic_buf_info *buf_info)
  {
 struct ionic_lif *lif = q->lif;
 struct ionic_rx_stats *stats;
@@ -78,26 +85,26 @@ static int ionic_rx_page_alloc(struct ionic_queue *q,
 dev = lif->ionic->dev;
 stats = q_to_rx_stats(q);

-   if (unlikely(!page_info)) {
-   net_err_ratelimited("%s: %s invalid page_info in alloc\n",
+   if (unlikely(!buf_info)) {
+   net_err_ratelimited("%s: %s 

Re: [RFC PATCH 10/10] ionic: Update driver to use ethtool_gsprintf

2021-03-11 Thread Shannon Nelson

On 3/10/21 5:36 PM, Alexander Duyck wrote:

From: Alexander Duyck 

Update the ionic driver to make use of ethtool_gsprintf. In addition add
separate functions for Tx/Rx stats strings in order to reduce the total
amount of indenting needed in the driver code.

Signed-off-by: Alexander Duyck 


Thanks, Alex!

Acked-by: Shannon Nelson 



---
  drivers/net/ethernet/pensando/ionic/ionic_stats.c |  145 +
  1 file changed, 60 insertions(+), 85 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c 
b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
index 6ae75b771a15..1dac960386df 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
@@ -246,98 +246,73 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
return total;
  }
  
+static void ionic_sw_stats_get_tx_strings(struct ionic_lif *lif, u8 **buf,

+ int q_num)
+{
+   int i;
+
+   for (i = 0; i < IONIC_NUM_TX_STATS; i++)
+   ethtool_gsprintf(buf, "tx_%d_%s", q_num,
+ionic_tx_stats_desc[i].name);
+
+   if (!test_bit(IONIC_LIF_F_UP, lif->state) ||
+   !test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
+   return;
+
+   for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++)
+   ethtool_gsprintf(buf, "txq_%d_%s", q_num,
+ionic_txq_stats_desc[i].name);
+   for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++)
+   ethtool_gsprintf(buf, "txq_%d_cq_%s", q_num,
+ionic_dbg_cq_stats_desc[i].name);
+   for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++)
+   ethtool_gsprintf(buf, "txq_%d_intr_%s", q_num,
+ionic_dbg_intr_stats_desc[i].name);
+   for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++)
+   ethtool_gsprintf(buf, "txq_%d_sg_cntr_%d", q_num, i);
+}
+
+static void ionic_sw_stats_get_rx_strings(struct ionic_lif *lif, u8 **buf,
+ int q_num)
+{
+   int i;
+
+   for (i = 0; i < IONIC_NUM_RX_STATS; i++)
+   ethtool_gsprintf(buf, "rx_%d_%s", q_num,
+ionic_rx_stats_desc[i].name);
+
+   if (!test_bit(IONIC_LIF_F_UP, lif->state) ||
+   !test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
+   return;
+
+   for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++)
+   ethtool_gsprintf(buf, "rxq_%d_cq_%s", q_num,
+ionic_dbg_cq_stats_desc[i].name);
+   for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++)
+   ethtool_gsprintf(buf, "rxq_%d_intr_%s", q_num,
+ionic_dbg_intr_stats_desc[i].name);
+   for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++)
+   ethtool_gsprintf(buf, "rxq_%d_napi_%s", q_num,
+ionic_dbg_napi_stats_desc[i].name);
+   for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++)
+   ethtool_gsprintf(buf, "rxq_%d_napi_work_done_%d", q_num, i);
+}
+
  static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
  {
int i, q_num;
  
-	for (i = 0; i < IONIC_NUM_LIF_STATS; i++) {

-   snprintf(*buf, ETH_GSTRING_LEN, ionic_lif_stats_desc[i].name);
-   *buf += ETH_GSTRING_LEN;
-   }
+   for (i = 0; i < IONIC_NUM_LIF_STATS; i++)
+   ethtool_gsprintf(buf, ionic_lif_stats_desc[i].name);
  
-	for (i = 0; i < IONIC_NUM_PORT_STATS; i++) {

-   snprintf(*buf, ETH_GSTRING_LEN,
-ionic_port_stats_desc[i].name);
-   *buf += ETH_GSTRING_LEN;
-   }
+   for (i = 0; i < IONIC_NUM_PORT_STATS; i++)
+   ethtool_gsprintf(buf, ionic_port_stats_desc[i].name);
  
-	for (q_num = 0; q_num < MAX_Q(lif); q_num++) {

-   for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
-   snprintf(*buf, ETH_GSTRING_LEN, "tx_%d_%s",
-q_num, ionic_tx_stats_desc[i].name);
-   *buf += ETH_GSTRING_LEN;
-   }
+   for (q_num = 0; q_num < MAX_Q(lif); q_num++)
+   ionic_sw_stats_get_tx_strings(lif, buf, q_num);
  
-		if (test_bit(IONIC_LIF_F_UP, lif->state) &&

-   test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
-   for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
-   snprintf(*buf, ETH_GSTRING_LEN,
-"txq_%d_%s",
-q_num,
-ionic_txq_stats_desc[i].name);
-   *buf += ETH_GSTRING_LEN;
-  

[PATCH net-next 6/6] ionic: simplify use of completion types

2021-03-10 Thread Shannon Nelson
Make better use of our struct types and type checking by passing
the actual Rx or Tx completion type rather than a generic void
pointer type.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index cd2540ff9251..c63e6e7aa47b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -125,9 +125,8 @@ static bool ionic_rx_buf_recycle(struct ionic_queue *q,
 
 static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
  struct ionic_desc_info *desc_info,
- struct ionic_cq_info *cq_info)
+ struct ionic_rxq_comp *comp)
 {
-   struct ionic_rxq_comp *comp = cq_info->cq_desc;
struct net_device *netdev = q->lif->netdev;
struct ionic_buf_info *buf_info;
struct ionic_rx_stats *stats;
@@ -155,9 +154,6 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
i = comp->num_sg_elems + 1;
do {
if (unlikely(!buf_info->page)) {
-   struct napi_struct *napi = &q_to_qcq(q)->napi;
-
-   napi->skb = NULL;
dev_kfree_skb(skb);
return NULL;
}
@@ -189,9 +185,8 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
 
 static struct sk_buff *ionic_rx_copybreak(struct ionic_queue *q,
  struct ionic_desc_info *desc_info,
- struct ionic_cq_info *cq_info)
+ struct ionic_rxq_comp *comp)
 {
-   struct ionic_rxq_comp *comp = cq_info->cq_desc;
struct net_device *netdev = q->lif->netdev;
struct ionic_buf_info *buf_info;
struct ionic_rx_stats *stats;
@@ -234,7 +229,7 @@ static void ionic_rx_clean(struct ionic_queue *q,
   struct ionic_cq_info *cq_info,
   void *cb_arg)
 {
-   struct ionic_rxq_comp *comp = cq_info->cq_desc;
+   struct ionic_rxq_comp *comp = cq_info->rxcq;
struct net_device *netdev = q->lif->netdev;
struct ionic_qcq *qcq = q_to_qcq(q);
struct ionic_rx_stats *stats;
@@ -251,9 +246,9 @@ static void ionic_rx_clean(struct ionic_queue *q,
stats->bytes += le16_to_cpu(comp->len);
 
if (le16_to_cpu(comp->len) <= q->lif->rx_copybreak)
-   skb = ionic_rx_copybreak(q, desc_info, cq_info);
+   skb = ionic_rx_copybreak(q, desc_info, comp);
else
-   skb = ionic_rx_frags(q, desc_info, cq_info);
+   skb = ionic_rx_frags(q, desc_info, comp);
 
if (unlikely(!skb)) {
stats->dropped++;
@@ -309,7 +304,7 @@ static void ionic_rx_clean(struct ionic_queue *q,
 
 static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info 
*cq_info)
 {
-   struct ionic_rxq_comp *comp = cq_info->cq_desc;
+   struct ionic_rxq_comp *comp = cq_info->rxcq;
struct ionic_queue *q = cq->bound_q;
struct ionic_desc_info *desc_info;
 
@@ -661,7 +656,7 @@ static void ionic_tx_clean(struct ionic_queue *q,
 
 static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info 
*cq_info)
 {
-   struct ionic_txq_comp *comp = cq_info->cq_desc;
+   struct ionic_txq_comp *comp = cq_info->txcq;
struct ionic_queue *q = cq->bound_q;
struct ionic_desc_info *desc_info;
u16 index;
-- 
2.17.1



[PATCH net-next 5/6] ionic: rebuild debugfs on qcq swap

2021-03-10 Thread Shannon Nelson
With a reconfigure of each queue is needed a rebuild of
the matching debugfs information.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 6f8a5daaadfa..48d3c7685b6c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2204,6 +2204,9 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct 
ionic_qcq *b)
swap(a->cq_base,  b->cq_base);
swap(a->cq_base_pa,   b->cq_base_pa);
swap(a->cq_size,  b->cq_size);
+
+   ionic_debugfs_del_qcq(a);
+   ionic_debugfs_add_qcq(a->q.lif, a);
 }
 
 int ionic_reconfigure_queues(struct ionic_lif *lif,
-- 
2.17.1



[PATCH net-next 4/6] ionic: simplify rx skb alloc

2021-03-10 Thread Shannon Nelson
Remove an unnecessary layer over rx skb allocation.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 63 +++
 1 file changed, 22 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index c472c14b3a80..cd2540ff9251 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -10,12 +10,6 @@
 #include "ionic_lif.h"
 #include "ionic_txrx.h"
 
-static void ionic_rx_clean(struct ionic_queue *q,
-  struct ionic_desc_info *desc_info,
-  struct ionic_cq_info *cq_info,
-  void *cb_arg);
-
-static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info 
*cq_info);
 
 static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info 
*cq_info);
 
@@ -40,32 +34,6 @@ static inline struct netdev_queue *q_to_ndq(struct 
ionic_queue *q)
return netdev_get_tx_queue(q->lif->netdev, q->index);
 }
 
-static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue *q,
- unsigned int len, bool frags)
-{
-   struct ionic_lif *lif = q->lif;
-   struct ionic_rx_stats *stats;
-   struct net_device *netdev;
-   struct sk_buff *skb;
-
-   netdev = lif->netdev;
-   stats = &q->lif->rxqstats[q->index];
-
-   if (frags)
-   skb = napi_get_frags(&q_to_qcq(q)->napi);
-   else
-   skb = napi_alloc_skb(&q_to_qcq(q)->napi, len);
-
-   if (unlikely(!skb)) {
-   net_warn_ratelimited("%s: SKB alloc failed on %s!\n",
-netdev->name, q->name);
-   stats->alloc_err++;
-   return NULL;
-   }
-
-   return skb;
-}
-
 static void ionic_rx_buf_reset(struct ionic_buf_info *buf_info)
 {
buf_info->page = NULL;
@@ -76,12 +44,10 @@ static void ionic_rx_buf_reset(struct ionic_buf_info 
*buf_info)
 static int ionic_rx_page_alloc(struct ionic_queue *q,
   struct ionic_buf_info *buf_info)
 {
-   struct ionic_lif *lif = q->lif;
+   struct net_device *netdev = q->lif->netdev;
struct ionic_rx_stats *stats;
-   struct net_device *netdev;
struct device *dev;
 
-   netdev = lif->netdev;
dev = q->dev;
stats = q_to_rx_stats(q);
 
@@ -162,21 +128,29 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue 
*q,
  struct ionic_cq_info *cq_info)
 {
struct ionic_rxq_comp *comp = cq_info->cq_desc;
+   struct net_device *netdev = q->lif->netdev;
struct ionic_buf_info *buf_info;
+   struct ionic_rx_stats *stats;
struct device *dev = q->dev;
struct sk_buff *skb;
unsigned int i;
u16 frag_len;
u16 len;
 
+   stats = q_to_rx_stats(q);
+
buf_info = &desc_info->bufs[0];
len = le16_to_cpu(comp->len);
 
prefetch(buf_info->page);
 
-   skb = ionic_rx_skb_alloc(q, len, true);
-   if (unlikely(!skb))
+   skb = napi_get_frags(&q_to_qcq(q)->napi);
+   if (unlikely(!skb)) {
+   net_warn_ratelimited("%s: SKB alloc failed on %s!\n",
+netdev->name, q->name);
+   stats->alloc_err++;
return NULL;
+   }
 
i = comp->num_sg_elems + 1;
do {
@@ -218,17 +192,25 @@ static struct sk_buff *ionic_rx_copybreak(struct 
ionic_queue *q,
  struct ionic_cq_info *cq_info)
 {
struct ionic_rxq_comp *comp = cq_info->cq_desc;
+   struct net_device *netdev = q->lif->netdev;
struct ionic_buf_info *buf_info;
+   struct ionic_rx_stats *stats;
struct device *dev = q->dev;
struct sk_buff *skb;
u16 len;
 
+   stats = q_to_rx_stats(q);
+
buf_info = &desc_info->bufs[0];
len = le16_to_cpu(comp->len);
 
-   skb = ionic_rx_skb_alloc(q, len, false);
-   if (unlikely(!skb))
+   skb = napi_alloc_skb(&q_to_qcq(q)->napi, len);
+   if (unlikely(!skb)) {
+   net_warn_ratelimited("%s: SKB alloc failed on %s!\n",
+netdev->name, q->name);
+   stats->alloc_err++;
return NULL;
+   }
 
if (unlikely(!buf_info->page)) {
dev_kfree_skb(skb);
@@ -253,13 +235,12 @@ static void ionic_rx_clean(struct ionic_queue *q,
   void *cb_arg)
 {
struct ionic_rxq_comp *comp = cq_info->cq_desc;
+   struct net_device *netdev = q->lif->netdev;
struct ionic_qcq *qcq = q_to_qcq(q);
struct ion

[PATCH net-next 1/6] ionic: move rx_page_alloc and free

2021-03-10 Thread Shannon Nelson
Move ionic_rx_page_alloc() and ionic_rx_page_free() to earlier
in the file to make the next patch easier to review.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 140 +-
 1 file changed, 70 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 162a1ff1e9d2..70b997f302ac 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -66,6 +66,76 @@ static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue 
*q,
return skb;
 }
 
+static int ionic_rx_page_alloc(struct ionic_queue *q,
+  struct ionic_page_info *page_info)
+{
+   struct ionic_lif *lif = q->lif;
+   struct ionic_rx_stats *stats;
+   struct net_device *netdev;
+   struct device *dev;
+
+   netdev = lif->netdev;
+   dev = lif->ionic->dev;
+   stats = q_to_rx_stats(q);
+
+   if (unlikely(!page_info)) {
+   net_err_ratelimited("%s: %s invalid page_info in alloc\n",
+   netdev->name, q->name);
+   return -EINVAL;
+   }
+
+   page_info->page = dev_alloc_page();
+   if (unlikely(!page_info->page)) {
+   net_err_ratelimited("%s: %s page alloc failed\n",
+   netdev->name, q->name);
+   stats->alloc_err++;
+   return -ENOMEM;
+   }
+
+   page_info->dma_addr = dma_map_page(dev, page_info->page, 0, PAGE_SIZE,
+  DMA_FROM_DEVICE);
+   if (unlikely(dma_mapping_error(dev, page_info->dma_addr))) {
+   put_page(page_info->page);
+   page_info->dma_addr = 0;
+   page_info->page = NULL;
+   net_err_ratelimited("%s: %s dma map failed\n",
+   netdev->name, q->name);
+   stats->dma_map_err++;
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static void ionic_rx_page_free(struct ionic_queue *q,
+  struct ionic_page_info *page_info)
+{
+   struct ionic_lif *lif = q->lif;
+   struct net_device *netdev;
+   struct device *dev;
+
+   netdev = lif->netdev;
+   dev = lif->ionic->dev;
+
+   if (unlikely(!page_info)) {
+   net_err_ratelimited("%s: %s invalid page_info in free\n",
+   netdev->name, q->name);
+   return;
+   }
+
+   if (unlikely(!page_info->page)) {
+   net_err_ratelimited("%s: %s invalid page in free\n",
+   netdev->name, q->name);
+   return;
+   }
+
+   dma_unmap_page(dev, page_info->dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
+
+   put_page(page_info->page);
+   page_info->dma_addr = 0;
+   page_info->page = NULL;
+}
+
 static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
  struct ionic_desc_info *desc_info,
  struct ionic_cq_info *cq_info)
@@ -253,76 +323,6 @@ static bool ionic_rx_service(struct ionic_cq *cq, struct 
ionic_cq_info *cq_info)
return true;
 }
 
-static int ionic_rx_page_alloc(struct ionic_queue *q,
-  struct ionic_page_info *page_info)
-{
-   struct ionic_lif *lif = q->lif;
-   struct ionic_rx_stats *stats;
-   struct net_device *netdev;
-   struct device *dev;
-
-   netdev = lif->netdev;
-   dev = lif->ionic->dev;
-   stats = q_to_rx_stats(q);
-
-   if (unlikely(!page_info)) {
-   net_err_ratelimited("%s: %s invalid page_info in alloc\n",
-   netdev->name, q->name);
-   return -EINVAL;
-   }
-
-   page_info->page = dev_alloc_page();
-   if (unlikely(!page_info->page)) {
-   net_err_ratelimited("%s: %s page alloc failed\n",
-   netdev->name, q->name);
-   stats->alloc_err++;
-   return -ENOMEM;
-   }
-
-   page_info->dma_addr = dma_map_page(dev, page_info->page, 0, PAGE_SIZE,
-  DMA_FROM_DEVICE);
-   if (unlikely(dma_mapping_error(dev, page_info->dma_addr))) {
-   put_page(page_info->page);
-   page_info->dma_addr = 0;
-   page_info->page = NULL;
-   net_err_ratelimited("%s: %s dma map failed\n",
-   netdev->name, q->name);
-   stats->dma_map_err++;
-   return -EIO;
-   }
-
-   return 0;
-}
-
-static void ionic

[PATCH net-next 2/6] ionic: implement Rx page reuse

2021-03-10 Thread Shannon Nelson
Rework the Rx buffer allocations to use pages twice when using
normal MTU in order to cut down on buffer allocation and mapping
overhead.

Instead of tracking individual pages, in which we may have
wasted half the space when using standard 1500 MTU, we track
buffers which use half pages, so we can use the second half
of the page rather than allocate and map a new page once the
first buffer has been used.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  12 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 215 +++---
 2 files changed, 138 insertions(+), 89 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 690768ff0143..0f877c86eba6 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -170,9 +170,15 @@ typedef void (*ionic_desc_cb)(struct ionic_queue *q,
  struct ionic_desc_info *desc_info,
  struct ionic_cq_info *cq_info, void *cb_arg);
 
-struct ionic_page_info {
+#define IONIC_PAGE_SIZEPAGE_SIZE
+#define IONIC_PAGE_SPLIT_SZ(PAGE_SIZE / 2)
+#define IONIC_PAGE_GFP_MASK(GFP_ATOMIC | __GFP_NOWARN |\
+__GFP_COMP | __GFP_MEMALLOC)
+
+struct ionic_buf_info {
struct page *page;
dma_addr_t dma_addr;
+   u32 page_offset;
 };
 
 struct ionic_desc_info {
@@ -187,8 +193,8 @@ struct ionic_desc_info {
struct ionic_txq_sg_desc *txq_sg_desc;
struct ionic_rxq_sg_desc *rxq_sgl_desc;
};
-   unsigned int npages;
-   struct ionic_page_info pages[IONIC_RX_MAX_SG_ELEMS + 1];
+   unsigned int nbufs;
+   struct ionic_buf_info bufs[IONIC_RX_MAX_SG_ELEMS + 1];
ionic_desc_cb cb;
void *cb_arg;
 };
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 70b997f302ac..3e13cfee9ecd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -54,7 +54,7 @@ static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue 
*q,
if (frags)
skb = napi_get_frags(&q_to_qcq(q)->napi);
else
-   skb = netdev_alloc_skb_ip_align(netdev, len);
+   skb = napi_alloc_skb(&q_to_qcq(q)->napi, len);
 
if (unlikely(!skb)) {
net_warn_ratelimited("%s: SKB alloc failed on %s!\n",
@@ -66,8 +66,15 @@ static struct sk_buff *ionic_rx_skb_alloc(struct ionic_queue 
*q,
return skb;
 }
 
+static void ionic_rx_buf_reset(struct ionic_buf_info *buf_info)
+{
+   buf_info->page = NULL;
+   buf_info->page_offset = 0;
+   buf_info->dma_addr = 0;
+}
+
 static int ionic_rx_page_alloc(struct ionic_queue *q,
-  struct ionic_page_info *page_info)
+  struct ionic_buf_info *buf_info)
 {
struct ionic_lif *lif = q->lif;
struct ionic_rx_stats *stats;
@@ -78,26 +85,26 @@ static int ionic_rx_page_alloc(struct ionic_queue *q,
dev = lif->ionic->dev;
stats = q_to_rx_stats(q);
 
-   if (unlikely(!page_info)) {
-   net_err_ratelimited("%s: %s invalid page_info in alloc\n",
+   if (unlikely(!buf_info)) {
+   net_err_ratelimited("%s: %s invalid buf_info in alloc\n",
netdev->name, q->name);
return -EINVAL;
}
 
-   page_info->page = dev_alloc_page();
-   if (unlikely(!page_info->page)) {
+   buf_info->page = alloc_pages(IONIC_PAGE_GFP_MASK, 0);
+   if (unlikely(!buf_info->page)) {
net_err_ratelimited("%s: %s page alloc failed\n",
netdev->name, q->name);
stats->alloc_err++;
return -ENOMEM;
}
+   buf_info->page_offset = 0;
 
-   page_info->dma_addr = dma_map_page(dev, page_info->page, 0, PAGE_SIZE,
-  DMA_FROM_DEVICE);
-   if (unlikely(dma_mapping_error(dev, page_info->dma_addr))) {
-   put_page(page_info->page);
-   page_info->dma_addr = 0;
-   page_info->page = NULL;
+   buf_info->dma_addr = dma_map_page(dev, buf_info->page, 
buf_info->page_offset,
+ IONIC_PAGE_SIZE, DMA_FROM_DEVICE);
+   if (unlikely(dma_mapping_error(dev, buf_info->dma_addr))) {
+   __free_pages(buf_info->page, 0);
+   ionic_rx_buf_reset(buf_info);
net_err_ratelimited("%s: %s dma map failed\n",
netdev->

[PATCH net-next 0/6] ionic Rx updates

2021-03-10 Thread Shannon Nelson
The ionic driver's Rx path is due for an overhaul in order to
better use memory buffers and to clean up the data structures.

The first two patches convert the driver to using page sharing
between buffers so as to lessen the  page alloc and free overhead.

The remaining patches clean up the structs and fastpath code for
better efficency.

Shannon Nelson (6):
  ionic: move rx_page_alloc and free
  ionic: implement Rx page reuse
  ionic: optimize fastpath struct usage
  ionic: simplify rx skb alloc
  ionic: rebuild debugfs on qcq swap
  ionic: simplify use of completion types

 .../net/ethernet/pensando/ionic/ionic_dev.c   |   4 +-
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  19 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |   6 +-
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  22 +-
 .../net/ethernet/pensando/ionic/ionic_main.c  |   4 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 374 +-
 6 files changed, 226 insertions(+), 203 deletions(-)

-- 
2.17.1



[PATCH net-next 3/6] ionic: optimize fastpath struct usage

2021-03-10 Thread Shannon Nelson
Clean up a couple of struct uses to make for better fast path
access.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.c   |  4 +--
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  7 ++--
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  3 +-
 .../net/ethernet/pensando/ionic/ionic_lif.h   | 22 ++---
 .../net/ethernet/pensando/ionic/ionic_main.c  |  4 +--
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 33 +--
 6 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index fb2b5bf179d7..b951bf5bbdc4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -585,9 +585,9 @@ void ionic_q_sg_map(struct ionic_queue *q, void *base, 
dma_addr_t base_pa)
 void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,
  void *cb_arg)
 {
-   struct device *dev = q->lif->ionic->dev;
struct ionic_desc_info *desc_info;
struct ionic_lif *lif = q->lif;
+   struct device *dev = q->dev;
 
desc_info = &q->info[q->head_idx];
desc_info->cb = cb;
@@ -629,7 +629,7 @@ void ionic_q_service(struct ionic_queue *q, struct 
ionic_cq_info *cq_info,
 
/* stop index must be for a descriptor that is not yet completed */
if (unlikely(!ionic_q_is_posted(q, stop_index)))
-   dev_err(q->lif->ionic->dev,
+   dev_err(q->dev,
"ionic stop is not posted %s stop %u tail %u head %u\n",
q->name, stop_index, q->tail_idx, q->head_idx);
 
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 0f877c86eba6..339824cfd618 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -205,10 +205,12 @@ struct ionic_queue {
struct device *dev;
struct ionic_lif *lif;
struct ionic_desc_info *info;
+   u64 dbval;
u16 head_idx;
u16 tail_idx;
unsigned int index;
unsigned int num_descs;
+   unsigned int max_sg_elems;
u64 dbell_count;
u64 stop;
u64 wake;
@@ -217,7 +219,6 @@ struct ionic_queue {
unsigned int type;
unsigned int hw_index;
unsigned int hw_type;
-   u64 dbval;
union {
void *base;
struct ionic_txq_desc *txq;
@@ -235,7 +236,7 @@ struct ionic_queue {
unsigned int sg_desc_size;
unsigned int pid;
char name[IONIC_QUEUE_NAME_MAX_SZ];
-};
+} cacheline_aligned_in_smp;
 
 #define IONIC_INTR_INDEX_NOT_ASSIGNED  -1
 #define IONIC_INTR_NAME_MAX_SZ 32
@@ -262,7 +263,7 @@ struct ionic_cq {
u64 compl_count;
void *base;
dma_addr_t base_pa;
-};
+} cacheline_aligned_in_smp;
 
 struct ionic;
 
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 11140915c2da..6f8a5daaadfa 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -495,6 +495,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned 
int type,
goto err_out;
}
 
+   new->q.dev = dev;
new->flags = flags;
 
new->q.info = devm_kcalloc(dev, num_descs, sizeof(*new->q.info),
@@ -506,6 +507,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned 
int type,
}
 
new->q.type = type;
+   new->q.max_sg_elems = lif->qtype_info[type].max_sg_elems;
 
err = ionic_q_init(lif, idev, &new->q, index, name, num_descs,
   desc_size, sg_desc_size, pid);
@@ -2450,7 +2452,6 @@ int ionic_lif_alloc(struct ionic *ionic)
lif->index = 0;
lif->ntxq_descs = IONIC_DEF_TXRX_DESC;
lif->nrxq_descs = IONIC_DEF_TXRX_DESC;
-   lif->tx_budget = IONIC_TX_BUDGET_DEFAULT;
 
/* Convert the default coalesce value to actual hw resolution */
lif->rx_coalesce_usecs = IONIC_ITR_COAL_USEC_DEFAULT;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 563dba384a53..8ffda32a0a7d 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -159,16 +159,11 @@ struct ionic_qtype_info {
 
 #define IONIC_LIF_NAME_MAX_SZ  32
 struct ionic_lif {
-   char name[IONIC_LIF_NAME_MAX_SZ];
-   struct list_head list;
struct net_device *netdev;
DECLARE_BITMAP(state, IONIC_LIF_F_STATE_SIZE);
struct ionic *ionic;
-   bool registered;
unsigned int index;
unsigned int hw_index;
-   unsigned int kern_pid;

Re: [PATCH] ionic: Remove unused function pointer typedef ionic_reset_cb

2021-02-16 Thread Shannon Nelson

On 2/15/21 8:05 PM, Chen Lin wrote:

From: Chen Lin 

Remove the 'ionic_reset_cb' typedef as it is not used.

Signed-off-by: Chen Lin 
---
  drivers/net/ethernet/pensando/ionic/ionic_lif.h |2 --
  1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 9bed427..563dba3 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -249,8 +249,6 @@ static inline u32 ionic_coal_usec_to_hw(struct ionic 
*ionic, u32 usecs)
return (usecs * mult) / div;
  }
  
-typedef void (*ionic_reset_cb)(struct ionic_lif *lif, void *arg);

-
  void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep);
  void ionic_get_stats64(struct net_device *netdev,
   struct rtnl_link_stats64 *ns);


Yep - thanks.

Acked-by: Shannon Nelson 



Re: [PATCH net-next 1/6] net: add inline function skb_csum_is_sctp

2021-01-19 Thread Shannon Nelson

On 1/19/21 2:23 PM, Alexander Duyck wrote:

On Fri, Jan 15, 2021 at 10:13 PM Xin Long  wrote:

This patch is to define a inline function skb_csum_is_sctp(), and
also replace all places where it checks if it's a SCTP CSUM skb.
This function would be used later in many networking drivers in
the following patches.

Suggested-by: Alexander Duyck 
Signed-off-by: Xin Long 

One minor nit. If you had to resubmit this I might move the ionic
driver code into a separate patch. However It can probably be accepted
as is.

Reviewed-by: Alexander Duyck 


Alex has a good point - if you repost, please split out the ionic bits 
to a separate patch.


Either way, for ionic:
Acked-by: Shannon Nelson 



---
  drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 2 +-
  include/linux/skbuff.h   | 5 +
  net/core/dev.c   | 2 +-
  3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index ac4cd5d..162a1ff 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -979,7 +979,7 @@ static int ionic_tx_calc_csum(struct ionic_queue *q, struct 
sk_buff *skb)
 stats->vlan_inserted++;
 }

-   if (skb->csum_not_inet)
+   if (skb_csum_is_sctp(skb))
 stats->crc32_csum++;
 else
 stats->csum++;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c9568cf..46f901a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -4621,6 +4621,11 @@ static inline void skb_reset_redirect(struct sk_buff 
*skb)
  #endif
  }

+static inline bool skb_csum_is_sctp(struct sk_buff *skb)
+{
+   return skb->csum_not_inet;
+}
+
  static inline void skb_set_kcov_handle(struct sk_buff *skb,
const u64 kcov_handle)
  {
diff --git a/net/core/dev.c b/net/core/dev.c
index 0a31d4e..bbd306f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3617,7 +3617,7 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff 
*skb,
  int skb_csum_hwoffload_help(struct sk_buff *skb,
 const netdev_features_t features)
  {
-   if (unlikely(skb->csum_not_inet))
+   if (unlikely(skb_csum_is_sctp(skb)))
 return !!(features & NETIF_F_SCTP_CRC) ? 0 :
 skb_crc32c_csum_help(skb);

--
2.1.0





Re: [PATCH net-next v1 1/2] net: core: count drops from GRO

2021-01-08 Thread Shannon Nelson

On 1/8/21 10:26 AM, Jesse Brandeburg wrote:

Shannon Nelson wrote:


On 1/6/21 1:55 PM, Jesse Brandeburg wrote:

When drivers call the various receive upcalls to receive an skb
to the stack, sometimes that stack can drop the packet. The good
news is that the return code is given to all the drivers of
NET_RX_DROP or GRO_DROP. The bad news is that no drivers except
the one "ice" driver that I changed, check the stat and increment

If the stack is dropping the packet, isn't it up to the stack to track
that, perhaps with something that shows up in netstat -s?  We don't
really want to make the driver responsible for any drops that happen
above its head, do we?

I totally agree!

In patch 2/2 I revert the driver-specific changes I had made in an
earlier patch, and this patch *was* my effort to make the stack show the
drops.

Maybe I wasn't clear. I'm seeing packets disappear during TCP
workloads, and this GRO_DROP code was the source of the drops (I see it
returning infrequently but regularly)

The driver processes the packet but the stack never sees it, and there
were no drop counters anywhere tracking it.



My point is that the patch increments a netdev counter, which to my mind 
immediately implicates the driver and hardware, rather than the stack.  
As a driver maintainer, I don't want to be chasing driver packet drop 
reports that are a stack problem.  I'd rather see a new counter in 
netstat -s that reflects the stack decision and can better imply what 
went wrong.  I don't have a good suggestion for a counter name at the 
moment.


I guess part of the issue is that this is right on the boundary of 
driver-stack.  But if we follow Eric's suggestions, maybe the problem 
magically goes away :-) .


sln



Re: [PATCH net-next v1 1/2] net: core: count drops from GRO

2021-01-07 Thread Shannon Nelson

On 1/6/21 1:55 PM, Jesse Brandeburg wrote:

When drivers call the various receive upcalls to receive an skb
to the stack, sometimes that stack can drop the packet. The good
news is that the return code is given to all the drivers of
NET_RX_DROP or GRO_DROP. The bad news is that no drivers except
the one "ice" driver that I changed, check the stat and increment


If the stack is dropping the packet, isn't it up to the stack to track 
that, perhaps with something that shows up in netstat -s?  We don't 
really want to make the driver responsible for any drops that happen 
above its head, do we?


sln


the dropped count. This is currently leading to packets that
arrive at the edge interface and are fully handled by the driver
and then mysteriously disappear.

Rather than fix all drivers to increment the drop stat when
handling the return code, emulate the already existing statistic
update for NET_RX_DROP events for the two GRO_DROP locations, and
increment the dev->rx_dropped associated with the skb.

Signed-off-by: Jesse Brandeburg 
Cc: Eric Dumazet 
Cc: Jamal Hadi Salim 
---
  net/core/dev.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index 8fa739259041..ef34043a9550 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6071,6 +6071,7 @@ static gro_result_t napi_skb_finish(struct napi_struct 
*napi,
break;
  
  	case GRO_DROP:

+   atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
break;
  
@@ -6159,6 +6160,7 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi,

break;
  
  	case GRO_DROP:

+   atomic_long_inc(&skb->dev->rx_dropped);
napi_reuse_skb(napi, skb);
break;
  




[PATCH net] ionic: account for vlan tag len in rx buffer len

2020-12-18 Thread Shannon Nelson
Let the FW know we have enough receive buffer space for the
vlan tag if it isn't stripped.

Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 9156c9825a16..ac4cd5d82e69 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -337,7 +337,7 @@ void ionic_rx_fill(struct ionic_queue *q)
unsigned int i, j;
unsigned int len;
 
-   len = netdev->mtu + ETH_HLEN;
+   len = netdev->mtu + ETH_HLEN + VLAN_HLEN;
nfrags = round_up(len, PAGE_SIZE) / PAGE_SIZE;
 
for (i = ionic_q_space_avail(q); i; i--) {
-- 
2.17.1



Re: [PATCH net-next] drivers: net: ionic: simplify the return expression of ionic_set_rxfh()

2020-12-09 Thread Shannon Nelson

On 12/8/20 5:53 AM, Zheng Yongjun wrote:

Simplify the return expression.

Signed-off-by: Zheng Yongjun 


Acked-by: Shannon Nelson 


---
  drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 7 +--
  1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c 
b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 35c72d4a78b3..0832bedcb3b4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -738,16 +738,11 @@ static int ionic_set_rxfh(struct net_device *netdev, 
const u32 *indir,
  const u8 *key, const u8 hfunc)
  {
struct ionic_lif *lif = netdev_priv(netdev);
-   int err;
  
  	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)

return -EOPNOTSUPP;
  
-	err = ionic_lif_rss_config(lif, lif->rss_types, key, indir);

-   if (err)
-   return err;
-
-   return 0;
+   return ionic_lif_rss_config(lif, lif->rss_types, key, indir);
  }
  
  static int ionic_set_tunable(struct net_device *dev,




Re: [PATCH 1/1] fix possible array overflow on receiving too many fragments for a packet

2020-12-09 Thread Shannon Nelson

On 12/7/20 8:06 PM, Xiaohui Zhang wrote:

From: Zhang Xiaohui 

If the hardware receives an oversized packet with too many rx fragments,
skb_shinfo(skb)->frags can overflow and corrupt memory of adjacent pages.
This becomes especially visible if it corrupts the freelist pointer of
a slab page.
I found these two code fragments were very similar to the vulnerable code
in CVE-2020-12465, so I submitted these two patches.

Signed-off-by: Zhang Xiaohui 
---
  drivers/net/ethernet/intel/ice/ice_txrx.c| 4 +++-
  drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 4 +++-
  2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c 
b/drivers/net/ethernet/intel/ice/ice_txrx.c
index eae75260f..f0a252208 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -821,9 +821,11 @@ ice_add_rx_frag(struct ice_ring *rx_ring, struct 
ice_rx_buf *rx_buf,
unsigned int truesize = ice_rx_pg_size(rx_ring) / 2;
  #endif
  
+	struct skb_shared_info *shinfo = skb_shinfo(skb);


This declaration should be up directly below the #endif and a blank line 
inserted before the code.



if (!size)
return;
-   skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buf->page,
+   if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags))
+   skb_add_rx_frag(skb, shinfo, rx_buf->page,
rx_buf->page_offset, size, truesize);
  
  	/* page is being used so we must update the page offset */

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 169ac4f54..d30e83a4b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -74,6 +74,7 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
struct device *dev = q->lif->ionic->dev;
struct ionic_page_info *page_info;
struct sk_buff *skb;
+   struct skb_shared_info *shinfo = skb_shinfo(skb);


As the kernel test robot has suggested, this is using an uninitialized 
skb and will likely cause great unhappiness.


Also, this needs to follow the "reverse xmas tree" formatting style for 
declarations.




unsigned int i;
u16 frag_len;
u16 len;
@@ -102,7 +103,8 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
  
  		dma_unmap_page(dev, dma_unmap_addr(page_info, dma_addr),

   PAGE_SIZE, DMA_FROM_DEVICE);
-   skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+   if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags))
+   skb_add_rx_frag(skb, shinfo->nr_frags,
page_info->page, 0, frag_len, PAGE_SIZE);


I'm still not convinced this is necessary here, and I'm still not 
thrilled with the result of just quietly dropping the fragments.


A better answer here might be to check the ARRAY_SIZE against 
comp->num_sg_elements before allocating the skb, and if too big, then 
return NULL - this gets the check done before any allocations are made, 
and the packet will be properly dropped and the drop statistic incremented.


sln


page_info->page = NULL;
page_info++;




Re: [PATCH 1/1] ionic: fix array overflow on receiving too many fragments for a packet

2020-12-06 Thread Shannon Nelson

On 12/6/20 5:51 PM, Jesse Brandeburg wrote:

Xiaohui Zhang wrote:


From: Zhang Xiaohui 

If the hardware receives an oversized packet with too many rx fragments,
skb_shinfo(skb)->frags can overflow and corrupt memory of adjacent pages.
This becomes especially visible if it corrupts the freelist pointer of
a slab page.

Signed-off-by: Zhang Xiaohui 

Hi, thanks for your patch.

It appears this is a part of a series of patches (at least this one and
one to the ice driver) - please send as one series, with a cover letter
explanation.

Please justify how this is a bug and how this is found / reproduced.

I'll respond separately to the ice driver patch as I don't know this
hardware and it's limits, but I suspect that you've tried to fix a bug
where there was none. (It seems like something a code scanner might find
and be confused about)


---
  drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 169ac4f54..a3e274c65 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -102,8 +102,12 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue 
*q,
  
  		dma_unmap_page(dev, dma_unmap_addr(page_info, dma_addr),

   PAGE_SIZE, DMA_FROM_DEVICE);
-   skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+   struct skb_shared_info *shinfo = skb_shinfo(skb);

you can't declare variables in the middle of a code flow in C, did you
compile this?


+
+   if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) {
+   skb_add_rx_frag(skb, shinfo->nr_frags,
page_info->page, 0, frag_len, PAGE_SIZE);
+   }


Is this just dropping the remaining frags without dropping the rest of 
the skb?  Is this going to leave an incorrect length in the skb?


A single statement after the 'if' doesn't need {}'s

This might be better handled by making sure ahead of time in 
configuration that the HW doesn't do this, rather than add a test into 
the fast path.  As it is, between the definitions of shinfo->frags[] and 
the ionic's rx sg list, I don't think this is a possible error.


As Jesse suggests, I'd like to see the test case so i can add it to our 
internal testing.


Thanks,
sln


page_info->page = NULL;
page_info++;
i--;






[PATCH net-next 1/2] ionic: remove some unnecessary oom messages

2020-11-30 Thread Shannon Nelson
Remove memory allocation fail messages where the OOM stack
trace will make it obvious which allocation request failed.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_dev.c  | 2 +-
 drivers/net/ethernet/pensando/ionic/ionic_lif.c  | 8 +++-
 drivers/net/ethernet/pensando/ionic/ionic_main.c | 4 +---
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index 318db5f77fdb..fb2b5bf179d7 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -142,7 +142,7 @@ int ionic_heartbeat_check(struct ionic *ionic)
 
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
-   dev_err(ionic->dev, "%s OOM\n", __func__);
+   dev_err(ionic->dev, "LIF reset trigger 
dropped\n");
} else {
work->type = IONIC_DW_TYPE_LIF_RESET;
if (fw_status & IONIC_FW_STS_F_RUNNING &&
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 0afec2fa572d..0b7f2def423c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -842,7 +842,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
case IONIC_EVENT_RESET:
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   netdev_err(lif->netdev, "Reset event dropped\n");
} else {
work->type = IONIC_DW_TYPE_LIF_RESET;
ionic_lif_deferred_enqueue(&lif->deferred, work);
@@ -1051,10 +1051,8 @@ static int ionic_lif_addr(struct ionic_lif *lif, const 
u8 *addr, bool add,
 
if (!can_sleep) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
-   if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   if (!work)
return -ENOMEM;
-   }
work->type = add ? IONIC_DW_TYPE_RX_ADDR_ADD :
   IONIC_DW_TYPE_RX_ADDR_DEL;
memcpy(work->addr, addr, ETH_ALEN);
@@ -1183,7 +1181,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool can_sleep)
if (!can_sleep) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   netdev_err(lif->netdev, "rxmode change 
dropped\n");
return;
}
work->type = IONIC_DW_TYPE_RX_MODE;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c 
b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index d355676f6c16..fbc57de6683e 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
@@ -511,10 +511,8 @@ int ionic_port_init(struct ionic *ionic)
 idev->port_info_sz,
 &idev->port_info_pa,
 GFP_KERNEL);
-   if (!idev->port_info) {
-   dev_err(ionic->dev, "Failed to allocate port info\n");
+   if (!idev->port_info)
return -ENOMEM;
-   }
}
 
sz = min(sizeof(ident->port.config), sizeof(idev->dev_cmd_regs->data));
-- 
2.17.1



[PATCH net-next 2/2] ionic: change mtu after queues are stopped

2020-11-30 Thread Shannon Nelson
Order of operations is slightly more correct in the driver
to change the netdev->mtu after the queues have been stopped
rather than before.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 0b7f2def423c..11140915c2da 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1465,12 +1465,14 @@ static int ionic_change_mtu(struct net_device *netdev, 
int new_mtu)
if (err)
return err;
 
-   netdev->mtu = new_mtu;
/* if we're not running, nothing more to do */
-   if (!netif_running(netdev))
+   if (!netif_running(netdev)) {
+   netdev->mtu = new_mtu;
return 0;
+   }
 
ionic_stop_queues_reconfig(lif);
+   netdev->mtu = new_mtu;
return ionic_start_queues_reconfig(lif);
 }
 
-- 
2.17.1



[PATCH net-next 0/2] ionic updates

2020-11-30 Thread Shannon Nelson
These are a pair of small code cleanups.

Shannon Nelson (2):
  ionic: remove some unnecessary oom messages
  ionic: change mtu after queues are stopped

 drivers/net/ethernet/pensando/ionic/ionic_dev.c  |  2 +-
 drivers/net/ethernet/pensando/ionic/ionic_lif.c  | 14 +++---
 drivers/net/ethernet/pensando/ionic/ionic_main.c |  4 +---
 3 files changed, 9 insertions(+), 11 deletions(-)

-- 
2.17.1



Re: [PATCH net-next] net: don't include ethtool.h from netdevice.h

2020-11-20 Thread Shannon Nelson

On 11/20/20 2:13 PM, Jakub Kicinski wrote:

linux/netdevice.h is included in very many places, touching any
of its dependecies causes large incremental builds.

Drop the linux/ethtool.h include, linux/netdevice.h just needs
a forward declaration of struct ethtool_ops.

Fix all the places which made use of this implicit include.

Signed-off-by: Jakub Kicinski 
---
  drivers/isdn/capi/capi.c | 1 +
  drivers/media/pci/ttpci/av7110_av.c  | 1 +
  drivers/net/bonding/bond_procfs.c| 1 +
  drivers/net/can/usb/gs_usb.c | 1 +
  drivers/net/ethernet/amazon/ena/ena_ethtool.c| 1 +
  drivers/net/ethernet/aquantia/atlantic/aq_nic.h  | 2 ++
  drivers/net/ethernet/broadcom/bnxt/bnxt.h| 1 +
  drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c  | 1 +
  drivers/net/ethernet/cavium/liquidio/lio_ethtool.c   | 1 +
  drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c  | 1 +
  drivers/net/ethernet/chelsio/cxgb4/cxgb4.h   | 1 +
  drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c   | 1 +
  drivers/net/ethernet/google/gve/gve_ethtool.c| 1 +
  drivers/net/ethernet/hisilicon/hns3/hnae3.h  | 1 +
  drivers/net/ethernet/huawei/hinic/hinic_port.h   | 1 +
  drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 1 +
  drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 1 +
  drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 +
  drivers/net/ethernet/mellanox/mlxsw/spectrum.h   | 1 +
  drivers/net/ethernet/mellanox/mlxsw/switchx2.c   | 1 +
  drivers/net/ethernet/pensando/ionic/ionic_lif.c  | 1 +
  drivers/net/ethernet/pensando/ionic/ionic_stats.c| 1 +


Acked-by: Shannon Nelson 


  drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c  | 1 +
  drivers/net/geneve.c | 1 +
  drivers/net/hyperv/netvsc_drv.c  | 1 +
  drivers/net/hyperv/rndis_filter.c| 1 +
  drivers/net/ipvlan/ipvlan_main.c | 2 ++
  drivers/net/nlmon.c  | 1 +
  drivers/net/team/team.c  | 1 +
  drivers/net/vrf.c| 1 +
  drivers/net/vsockmon.c   | 1 +
  drivers/scsi/bnx2fc/bnx2fc_fcoe.c| 2 ++
  drivers/scsi/fcoe/fcoe_transport.c   | 1 +
  drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c  | 2 ++
  drivers/staging/wimax/i2400m/usb.c   | 1 +
  include/linux/netdevice.h| 2 +-
  include/linux/qed/qed_if.h   | 1 +
  include/net/cfg80211.h   | 1 +
  include/rdma/ib_addr.h   | 1 +
  include/rdma/ib_verbs.h  | 1 +
  net/packet/af_packet.c   | 1 +
  net/sched/sch_cbs.c  | 1 +
  net/sched/sch_taprio.c   | 1 +
  net/socket.c | 1 +
  44 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 85767f52fe3c..fdf87acccd06 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -11,6 +11,7 @@
  
  #include 

  #include 
+#include 
  #include 
  #include 
  #include 
diff --git a/drivers/media/pci/ttpci/av7110_av.c 
b/drivers/media/pci/ttpci/av7110_av.c
index ea9f7d0058a2..91f4866c7e59 100644
--- a/drivers/media/pci/ttpci/av7110_av.c
+++ b/drivers/media/pci/ttpci/av7110_av.c
@@ -11,6 +11,7 @@
   * the project's page is at https://linuxtv.org
   */
  
+#include 

  #include 
  #include 
  #include 
diff --git a/drivers/net/bonding/bond_procfs.c 
b/drivers/net/bonding/bond_procfs.c
index fd5c9cbe45b1..56d34be5e797 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -1,5 +1,6 @@
  // SPDX-License-Identifier: GPL-2.0
  #include 
+#include 
  #include 
  #include 
  #include 
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index 3005157059ca..853c7b22aaef 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -9,6 +9,7 @@
   * Many thanks to all socketcan devs!
   */
  
+#include 

  #include 
  #include 
  #include 
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c 
b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 3b2cd28f962d..6cdd9efe8df3 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -3,6 +3,7 @@
   * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights 
reserved.
   */
  
+#include 

  #include 
  
  #include "ena_netdev.h"

diff --git a/drivers/net/ethernet/aq

Re: [net-next v2 PATCH] devlink: move request_firmware out of driver

2020-11-18 Thread Shannon Nelson

On 11/18/20 10:52 AM, Jacob Keller wrote:

On 11/13/2020 3:48 PM, Shannon Nelson wrote:

On 11/13/20 2:45 PM, Jacob Keller wrote:

-int ionic_firmware_update(struct ionic_lif *lif, const char *fw_name,
+int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw,
  struct netlink_ext_ack *extack)
   {
struct ionic_dev *idev = &lif->ionic->idev;
@@ -99,24 +99,15 @@ int ionic_firmware_update(struct ionic_lif *lif, const char 
*fw_name,
struct ionic *ionic = lif->ionic;
union ionic_dev_cmd_comp comp;
u32 buf_sz, copy_sz, offset;
-   const struct firmware *fw;
struct devlink *dl;
int next_interval;
int err = 0;
u8 fw_slot;
   
-	netdev_info(netdev, "Installing firmware %s\n", fw_name);

-

I prefer keeping the chatty little bits like this for debug purposes,
but if you're going to remove it, then you should remove the matching
netdev_info "Firmware update completed" message a few lines before the
release_firmware().

Aside from that, for the ionic bits:
Acked-by: Shannon Nelson 

Thanks,
sln


So the only reason I removed this is because the function no longer has
access to the fw_name string. I'll change it to just remove the %s
format string.


Thanks,
sln



Re: [net-next v2 PATCH] devlink: move request_firmware out of driver

2020-11-13 Thread Shannon Nelson

On 11/13/20 2:45 PM, Jacob Keller wrote:

All drivers which implement the devlink flash update support, with the
exception of netdevsim, use either request_firmware or
request_firmware_direct to locate the firmware file. Rather than having
each driver do this separately as part of its .flash_update
implementation, perform the request_firmware within net/core/devlink.c

Replace the file_name paramter in the struct devlink_flash_update_params


s/paramter/parameter/


with a pointer to the fw object.

Use request_firmware rather than request_firmware_direct. Although most
Linux distributions today do not have the fallback mechanism
implemented, only about half the drivers used the _direct request, as
compared to the generic request_firmware. In the event that
a distribution does support the fallback mechanism, the devlink flash
update ought to be able to use it to provide the firmware contents. For
distributions which do not support the fallback userspace mechanism,
there should be essentially no difference between request_firmware and
request_firmware_direct.

Signed-off-by: Jacob Keller 
Cc: Jiri Pirko 
Cc: Michael Chan 
Cc: Shannon Nelson 
Cc: Saeed Mahameed 
Cc: Boris Pismenny 
Cc: Bin Luo 
Cc: Jakub Kicinksi 
---
This is a follow to the discussion that took place at [1]. After reading
through the docs for request_firmware vs request_firmware_direct, I believe
that the net/core/devlink.c should be using request_firmware. While it is
true that no distribution supports this today, it seems like we shouldn't
rule it out entirely here. I'm willing to change this if we think it's not
worth bothering to support it.

Note that I have only compile-tested the drivers other than ice, as I do not
have hw for them. The only tricky transformation was in the bnxt driver
which shares code with the ethtool implementation. The rest were pretty
straight forward transformations.

Changes since v1
* fixed W=1 warnings about unused parameters

[1] 
https://lore.kernel.org/netdev/5fe24aae-6401-c879-b235-a12c1416d...@intel.com/

  .../net/ethernet/broadcom/bnxt/bnxt_devlink.c |  2 +-
  .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 33 ---
  .../net/ethernet/broadcom/bnxt/bnxt_ethtool.h |  4 +--
  .../net/ethernet/huawei/hinic/hinic_devlink.c | 12 +--
  drivers/net/ethernet/intel/ice/ice_devlink.c  | 14 +---
  .../net/ethernet/mellanox/mlx5/core/devlink.c | 11 +--
  drivers/net/ethernet/mellanox/mlxsw/core.c| 11 +--
  .../net/ethernet/netronome/nfp/nfp_devlink.c  |  2 +-
  drivers/net/ethernet/netronome/nfp/nfp_main.c | 17 ++
  drivers/net/ethernet/netronome/nfp/nfp_main.h |  2 +-
  .../ethernet/pensando/ionic/ionic_devlink.c   |  2 +-
  .../ethernet/pensando/ionic/ionic_devlink.h   |  2 +-
  .../net/ethernet/pensando/ionic/ionic_fw.c| 12 +--
  include/net/devlink.h |  7 ++--
  net/core/devlink.c| 26 ---
  15 files changed, 61 insertions(+), 96 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c 
b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 184b6d0513b2..4ebae8a236fd 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -32,7 +32,7 @@ bnxt_dl_flash_update(struct devlink *dl,
  
  	devlink_flash_update_begin_notify(dl);

devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 
0);
-   rc = bnxt_flash_package_from_file(bp->dev, params->file_name, 0);
+   rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0);
if (!rc)
devlink_flash_update_status_notify(dl, "Flashing done", NULL, 
0, 0);
else
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c 
b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 53687bc7fcf5..91e73aedcdff 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -2416,13 +2416,12 @@ static int bnxt_flash_firmware_from_file(struct 
net_device *dev,
return rc;
  }
  
-int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,

-u32 install_type)
+int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct 
firmware *fw,
+  u32 install_type)
  {
struct bnxt *bp = netdev_priv(dev);
struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_nvm_install_update_input install = {0};
-   const struct firmware *fw;
u32 item_len;
int rc = 0;
u16 index;
@@ -2437,13 +2436,6 @@ int bnxt_flash_package_from_file(struct net_device *dev, 
const char *filename,
return rc;
}
  
-	rc = request_firmware(&fw, filename, &dev->dev);

-   if (rc != 0) {
-   netdev_err(dev, "PKG error 

[PATCH v3 net-next 8/8] ionic: useful names for booleans

2020-11-12 Thread Shannon Nelson
With a few more uses of true and false in function calls, we
need to give them some useful names so we can tell from the
calling point what we're doing.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 drivers/net/ethernet/pensando/ionic/ionic_dev.c |  2 +-
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 16 
 drivers/net/ethernet/pensando/ionic/ionic_lif.h |  6 ++
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index dc5fbc2704f3..318db5f77fdb 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -25,7 +25,7 @@ static void ionic_watchdog_cb(struct timer_list *t)
hb = ionic_heartbeat_check(ionic);
 
if (hb >= 0)
-   ionic_link_status_check_request(ionic->lif, false);
+   ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP);
 }
 
 void ionic_init_devinfo(struct ionic *ionic)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 7408755bac17..deabd813e3fe 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1074,22 +1074,22 @@ static int ionic_lif_addr(struct ionic_lif *lif, const 
u8 *addr, bool add,
 
 static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_SLEEP);
 }
 
 static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, 
CAN_NOT_SLEEP);
 }
 
 static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_SLEEP);
 }
 
 static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, 
CAN_NOT_SLEEP);
 }
 
 static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
@@ -1197,7 +1197,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool can_sleep)
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
 {
-   ionic_set_rx_mode(netdev, false);
+   ionic_set_rx_mode(netdev, CAN_NOT_SLEEP);
 }
 
 static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
@@ -1784,7 +1784,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif);
 
-   ionic_set_rx_mode(lif->netdev, true);
+   ionic_set_rx_mode(lif->netdev, CAN_SLEEP);
 
return 0;
 
@@ -2792,7 +2792,7 @@ static int ionic_station_set(struct ionic_lif *lif)
 */
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
  netdev->dev_addr))
-   ionic_lif_addr(lif, netdev->dev_addr, true, true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, 
CAN_SLEEP);
} else {
/* Update the netdev mac with the device's mac */
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, 
netdev->addr_len);
@@ -2809,7 +2809,7 @@ static int ionic_station_set(struct ionic_lif *lif)
 
netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
   netdev->dev_addr);
-   ionic_lif_addr(lif, netdev->dev_addr, true, true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
 
return 0;
 }
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 0224dfd24b8a..9bed42719ae5 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -13,6 +13,12 @@
 
 #define IONIC_MAX_NUM_NAPI_CNTR(NAPI_POLL_WEIGHT + 1)
 #define IONIC_MAX_NUM_SG_CNTR  (IONIC_TX_MAX_SG_ELEMS + 1)
+
+#define ADD_ADDR   true
+#define DEL_ADDR   false
+#define CAN_SLEEP  true
+#define CAN_NOT_SLEEP  false
+
 #define IONIC_RX_COPYBREAK_DEFAULT 256
 #define IONIC_TX_BUDGET_DEFAULT256
 
-- 
2.17.1



[PATCH v3 net-next 6/8] ionic: flatten calls to ionic_lif_rx_mode

2020-11-12 Thread Shannon Nelson
The _ionic_lif_rx_mode() is only used once and really doesn't
need to be broken out.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 38 ---
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 13c7ac904611..58bf6e9314bb 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1129,29 +1129,10 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode)
lif->rx_mode = rx_mode;
 }
 
-static void _ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode,
-  bool from_ndo)
-{
-   struct ionic_deferred_work *work;
-
-   if (from_ndo) {
-   work = kzalloc(sizeof(*work), GFP_ATOMIC);
-   if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
-   return;
-   }
-   work->type = IONIC_DW_TYPE_RX_MODE;
-   work->rx_mode = rx_mode;
-   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
-   ionic_lif_deferred_enqueue(&lif->deferred, work);
-   } else {
-   ionic_lif_rx_mode(lif, rx_mode);
-   }
-}
-
 static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
 {
struct ionic_lif *lif = netdev_priv(netdev);
+   struct ionic_deferred_work *work;
unsigned int nfilters;
unsigned int rx_mode;
 
@@ -1197,8 +1178,21 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
}
 
-   if (lif->rx_mode != rx_mode)
-   _ionic_lif_rx_mode(lif, rx_mode, from_ndo);
+   if (lif->rx_mode != rx_mode) {
+   if (from_ndo) {
+   work = kzalloc(sizeof(*work), GFP_ATOMIC);
+   if (!work) {
+   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   return;
+   }
+   work->type = IONIC_DW_TYPE_RX_MODE;
+   work->rx_mode = rx_mode;
+   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
+   ionic_lif_deferred_enqueue(&lif->deferred, work);
+   } else {
+   ionic_lif_rx_mode(lif, rx_mode);
+   }
+   }
 }
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
-- 
2.17.1



[PATCH v3 net-next 7/8] ionic: change set_rx_mode from_ndo to can_sleep

2020-11-12 Thread Shannon Nelson
Instead of having two different ways of expressing the same
sleepability concept, using opposite logic, we can rework the
from_ndo to can_sleep for a more consistent usage.

Fixes: 1800eee16676 ("net: ionic: Replace in_interrupt() usage.")
Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 20 +--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 58bf6e9314bb..7408755bac17 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1129,7 +1129,7 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode)
lif->rx_mode = rx_mode;
 }
 
-static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
+static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
 {
struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_deferred_work *work;
@@ -1149,10 +1149,10 @@ static void ionic_set_rx_mode(struct net_device 
*netdev, bool from_ndo)
 *   we remove our overflow flag and check the netdev flags
 *   to see if we can disable NIC PROMISC
 */
-   if (from_ndo)
-   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
+   if (can_sleep)
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
+   else
+   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
if (netdev_uc_count(netdev) + 1 > nfilters) {
rx_mode |= IONIC_RX_MODE_F_PROMISC;
@@ -1164,10 +1164,10 @@ static void ionic_set_rx_mode(struct net_device 
*netdev, bool from_ndo)
}
 
/* same for multicast */
-   if (from_ndo)
-   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
+   if (can_sleep)
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
+   else
+   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
if (netdev_mc_count(netdev) > nfilters) {
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
@@ -1179,7 +1179,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
}
 
if (lif->rx_mode != rx_mode) {
-   if (from_ndo) {
+   if (!can_sleep) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
netdev_err(lif->netdev, "%s OOM\n", __func__);
@@ -1197,7 +1197,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
 {
-   ionic_set_rx_mode(netdev, true);
+   ionic_set_rx_mode(netdev, false);
 }
 
 static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
@@ -1784,7 +1784,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif);
 
-   ionic_set_rx_mode(lif->netdev, false);
+   ionic_set_rx_mode(lif->netdev, true);
 
return 0;
 
-- 
2.17.1



[PATCH v3 net-next 4/8] ionic: batch rx buffer refilling

2020-11-12 Thread Shannon Nelson
We don't need to refill the rx descriptors on every napi
if only a few were handled.  Waiting until we can batch up
a few together will save us a few Rx cycles.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h|  4 +++-
 .../net/ethernet/pensando/ionic/ionic_txrx.c   | 18 ++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 6c243b17312c..690768ff0143 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -12,8 +12,10 @@
 
 #define IONIC_MAX_TX_DESC  8192
 #define IONIC_MAX_RX_DESC  16384
-#define IONIC_MIN_TXRX_DESC16
+#define IONIC_MIN_TXRX_DESC64
 #define IONIC_DEF_TXRX_DESC4096
+#define IONIC_RX_FILL_THRESHOLD16
+#define IONIC_RX_FILL_DIV  8
 #define IONIC_LIFS_MAX 1024
 #define IONIC_WATCHDOG_SECS5
 #define IONIC_ITR_COAL_USEC_DEFAULT64
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index b3d2250c77d0..9156c9825a16 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -392,11 +392,6 @@ void ionic_rx_fill(struct ionic_queue *q)
 q->dbval | q->head_idx);
 }
 
-static void ionic_rx_fill_cb(void *arg)
-{
-   ionic_rx_fill(arg);
-}
-
 void ionic_rx_empty(struct ionic_queue *q)
 {
struct ionic_desc_info *desc_info;
@@ -480,6 +475,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
struct ionic_cq *cq = napi_to_cq(napi);
struct ionic_dev *idev;
struct ionic_lif *lif;
+   u16 rx_fill_threshold;
u32 work_done = 0;
u32 flags = 0;
 
@@ -489,7 +485,9 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
work_done = ionic_cq_service(cq, budget,
 ionic_rx_service, NULL, NULL);
 
-   if (work_done)
+   rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
+ cq->num_descs / IONIC_RX_FILL_DIV);
+   if (work_done && ionic_q_space_avail(cq->bound_q) >= rx_fill_threshold)
ionic_rx_fill(cq->bound_q);
 
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -518,6 +516,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
struct ionic_dev *idev;
struct ionic_lif *lif;
struct ionic_cq *txcq;
+   u16 rx_fill_threshold;
u32 rx_work_done = 0;
u32 tx_work_done = 0;
u32 flags = 0;
@@ -531,8 +530,11 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
 
rx_work_done = ionic_cq_service(rxcq, budget,
ionic_rx_service, NULL, NULL);
-   if (rx_work_done)
-   ionic_rx_fill_cb(rxcq->bound_q);
+
+   rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
+ rxcq->num_descs / IONIC_RX_FILL_DIV);
+   if (rx_work_done && ionic_q_space_avail(rxcq->bound_q) >= 
rx_fill_threshold)
+   ionic_rx_fill(rxcq->bound_q);
 
if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) {
ionic_dim_update(qcq);
-- 
2.17.1



[PATCH v3 net-next 5/8] ionic: use mc sync for multicast filters

2020-11-12 Thread Shannon Nelson
We should be using the multicast sync routines for the multicast
filters.  Also, let's just flatten the logic a bit and pull
the small unicast routine back into ionic_set_rx_mode().

Fixes: 1800eee16676 ("net: ionic: Replace in_interrupt() usage.")
Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index e5ed8231317a..13c7ac904611 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1149,15 +1149,6 @@ static void _ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode,
}
 }
 
-static void ionic_dev_uc_sync(struct net_device *netdev, bool from_ndo)
-{
-   if (from_ndo)
-   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
-   __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
-
-}
-
 static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
 {
struct ionic_lif *lif = netdev_priv(netdev);
@@ -1177,7 +1168,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
 *   we remove our overflow flag and check the netdev flags
 *   to see if we can disable NIC PROMISC
 */
-   ionic_dev_uc_sync(netdev, from_ndo);
+   if (from_ndo)
+   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
+   else
+   __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
if (netdev_uc_count(netdev) + 1 > nfilters) {
rx_mode |= IONIC_RX_MODE_F_PROMISC;
@@ -1189,7 +1183,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
}
 
/* same for multicast */
-   ionic_dev_uc_sync(netdev, from_ndo);
+   if (from_ndo)
+   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
+   else
+   __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
if (netdev_mc_count(netdev) > nfilters) {
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
-- 
2.17.1



[PATCH v3 net-next 0/8] ionic updates

2020-11-12 Thread Shannon Nelson
These updates are a bit of code cleaning and a minor
bit of performance tweaking.

v3: convert ionic_lif_quiesce() to void
v2: added void cast on call to ionic_lif_quiesce()
lowered batching threshold
added patch to flatten calls to ionic_lif_rx_mode
added patch to change from_ndo to can_sleep

Shannon Nelson (8):
  ionic: start queues before announcing link up
  ionic: check for link after netdev registration
  ionic: add lif quiesce
  ionic: batch rx buffer refilling
  ionic: use mc sync for multicast filters
  ionic: flatten calls to ionic_lif_rx_mode
  ionic: change set_rx_mode from_ndo to can_sleep
  ionic: useful names for booleans

 .../net/ethernet/pensando/ionic/ionic_dev.c   |   2 +-
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   4 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 109 ++
 .../net/ethernet/pensando/ionic/ionic_lif.h   |   6 +
 .../net/ethernet/pensando/ionic/ionic_txrx.c  |  18 +--
 5 files changed, 81 insertions(+), 58 deletions(-)

-- 
2.17.1



[PATCH v3 net-next 3/8] ionic: add lif quiesce

2020-11-12 Thread Shannon Nelson
After the queues are stopped, expressly quiesce the lif.
This assures that even if the queues were in an odd state,
the firmware will close up everything cleanly.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 20 +++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 519d544821af..e5ed8231317a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1625,6 +1625,24 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
ionic_lif_rss_config(lif, 0x0, NULL, NULL);
 }
 
+static void ionic_lif_quiesce(struct ionic_lif *lif)
+{
+   struct ionic_admin_ctx ctx = {
+   .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+   .cmd.lif_setattr = {
+   .opcode = IONIC_CMD_LIF_SETATTR,
+   .index = cpu_to_le16(lif->index),
+   .attr = IONIC_LIF_ATTR_STATE,
+   .state = IONIC_LIF_QUIESCE,
+   },
+   };
+   int err;
+
+   err = ionic_adminq_post_wait(lif, &ctx);
+   if (err)
+   netdev_err(lif->netdev, "lif quiesce failed %d\n", err);
+}
+
 static void ionic_txrx_disable(struct ionic_lif *lif)
 {
unsigned int i;
@@ -1639,6 +1657,8 @@ static void ionic_txrx_disable(struct ionic_lif *lif)
for (i = 0; i < lif->nxqs; i++)
err = ionic_qcq_disable(lif->rxqcqs[i], (err != 
-ETIMEDOUT));
}
+
+   ionic_lif_quiesce(lif);
 }
 
 static void ionic_txrx_deinit(struct ionic_lif *lif)
-- 
2.17.1



[PATCH v3 net-next 1/8] ionic: start queues before announcing link up

2020-11-12 Thread Shannon Nelson
Change the order of operations in the link_up handling to be
sure that the queues are up and ready before we announce that
the link is up.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a12df3946a07..5457fb5d69ed 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -123,6 +123,12 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_up = link_status == IONIC_PORT_OPER_STATUS_UP;
 
if (link_up) {
+   if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
+   mutex_lock(&lif->queue_lock);
+   ionic_start_queues(lif);
+   mutex_unlock(&lif->queue_lock);
+   }
+
if (!netif_carrier_ok(netdev)) {
u32 link_speed;
 
@@ -132,12 +138,6 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_speed / 1000);
netif_carrier_on(netdev);
}
-
-   if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
-   mutex_lock(&lif->queue_lock);
-   ionic_start_queues(lif);
-   mutex_unlock(&lif->queue_lock);
-   }
} else {
if (netif_carrier_ok(netdev)) {
netdev_info(netdev, "Link down\n");
-- 
2.17.1



[PATCH v3 net-next 2/8] ionic: check for link after netdev registration

2020-11-12 Thread Shannon Nelson
Request a link check as soon as the netdev is registered rather
than waiting for the watchdog to go off in order to get the
interface operational a little more quickly.

Signed-off-by: Shannon Nelson 
Reviewed-by: Saeed Mahameed 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 5457fb5d69ed..519d544821af 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2959,6 +2959,8 @@ int ionic_lif_register(struct ionic_lif *lif)
dev_err(lif->ionic->dev, "Cannot register net device, 
aborting\n");
return err;
}
+
+   ionic_link_status_check_request(lif, true);
lif->registered = true;
ionic_lif_set_netdev_info(lif);
 
-- 
2.17.1



Re: [PATCH v2 net-next 6/8] ionic: flatten calls to ionic_lif_rx_mode

2020-11-06 Thread Shannon Nelson

On 11/6/20 1:33 PM, Saeed Mahameed wrote:

On Thu, 2020-11-05 at 16:12 -0800, Shannon Nelson wrote:

The _ionic_lif_rx_mode() is only used once and really doesn't
need to be broken out.

Signed-off-by: Shannon Nelson 
---
  .../net/ethernet/pensando/ionic/ionic_lif.c   | 38 -
--
  1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a0d26fe4cbc3..ef092ee33e59 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1129,29 +1129,10 @@ static void ionic_lif_rx_mode(struct
ionic_lif *lif, unsigned int rx_mode)
lif->rx_mode = rx_mode;
  }
  
-static void _ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int

rx_mode,
-  bool from_ndo)
-{
-   struct ionic_deferred_work *work;
-
-   if (from_ndo) {
-   work = kzalloc(sizeof(*work), GFP_ATOMIC);
-   if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
-   return;
-   }
-   work->type = IONIC_DW_TYPE_RX_MODE;
-   work->rx_mode = rx_mode;
-   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
-   ionic_lif_deferred_enqueue(&lif->deferred, work);
-   } else {
-   ionic_lif_rx_mode(lif, rx_mode);
-   }
-}
-
  static void ionic_set_rx_mode(struct net_device *netdev, bool
from_ndo)
  {
struct ionic_lif *lif = netdev_priv(netdev);
+   struct ionic_deferred_work *work;
unsigned int nfilters;
unsigned int rx_mode;
  
@@ -1197,8 +1178,21 @@ static void ionic_set_rx_mode(struct

net_device *netdev, bool from_ndo)
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
}
  
-	if (lif->rx_mode != rx_mode)

-   _ionic_lif_rx_mode(lif, rx_mode, from_ndo);
+   if (lif->rx_mode != rx_mode) {
+   if (from_ndo) {
+   work = kzalloc(sizeof(*work), GFP_ATOMIC);
+   if (!work) {
+   netdev_err(lif->netdev, "%s OOM\n",
__func__);
+   return;
+   }
+   work->type = IONIC_DW_TYPE_RX_MODE;
+   work->rx_mode = rx_mode;
+   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
+   ionic_lif_deferred_enqueue(&lif->deferred,
work);
+   } else {
+   ionic_lif_rx_mode(lif, rx_mode);
+   }
+   }
  }

You could move this logic one level up and totally eliminate the if
condition

ionic_set_rx_mode_needed() {
   //sync driver data base
   return lif->rx_mode != rx_mode;
}

ndo_set_rx_mode() {
   if (!ionic_set_rx_mode_needed())
 return; // no change;
   schedule_work(set_rx_mode_hw);
}

none_ndo_set_rx_mode() {
   if (!ionic_set_rx_mode_needed())
 return; // no change;
   set_rx_mode_hw();
}


Hmm... yes, that's possible, but I like keeping that bit of logic 
together with the rest in the main set_rx_mode block.



Future improvement:

One more thing I've noticed about you current ionic_set_rx_mode()
is that in case of from_ndo, when it syncs mac addresses it will
schedule a deferred mac address update work to hw per address. which i
think is an overkill,


This is much less of an issue with the recent change in 
ionic_lif_deferred_work() to run through the whole work list in one 
deferred_work session.


sln


a simpler design which will totally eliminate the
need for from_ndo flags, is to do similar to the above but with a minor
change.

ionic_set_rx_mode_needed() {
   // Just sync driver mac table here and update hw later
   // in one deferred work rather than scheduling multi work
   addr_changed = ionic_dev_uc_sync();
   addr_changed |= ionic_dev_mc_sync();
   rx_mode_changed = sync_driver_rx_mode(rx_mode);

   return rx_mode_changed || addr_changed;
}

/* might sleep */
set_rx_mode_hw() {
   commit_addr_change_to_hw();
   commit_rx_mode_changes_to_hw();
}

ndo_set_rx_mode() {
   if (!ionic_set_rx_mode_needed())
 return; // no change;
   schedule_work(set_rx_mode_hw);
}

none_ndo_set_rx_mode() {
   if (!ionic_set_rx_mode_needed())
 return; // no change;
   set_rx_mode_hw();
}





Re: [PATCH v2 net-next 6/8] ionic: flatten calls to ionic_lif_rx_mode

2020-11-06 Thread Shannon Nelson

On 11/6/20 9:03 AM, Jakub Kicinski wrote:

On Thu,  5 Nov 2020 16:12:18 -0800 Shannon Nelson wrote:

+   work = kzalloc(sizeof(*work), GFP_ATOMIC);
+   if (!work) {
+   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   return;
+   }

Can you drop this message (can be a follow up, since you're just moving
it).

AFAICT ATOMIC doesn't imply NOWARN so the message is redundant no?


Yes, this can probably be cleaned up.  There are several of these left 
over from the very early version of this driver that I'd like to clean 
up, but haven't yet bubbled up high enough on my priority-vs-time list.  
I'll try to get to them in the next week or so.


sln



[PATCH v2 net-next 5/8] ionic: use mc sync for multicast filters

2020-11-05 Thread Shannon Nelson
We should be using the multicast sync routines for the multicast
filters.  Also, let's just flatten the logic a bit and pull
the small unicast routine back into ionic_set_rx_mode().

Fixes: 1800eee16676 ("net: ionic: Replace in_interrupt() usage.")
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 990bd9ce93c2..a0d26fe4cbc3 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1149,15 +1149,6 @@ static void _ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode,
}
 }
 
-static void ionic_dev_uc_sync(struct net_device *netdev, bool from_ndo)
-{
-   if (from_ndo)
-   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
-   __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
-
-}
-
 static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
 {
struct ionic_lif *lif = netdev_priv(netdev);
@@ -1177,7 +1168,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
 *   we remove our overflow flag and check the netdev flags
 *   to see if we can disable NIC PROMISC
 */
-   ionic_dev_uc_sync(netdev, from_ndo);
+   if (from_ndo)
+   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
+   else
+   __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
if (netdev_uc_count(netdev) + 1 > nfilters) {
rx_mode |= IONIC_RX_MODE_F_PROMISC;
@@ -1189,7 +1183,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
}
 
/* same for multicast */
-   ionic_dev_uc_sync(netdev, from_ndo);
+   if (from_ndo)
+   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
+   else
+   __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
if (netdev_mc_count(netdev) > nfilters) {
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
-- 
2.17.1



[PATCH v2 net-next 7/8] ionic: change set_rx_mode from_ndo to can_sleep

2020-11-05 Thread Shannon Nelson
Instead of having two different ways of expressing the same
sleepability concept, using opposite logic, we can rework the
from_ndo to can_sleep for a more consistent usage.

Fixes: 1800eee16676 ("net: ionic: Replace in_interrupt() usage.")
Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 20 +--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index ef092ee33e59..7e4ea4ecc912 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1129,7 +1129,7 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode)
lif->rx_mode = rx_mode;
 }
 
-static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
+static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
 {
struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_deferred_work *work;
@@ -1149,10 +1149,10 @@ static void ionic_set_rx_mode(struct net_device 
*netdev, bool from_ndo)
 *   we remove our overflow flag and check the netdev flags
 *   to see if we can disable NIC PROMISC
 */
-   if (from_ndo)
-   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
+   if (can_sleep)
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
+   else
+   __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
if (netdev_uc_count(netdev) + 1 > nfilters) {
rx_mode |= IONIC_RX_MODE_F_PROMISC;
@@ -1164,10 +1164,10 @@ static void ionic_set_rx_mode(struct net_device 
*netdev, bool from_ndo)
}
 
/* same for multicast */
-   if (from_ndo)
-   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
-   else
+   if (can_sleep)
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
+   else
+   __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
if (netdev_mc_count(netdev) > nfilters) {
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
@@ -1179,7 +1179,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
}
 
if (lif->rx_mode != rx_mode) {
-   if (from_ndo) {
+   if (!can_sleep) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
netdev_err(lif->netdev, "%s OOM\n", __func__);
@@ -1197,7 +1197,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
 {
-   ionic_set_rx_mode(netdev, true);
+   ionic_set_rx_mode(netdev, false);
 }
 
 static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
@@ -1788,7 +1788,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif);
 
-   ionic_set_rx_mode(lif->netdev, false);
+   ionic_set_rx_mode(lif->netdev, true);
 
return 0;
 
-- 
2.17.1



[PATCH v2 net-next 6/8] ionic: flatten calls to ionic_lif_rx_mode

2020-11-05 Thread Shannon Nelson
The _ionic_lif_rx_mode() is only used once and really doesn't
need to be broken out.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 38 ---
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a0d26fe4cbc3..ef092ee33e59 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1129,29 +1129,10 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, 
unsigned int rx_mode)
lif->rx_mode = rx_mode;
 }
 
-static void _ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode,
-  bool from_ndo)
-{
-   struct ionic_deferred_work *work;
-
-   if (from_ndo) {
-   work = kzalloc(sizeof(*work), GFP_ATOMIC);
-   if (!work) {
-   netdev_err(lif->netdev, "%s OOM\n", __func__);
-   return;
-   }
-   work->type = IONIC_DW_TYPE_RX_MODE;
-   work->rx_mode = rx_mode;
-   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
-   ionic_lif_deferred_enqueue(&lif->deferred, work);
-   } else {
-   ionic_lif_rx_mode(lif, rx_mode);
-   }
-}
-
 static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
 {
struct ionic_lif *lif = netdev_priv(netdev);
+   struct ionic_deferred_work *work;
unsigned int nfilters;
unsigned int rx_mode;
 
@@ -1197,8 +1178,21 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool from_ndo)
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
}
 
-   if (lif->rx_mode != rx_mode)
-   _ionic_lif_rx_mode(lif, rx_mode, from_ndo);
+   if (lif->rx_mode != rx_mode) {
+   if (from_ndo) {
+   work = kzalloc(sizeof(*work), GFP_ATOMIC);
+   if (!work) {
+   netdev_err(lif->netdev, "%s OOM\n", __func__);
+   return;
+   }
+   work->type = IONIC_DW_TYPE_RX_MODE;
+   work->rx_mode = rx_mode;
+   netdev_dbg(lif->netdev, "deferred: rx_mode\n");
+   ionic_lif_deferred_enqueue(&lif->deferred, work);
+   } else {
+   ionic_lif_rx_mode(lif, rx_mode);
+   }
+   }
 }
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
-- 
2.17.1



[PATCH v2 net-next 8/8] ionic: useful names for booleans

2020-11-05 Thread Shannon Nelson
With a few more uses of true and false in function calls, we
need to give them some useful names so we can tell from the
calling point what we're doing.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_dev.c |  2 +-
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 16 
 drivers/net/ethernet/pensando/ionic/ionic_lif.h |  6 ++
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index dc5fbc2704f3..318db5f77fdb 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -25,7 +25,7 @@ static void ionic_watchdog_cb(struct timer_list *t)
hb = ionic_heartbeat_check(ionic);
 
if (hb >= 0)
-   ionic_link_status_check_request(ionic->lif, false);
+   ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP);
 }
 
 void ionic_init_devinfo(struct ionic *ionic)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 7e4ea4ecc912..9dde9d50c866 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1074,22 +1074,22 @@ static int ionic_lif_addr(struct ionic_lif *lif, const 
u8 *addr, bool add,
 
 static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_SLEEP);
 }
 
 static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, 
CAN_NOT_SLEEP);
 }
 
 static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_SLEEP);
 }
 
 static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr)
 {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, 
CAN_NOT_SLEEP);
 }
 
 static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
@@ -1197,7 +1197,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, 
bool can_sleep)
 
 static void ionic_ndo_set_rx_mode(struct net_device *netdev)
 {
-   ionic_set_rx_mode(netdev, false);
+   ionic_set_rx_mode(netdev, CAN_NOT_SLEEP);
 }
 
 static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
@@ -1788,7 +1788,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif);
 
-   ionic_set_rx_mode(lif->netdev, true);
+   ionic_set_rx_mode(lif->netdev, CAN_SLEEP);
 
return 0;
 
@@ -2796,7 +2796,7 @@ static int ionic_station_set(struct ionic_lif *lif)
 */
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
  netdev->dev_addr))
-   ionic_lif_addr(lif, netdev->dev_addr, true, true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, 
CAN_SLEEP);
} else {
/* Update the netdev mac with the device's mac */
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, 
netdev->addr_len);
@@ -2813,7 +2813,7 @@ static int ionic_station_set(struct ionic_lif *lif)
 
netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
   netdev->dev_addr);
-   ionic_lif_addr(lif, netdev->dev_addr, true, true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
 
return 0;
 }
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 0224dfd24b8a..9bed42719ae5 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -13,6 +13,12 @@
 
 #define IONIC_MAX_NUM_NAPI_CNTR(NAPI_POLL_WEIGHT + 1)
 #define IONIC_MAX_NUM_SG_CNTR  (IONIC_TX_MAX_SG_ELEMS + 1)
+
+#define ADD_ADDR   true
+#define DEL_ADDR   false
+#define CAN_SLEEP  true
+#define CAN_NOT_SLEEP  false
+
 #define IONIC_RX_COPYBREAK_DEFAULT 256
 #define IONIC_TX_BUDGET_DEFAULT256
 
-- 
2.17.1



[PATCH v2 net-next 1/8] ionic: start queues before announcing link up

2020-11-05 Thread Shannon Nelson
Change the order of operations in the link_up handling to be
sure that the queues are up and ready before we announce that
the link is up.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a12df3946a07..5457fb5d69ed 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -123,6 +123,12 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_up = link_status == IONIC_PORT_OPER_STATUS_UP;
 
if (link_up) {
+   if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
+   mutex_lock(&lif->queue_lock);
+   ionic_start_queues(lif);
+   mutex_unlock(&lif->queue_lock);
+   }
+
if (!netif_carrier_ok(netdev)) {
u32 link_speed;
 
@@ -132,12 +138,6 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_speed / 1000);
netif_carrier_on(netdev);
}
-
-   if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
-   mutex_lock(&lif->queue_lock);
-   ionic_start_queues(lif);
-   mutex_unlock(&lif->queue_lock);
-   }
} else {
if (netif_carrier_ok(netdev)) {
netdev_info(netdev, "Link down\n");
-- 
2.17.1



[PATCH v2 net-next 4/8] ionic: batch rx buffer refilling

2020-11-05 Thread Shannon Nelson
We don't need to refill the rx descriptors on every napi
if only a few were handled.  Waiting until we can batch up
a few together will save us a few Rx cycles.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_dev.h|  4 +++-
 .../net/ethernet/pensando/ionic/ionic_txrx.c   | 18 ++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h 
b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 6c243b17312c..690768ff0143 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -12,8 +12,10 @@
 
 #define IONIC_MAX_TX_DESC  8192
 #define IONIC_MAX_RX_DESC  16384
-#define IONIC_MIN_TXRX_DESC16
+#define IONIC_MIN_TXRX_DESC64
 #define IONIC_DEF_TXRX_DESC4096
+#define IONIC_RX_FILL_THRESHOLD16
+#define IONIC_RX_FILL_DIV  8
 #define IONIC_LIFS_MAX 1024
 #define IONIC_WATCHDOG_SECS5
 #define IONIC_ITR_COAL_USEC_DEFAULT64
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c 
b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index b3d2250c77d0..9156c9825a16 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -392,11 +392,6 @@ void ionic_rx_fill(struct ionic_queue *q)
 q->dbval | q->head_idx);
 }
 
-static void ionic_rx_fill_cb(void *arg)
-{
-   ionic_rx_fill(arg);
-}
-
 void ionic_rx_empty(struct ionic_queue *q)
 {
struct ionic_desc_info *desc_info;
@@ -480,6 +475,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
struct ionic_cq *cq = napi_to_cq(napi);
struct ionic_dev *idev;
struct ionic_lif *lif;
+   u16 rx_fill_threshold;
u32 work_done = 0;
u32 flags = 0;
 
@@ -489,7 +485,9 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
work_done = ionic_cq_service(cq, budget,
 ionic_rx_service, NULL, NULL);
 
-   if (work_done)
+   rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
+ cq->num_descs / IONIC_RX_FILL_DIV);
+   if (work_done && ionic_q_space_avail(cq->bound_q) >= rx_fill_threshold)
ionic_rx_fill(cq->bound_q);
 
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -518,6 +516,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
struct ionic_dev *idev;
struct ionic_lif *lif;
struct ionic_cq *txcq;
+   u16 rx_fill_threshold;
u32 rx_work_done = 0;
u32 tx_work_done = 0;
u32 flags = 0;
@@ -531,8 +530,11 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
 
rx_work_done = ionic_cq_service(rxcq, budget,
ionic_rx_service, NULL, NULL);
-   if (rx_work_done)
-   ionic_rx_fill_cb(rxcq->bound_q);
+
+   rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
+ rxcq->num_descs / IONIC_RX_FILL_DIV);
+   if (rx_work_done && ionic_q_space_avail(rxcq->bound_q) >= 
rx_fill_threshold)
+   ionic_rx_fill(rxcq->bound_q);
 
if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) {
ionic_dim_update(qcq);
-- 
2.17.1



[PATCH v2 net-next 0/8] ionic updates

2020-11-05 Thread Shannon Nelson
These updates are a bit of code cleaning and a minor
bit of performance tweaking.

v2: added void cast on call to ionic_lif_quiesce()
lowered batching threshold
added patch to flatten calls to ionic_lif_rx_mode
added patch to change from_ndo to can_sleep

Shannon Nelson (8):
  ionic: start queues before announcing link up
  ionic: check for link after netdev registration
  ionic: add lif quiesce
  ionic: batch rx buffer refilling
  ionic: use mc sync for multicast filters
  ionic: flatten calls to ionic_lif_rx_mode
  ionic: change set_rx_mode from_ndo to can_sleep
  ionic: useful names for booleans

 .../net/ethernet/pensando/ionic/ionic_dev.c   |   2 +-
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   4 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 113 ++
 .../net/ethernet/pensando/ionic/ionic_lif.h   |   6 +
 .../net/ethernet/pensando/ionic/ionic_txrx.c  |  18 +--
 5 files changed, 85 insertions(+), 58 deletions(-)

-- 
2.17.1



[PATCH v2 net-next 3/8] ionic: add lif quiesce

2020-11-05 Thread Shannon Nelson
After the queues are stopped, expressly quiesce the lif.
This assures that even if the queues were in an odd state,
the firmware will close up everything cleanly.

Signed-off-by: Shannon Nelson 
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 24 +++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 519d544821af..990bd9ce93c2 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1625,6 +1625,28 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
ionic_lif_rss_config(lif, 0x0, NULL, NULL);
 }
 
+static int ionic_lif_quiesce(struct ionic_lif *lif)
+{
+   struct ionic_admin_ctx ctx = {
+   .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+   .cmd.lif_setattr = {
+   .opcode = IONIC_CMD_LIF_SETATTR,
+   .index = cpu_to_le16(lif->index),
+   .attr = IONIC_LIF_ATTR_STATE,
+   .state = IONIC_LIF_QUIESCE,
+   },
+   };
+   int err;
+
+   err = ionic_adminq_post_wait(lif, &ctx);
+   if (err) {
+   netdev_err(lif->netdev, "lif quiesce failed %d\n", err);
+   return err;
+   }
+
+   return 0;
+}
+
 static void ionic_txrx_disable(struct ionic_lif *lif)
 {
unsigned int i;
@@ -1639,6 +1661,8 @@ static void ionic_txrx_disable(struct ionic_lif *lif)
for (i = 0; i < lif->nxqs; i++)
err = ionic_qcq_disable(lif->rxqcqs[i], (err != 
-ETIMEDOUT));
}
+
+   (void)ionic_lif_quiesce(lif);
 }
 
 static void ionic_txrx_deinit(struct ionic_lif *lif)
-- 
2.17.1



[PATCH v2 net-next 2/8] ionic: check for link after netdev registration

2020-11-05 Thread Shannon Nelson
Request a link check as soon as the netdev is registered rather
than waiting for the watchdog to go off in order to get the
interface operational a little more quickly.

Signed-off-by: Shannon Nelson 
---
 drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c 
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 5457fb5d69ed..519d544821af 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2959,6 +2959,8 @@ int ionic_lif_register(struct ionic_lif *lif)
dev_err(lif->ionic->dev, "Cannot register net device, 
aborting\n");
return err;
}
+
+   ionic_link_status_check_request(lif, true);
lif->registered = true;
ionic_lif_set_netdev_info(lif);
 
-- 
2.17.1



Re: [PATCH net-next 6/6] ionic: useful names for booleans

2020-11-05 Thread Shannon Nelson

On 11/4/20 5:21 PM, Saeed Mahameed wrote:

On Wed, 2020-11-04 at 14:33 -0800, Shannon Nelson wrote:

With a few more uses of true and false in function calls, we
need to give them some useful names so we can tell from the
calling point what we're doing.


Aha! The root cause of the issue is passing booleans to functions in
first place, it is usually a bad idea that could lead to complication
and overloading the design for no reason, please see my suggestion in
the previous patch maybe you can apply the same approach on some of the
booleans below.


Yes, this is similar to what I was commenting on when I responded to the 
in_interrupt() patches.  However, when the code around Add and Delete is 
identicle and called from multiple places, it is handy to put it in one 
place with a boolean so as to not have multiple instances to maintain.  
Yes, it's a tradeoff, and these #defines are meant to help ease the 
readability.


The v2 for patch 5/6 in this patchset might help this a little, I'll see 
what I can do.


Thanks for you time in looking through these patches.

Cheers,
sln





Signed-off-by: Shannon Nelson 
---
  drivers/net/ethernet/pensando/ionic/ionic_lif.c | 16 ---
-
  drivers/net/ethernet/pensando/ionic/ionic_lif.h |  8 
  2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a58bb572b23b..a0d2989a0d8d 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1074,22 +1074,22 @@ static int ionic_lif_addr(struct ionic_lif
*lif, const u8 *addr, bool add,
  
  static int ionic_addr_add(struct net_device *netdev, const u8 *addr)

  {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR,
CAN_SLEEP);
  }
  
  static int ionic_ndo_addr_add(struct net_device *netdev, const u8

*addr)
  {
-   return ionic_lif_addr(netdev_priv(netdev), addr, true, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR,
CAN_NOT_SLEEP);
  }
  
  static int ionic_addr_del(struct net_device *netdev, const u8 *addr)

  {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, true);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR,
CAN_SLEEP);
  }
  
  static int ionic_ndo_addr_del(struct net_device *netdev, const u8

*addr)
  {
-   return ionic_lif_addr(netdev_priv(netdev), addr, false, false);
+   return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR,
CAN_NOT_SLEEP);
  }
  
  static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int

rx_mode)
@@ -1214,7 +1214,7 @@ static void ionic_set_rx_mode(struct net_device
*netdev, bool from_ndo)
  
  static void ionic_ndo_set_rx_mode(struct net_device *netdev)

  {
-   ionic_set_rx_mode(netdev, true);
+   ionic_set_rx_mode(netdev, FROM_NDO);
  }
  
  static __le64 ionic_netdev_features_to_nic(netdev_features_t

features)
@@ -1805,7 +1805,7 @@ static int ionic_txrx_init(struct ionic_lif
*lif)
if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif);
  
-	ionic_set_rx_mode(lif->netdev, false);

+   ionic_set_rx_mode(lif->netdev, NOT_FROM_NDO);
  
  	return 0;
  
@@ -2813,7 +2813,7 @@ static int ionic_station_set(struct ionic_lif

*lif)
 */
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
  netdev->dev_addr))
-   ionic_lif_addr(lif, netdev->dev_addr, true,
true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR,
CAN_SLEEP);
} else {
/* Update the netdev mac with the device's mac */
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev-

addr_len);

@@ -2830,7 +2830,7 @@ static int ionic_station_set(struct ionic_lif
*lif)
  
  	netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",

   netdev->dev_addr);
-   ionic_lif_addr(lif, netdev->dev_addr, true, true);
+   ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
  
  	return 0;

  }
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 0224dfd24b8a..493de679b498 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -13,6 +13,14 @@
  
  #define IONIC_MAX_NUM_NAPI_CNTR		(NAPI_POLL_WEIGHT + 1)

  #define IONIC_MAX_NUM_SG_CNTR (IONIC_TX_MAX_SG_ELEMS
+ 1)
+
+#define ADD_ADDR   true
+#define DEL_ADDR   false
+#define CAN_SLEEP  true
+#define CAN_NOT_SLEEP  false
+#define FROM_NDO   true
+#define NOT_FROM_NDO   false
+
  #define IONIC_RX_COPYBREAK_DEFAULT256
  #define IONIC_TX_BUDGET_DEFAULT   256
  




  1   2   3   4   5   6   7   8   9   10   >