Merge branch 'ionic-cleanups'
Shannon Nelson says: ==================== ionic: code cleanup for heartbeat, dma error counts, sizeof, stats 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. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3c7a83fa42
@ -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;
|
||||
ionic_lif_deferred_enqueue(&lif->deferred, work);
|
||||
}
|
||||
}
|
||||
}
|
||||
idev->last_fw_status = fw_status;
|
||||
|
||||
if (!fw_status || fw_status == 0xff)
|
||||
if (!fw_status_ready)
|
||||
return -ENXIO;
|
||||
|
||||
/* early FW has no heartbeat, else FW will return non-zero */
|
||||
hb = ioread32(&idev->dev_info_regs->fw_heartbeat);
|
||||
if (!hb)
|
||||
/* wait at least one watchdog period since the last heartbeat */
|
||||
last_check_time = idev->last_hb_time;
|
||||
if (time_before(check_time, last_check_time + ionic->watchdog_period))
|
||||
return 0;
|
||||
|
||||
/* are we stalled? */
|
||||
if (hb == idev->last_hb) {
|
||||
/* only complain once for each stall seen */
|
||||
if (idev->last_hb_time != 1) {
|
||||
dev_info(ionic->dev, "FW heartbeat stalled at %d\n",
|
||||
idev->last_hb);
|
||||
idev->last_hb_time = 1;
|
||||
}
|
||||
fw_hb = ioread32(&idev->dev_info_regs->fw_heartbeat);
|
||||
fw_hb_ready = fw_hb != idev->last_fw_hb;
|
||||
|
||||
return -ENXIO;
|
||||
/* early FW version had no heartbeat, so fake it */
|
||||
if (!fw_hb_ready && !fw_hb)
|
||||
fw_hb_ready = true;
|
||||
|
||||
dev_dbg(ionic->dev, "%s: fw_hb %u last_fw_hb %u ready %u\n",
|
||||
__func__, fw_hb, idev->last_fw_hb, fw_hb_ready);
|
||||
|
||||
idev->last_fw_hb = fw_hb;
|
||||
|
||||
/* log a transition */
|
||||
if (fw_hb_ready != idev->fw_hb_ready) {
|
||||
idev->fw_hb_ready = fw_hb_ready;
|
||||
if (!fw_hb_ready)
|
||||
dev_info(ionic->dev, "FW heartbeat stalled at %d\n", fw_hb);
|
||||
else
|
||||
dev_info(ionic->dev, "FW heartbeat restored at %d\n", fw_hb);
|
||||
}
|
||||
|
||||
if (idev->last_hb_time == 1)
|
||||
dev_info(ionic->dev, "FW heartbeat restored at %d\n", hb);
|
||||
if (!fw_hb_ready)
|
||||
return -ENXIO;
|
||||
|
||||
idev->last_hb = hb;
|
||||
idev->last_hb_time = hb_time;
|
||||
idev->last_hb_time = check_time;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef _IONIC_DEV_H_
|
||||
#define _IONIC_DEV_H_
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
@ -135,9 +136,11 @@ struct ionic_dev {
|
||||
union ionic_dev_info_regs __iomem *dev_info_regs;
|
||||
union ionic_dev_cmd_regs __iomem *dev_cmd_regs;
|
||||
|
||||
atomic_long_t last_check_time;
|
||||
unsigned long last_hb_time;
|
||||
u32 last_hb;
|
||||
u8 last_fw_status;
|
||||
u32 last_fw_hb;
|
||||
bool fw_hb_ready;
|
||||
bool fw_status_ready;
|
||||
|
||||
u64 __iomem *db_pages;
|
||||
dma_addr_t phy_db_pages;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
int q_num)
|
||||
{
|
||||
struct ionic_tx_stats *txstats;
|
||||
struct ionic_qcq *txqcq;
|
||||
int i;
|
||||
|
||||
txstats = &lif->txqstats[q_num];
|
||||
|
||||
for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(txstats, &ionic_tx_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
|
||||
if (!test_bit(IONIC_LIF_F_UP, lif->state) ||
|
||||
!test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
|
||||
return;
|
||||
|
||||
txqcq = lif->txqcqs[q_num];
|
||||
for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->q,
|
||||
&ionic_txq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->cq,
|
||||
&ionic_dbg_cq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->intr,
|
||||
&ionic_dbg_intr_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->napi_stats,
|
||||
&ionic_dbg_napi_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
|
||||
**buf = txqcq->napi_stats.work_done_cntr[i];
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
|
||||
**buf = txstats->sg_cntr[i];
|
||||
(*buf)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void ionic_sw_stats_get_rxq_values(struct ionic_lif *lif, u64 **buf,
|
||||
int q_num)
|
||||
{
|
||||
struct ionic_rx_stats *rxstats;
|
||||
struct ionic_qcq *rxqcq;
|
||||
int i;
|
||||
|
||||
rxstats = &lif->rxqstats[q_num];
|
||||
|
||||
for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(rxstats, &ionic_rx_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
|
||||
if (!test_bit(IONIC_LIF_F_UP, lif->state) ||
|
||||
!test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
|
||||
return;
|
||||
|
||||
rxqcq = lif->rxqcqs[q_num];
|
||||
for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->cq,
|
||||
&ionic_dbg_cq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->intr,
|
||||
&ionic_dbg_intr_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->napi_stats,
|
||||
&ionic_dbg_napi_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
|
||||
**buf = rxqcq->napi_stats.work_done_cntr[i];
|
||||
(*buf)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
|
||||
{
|
||||
struct ionic_port_stats *port_stats;
|
||||
struct ionic_lif_sw_stats lif_stats;
|
||||
struct ionic_qcq *txqcq, *rxqcq;
|
||||
struct ionic_tx_stats *txstats;
|
||||
struct ionic_rx_stats *rxstats;
|
||||
int i, q_num;
|
||||
|
||||
ionic_get_lif_stats(lif, &lif_stats);
|
||||
@ -338,73 +431,11 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
|
||||
(*buf)++;
|
||||
}
|
||||
|
||||
for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
|
||||
txstats = &lif->txqstats[q_num];
|
||||
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
|
||||
ionic_sw_stats_get_txq_values(lif, buf, q_num);
|
||||
|
||||
for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(txstats,
|
||||
&ionic_tx_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
|
||||
if (test_bit(IONIC_LIF_F_UP, lif->state) &&
|
||||
test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
|
||||
txqcq = lif->txqcqs[q_num];
|
||||
for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->q,
|
||||
&ionic_txq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->cq,
|
||||
&ionic_dbg_cq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&txqcq->intr,
|
||||
&ionic_dbg_intr_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
|
||||
**buf = txstats->sg_cntr[i];
|
||||
(*buf)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
|
||||
rxstats = &lif->rxqstats[q_num];
|
||||
|
||||
for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(rxstats,
|
||||
&ionic_rx_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
|
||||
if (test_bit(IONIC_LIF_F_UP, lif->state) &&
|
||||
test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
|
||||
rxqcq = lif->rxqcqs[q_num];
|
||||
for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->cq,
|
||||
&ionic_dbg_cq_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->intr,
|
||||
&ionic_dbg_intr_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
|
||||
**buf = IONIC_READ_STAT64(&rxqcq->napi_stats,
|
||||
&ionic_dbg_napi_stats_desc[i]);
|
||||
(*buf)++;
|
||||
}
|
||||
for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
|
||||
**buf = rxqcq->napi_stats.work_done_cntr[i];
|
||||
(*buf)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (q_num = 0; q_num < MAX_Q(lif); q_num++)
|
||||
ionic_sw_stats_get_rxq_values(lif, buf, q_num);
|
||||
}
|
||||
|
||||
const struct ionic_stats_group_intf ionic_stats_groups[] = {
|
||||
|
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user