提交 92a84c78 编写于 作者: D David S. Miller

Merge branch 'ionic-updates'

Shannon Nelson says:

====================
ionic updates

This set of patches is a bunch of code cleanup, a little
documentation, longer tx sg lists, more ethtool stats,
and a couple more transceiver types.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -11,6 +11,9 @@ Contents
========
- Identifying the Adapter
- Enabling the driver
- Configuring the driver
- Statistics
- Support
Identifying the Adapter
......@@ -28,12 +31,238 @@ and configure them for use. There should be log entries in the kernel
messages such as these::
$ dmesg | grep ionic
ionic Pensando Ethernet NIC Driver, ver 0.15.0-k
ionic 0000:b5:00.0: 126.016 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x16 link)
ionic 0000:b5:00.0 enp181s0: renamed from eth0
ionic 0000:b5:00.0 enp181s0: Link up - 100 Gbps
ionic 0000:b6:00.0: 126.016 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x16 link)
ionic 0000:b6:00.0 enp182s0: renamed from eth0
ionic 0000:b6:00.0 enp182s0: Link up - 100 Gbps
Driver and firmware version information can be gathered with either of
ethtool or devlink tools::
$ ethtool -i enp181s0
driver: ionic
version: 5.7.0
firmware-version: 1.8.0-28
...
$ devlink dev info pci/0000:b5:00.0
pci/0000:b5:00.0:
driver ionic
serial_number FLM18420073
versions:
fixed:
asic.id 0x0
asic.rev 0x0
running:
fw 1.8.0-28
See Documentation/networking/devlink/ionic.rst for more information
on the devlink dev info data.
Enabling the driver
===================
The driver is enabled via the standard kernel configuration system,
using the make command::
make oldconfig/menuconfig/etc.
The driver is located in the menu structure at:
-> Device Drivers
-> Network device support (NETDEVICES [=y])
-> Ethernet driver support
-> Pensando devices
-> Pensando Ethernet IONIC Support
Configuring the Driver
======================
MTU
---
Jumbo frame support is available with a maximim size of 9194 bytes.
Interrupt coalescing
--------------------
Interrupt coalescing can be configured by changing the rx-usecs value with
the "ethtool -C" command. The rx-usecs range is 0-190. The tx-usecs value
reflects the rx-usecs value as they are tied together on the same interrupt.
SR-IOV
------
Minimal SR-IOV support is currently offered and can be enabled by setting
the sysfs 'sriov_numvfs' value, if supported by your particular firmware
configuration.
Statistics
==========
Basic hardware stats
--------------------
The commands ``netstat -i``, ``ip -s link show``, and ``ifconfig`` show
a limited set of statistics taken directly from firmware. For example::
$ ip -s link show enp181s0
7: enp181s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:ae:cd:00:07:68 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
414 5 0 0 0 0
TX: bytes packets errors dropped carrier collsns
1384 18 0 0 0 0
ethtool -S
----------
The statistics shown from the ``ethtool -S`` command includes a combination of
driver counters and firmware counters, including port and queue specific values.
The driver values are counters computed by the driver, and the firmware values
are gathered by the firmware from the port hardware and passed through the
driver with no further interpretation.
Driver port specific::
tx_packets: 12
tx_bytes: 964
rx_packets: 5
rx_bytes: 414
tx_tso: 0
tx_tso_bytes: 0
tx_csum_none: 12
tx_csum: 0
rx_csum_none: 0
rx_csum_complete: 3
rx_csum_error: 0
Driver queue specific::
tx_0_pkts: 3
tx_0_bytes: 294
tx_0_clean: 3
tx_0_dma_map_err: 0
tx_0_linearize: 0
tx_0_frags: 0
tx_0_tso: 0
tx_0_tso_bytes: 0
tx_0_csum_none: 3
tx_0_csum: 0
tx_0_vlan_inserted: 0
rx_0_pkts: 2
rx_0_bytes: 120
rx_0_dma_map_err: 0
rx_0_alloc_err: 0
rx_0_csum_none: 0
rx_0_csum_complete: 0
rx_0_csum_error: 0
rx_0_dropped: 0
rx_0_vlan_stripped: 0
Firmware port specific::
hw_tx_dropped: 0
hw_rx_dropped: 0
hw_rx_over_errors: 0
hw_rx_missed_errors: 0
hw_tx_aborted_errors: 0
frames_rx_ok: 15
frames_rx_all: 15
frames_rx_bad_fcs: 0
frames_rx_bad_all: 0
octets_rx_ok: 1290
octets_rx_all: 1290
frames_rx_unicast: 10
frames_rx_multicast: 5
frames_rx_broadcast: 0
frames_rx_pause: 0
frames_rx_bad_length: 0
frames_rx_undersized: 0
frames_rx_oversized: 0
frames_rx_fragments: 0
frames_rx_jabber: 0
frames_rx_pripause: 0
frames_rx_stomped_crc: 0
frames_rx_too_long: 0
frames_rx_vlan_good: 3
frames_rx_dropped: 0
frames_rx_less_than_64b: 0
frames_rx_64b: 4
frames_rx_65b_127b: 11
frames_rx_128b_255b: 0
frames_rx_256b_511b: 0
frames_rx_512b_1023b: 0
frames_rx_1024b_1518b: 0
frames_rx_1519b_2047b: 0
frames_rx_2048b_4095b: 0
frames_rx_4096b_8191b: 0
frames_rx_8192b_9215b: 0
frames_rx_other: 0
frames_tx_ok: 31
frames_tx_all: 31
frames_tx_bad: 0
octets_tx_ok: 2614
octets_tx_total: 2614
frames_tx_unicast: 8
frames_tx_multicast: 21
frames_tx_broadcast: 2
frames_tx_pause: 0
frames_tx_pripause: 0
frames_tx_vlan: 0
frames_tx_less_than_64b: 0
frames_tx_64b: 4
frames_tx_65b_127b: 27
frames_tx_128b_255b: 0
frames_tx_256b_511b: 0
frames_tx_512b_1023b: 0
frames_tx_1024b_1518b: 0
frames_tx_1519b_2047b: 0
frames_tx_2048b_4095b: 0
frames_tx_4096b_8191b: 0
frames_tx_8192b_9215b: 0
frames_tx_other: 0
frames_tx_pri_0: 0
frames_tx_pri_1: 0
frames_tx_pri_2: 0
frames_tx_pri_3: 0
frames_tx_pri_4: 0
frames_tx_pri_5: 0
frames_tx_pri_6: 0
frames_tx_pri_7: 0
frames_rx_pri_0: 0
frames_rx_pri_1: 0
frames_rx_pri_2: 0
frames_rx_pri_3: 0
frames_rx_pri_4: 0
frames_rx_pri_5: 0
frames_rx_pri_6: 0
frames_rx_pri_7: 0
tx_pripause_0_1us_count: 0
tx_pripause_1_1us_count: 0
tx_pripause_2_1us_count: 0
tx_pripause_3_1us_count: 0
tx_pripause_4_1us_count: 0
tx_pripause_5_1us_count: 0
tx_pripause_6_1us_count: 0
tx_pripause_7_1us_count: 0
rx_pripause_0_1us_count: 0
rx_pripause_1_1us_count: 0
rx_pripause_2_1us_count: 0
rx_pripause_3_1us_count: 0
rx_pripause_4_1us_count: 0
rx_pripause_5_1us_count: 0
rx_pripause_6_1us_count: 0
rx_pripause_7_1us_count: 0
rx_pause_1us_count: 0
frames_tx_truncated: 0
Support
=======
For general Linux networking support, please use the netdev mailing
list, which is monitored by Pensando personnel::
......
......@@ -388,6 +388,19 @@ int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data)
}
/* LIF commands */
void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
u16 lif_type, u8 qtype, u8 qver)
{
union ionic_dev_cmd cmd = {
.q_identify.opcode = IONIC_CMD_Q_IDENTIFY,
.q_identify.lif_type = lif_type,
.q_identify.type = qtype,
.q_identify.ver = qver,
};
ionic_dev_cmd_go(idev, &cmd);
}
void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver)
{
union ionic_dev_cmd cmd = {
......@@ -431,6 +444,7 @@ void ionic_dev_cmd_adminq_init(struct ionic_dev *idev, struct ionic_qcq *qcq,
.q_init.opcode = IONIC_CMD_Q_INIT,
.q_init.lif_index = cpu_to_le16(lif_index),
.q_init.type = q->type,
.q_init.ver = qcq->q.lif->qtype_info[q->type].version,
.q_init.index = cpu_to_le32(q->index),
.q_init.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
IONIC_QINIT_F_ENA),
......
......@@ -12,7 +12,8 @@
#define IONIC_MIN_MTU ETH_MIN_MTU
#define IONIC_MAX_MTU 9194
#define IONIC_MAX_TXRX_DESC 16384
#define IONIC_MAX_TX_DESC 8192
#define IONIC_MAX_RX_DESC 16384
#define IONIC_MIN_TXRX_DESC 16
#define IONIC_DEF_TXRX_DESC 4096
#define IONIC_LIFS_MAX 1024
......@@ -83,6 +84,8 @@ static_assert(sizeof(struct ionic_q_init_cmd) == 64);
static_assert(sizeof(struct ionic_q_init_comp) == 16);
static_assert(sizeof(struct ionic_q_control_cmd) == 64);
static_assert(sizeof(ionic_q_control_comp) == 16);
static_assert(sizeof(struct ionic_q_identify_cmd) == 64);
static_assert(sizeof(struct ionic_q_identify_comp) == 16);
static_assert(sizeof(struct ionic_rx_mode_set_cmd) == 64);
static_assert(sizeof(ionic_rx_mode_set_comp) == 16);
......@@ -179,7 +182,7 @@ struct ionic_desc_info {
void *cb_arg;
};
#define QUEUE_NAME_MAX_SZ 32
#define IONIC_QUEUE_NAME_MAX_SZ 32
struct ionic_queue {
u64 dbell_count;
......@@ -204,14 +207,14 @@ struct ionic_queue {
unsigned int desc_size;
unsigned int sg_desc_size;
unsigned int pid;
char name[QUEUE_NAME_MAX_SZ];
char name[IONIC_QUEUE_NAME_MAX_SZ];
};
#define INTR_INDEX_NOT_ASSIGNED -1
#define INTR_NAME_MAX_SZ 32
#define IONIC_INTR_INDEX_NOT_ASSIGNED -1
#define IONIC_INTR_NAME_MAX_SZ 32
struct ionic_intr_info {
char name[INTR_NAME_MAX_SZ];
char name[IONIC_INTR_NAME_MAX_SZ];
unsigned int index;
unsigned int vector;
u64 rearm_count;
......@@ -283,6 +286,8 @@ void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type);
void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type);
int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data);
void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
u16 lif_type, u8 qtype, u8 qver);
void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver);
void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index,
dma_addr_t addr);
......
......@@ -12,10 +12,11 @@
#include "ionic_stats.h"
static const char ionic_priv_flags_strings[][ETH_GSTRING_LEN] = {
#define PRIV_F_SW_DBG_STATS BIT(0)
#define IONIC_PRIV_F_SW_DBG_STATS BIT(0)
"sw-dbg-stats",
};
#define PRIV_FLAGS_COUNT ARRAY_SIZE(ionic_priv_flags_strings)
#define IONIC_PRIV_FLAGS_COUNT ARRAY_SIZE(ionic_priv_flags_strings)
static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf)
{
......@@ -58,7 +59,7 @@ static int ionic_get_sset_count(struct net_device *netdev, int sset)
count = ionic_get_stats_count(lif);
break;
case ETH_SS_PRIV_FLAGS:
count = PRIV_FLAGS_COUNT;
count = IONIC_PRIV_FLAGS_COUNT;
break;
}
return count;
......@@ -75,7 +76,7 @@ static void ionic_get_strings(struct net_device *netdev,
break;
case ETH_SS_PRIV_FLAGS:
memcpy(buf, ionic_priv_flags_strings,
PRIV_FLAGS_COUNT * ETH_GSTRING_LEN);
IONIC_PRIV_FLAGS_COUNT * ETH_GSTRING_LEN);
break;
}
}
......@@ -159,6 +160,8 @@ static int ionic_get_link_ksettings(struct net_device *netdev,
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseSR4_Full);
break;
case IONIC_XCVR_PID_QSFP_100G_CWDM4:
case IONIC_XCVR_PID_QSFP_100G_PSM4:
case IONIC_XCVR_PID_QSFP_100G_LR4:
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseLR4_ER4_Full);
......@@ -178,6 +181,7 @@ static int ionic_get_link_ksettings(struct net_device *netdev,
break;
case IONIC_XCVR_PID_SFP_25GBASE_SR:
case IONIC_XCVR_PID_SFP_25GBASE_AOC:
case IONIC_XCVR_PID_SFP_25GBASE_ACC:
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseSR_Full);
break;
......@@ -458,9 +462,9 @@ static void ionic_get_ringparam(struct net_device *netdev,
{
struct ionic_lif *lif = netdev_priv(netdev);
ring->tx_max_pending = IONIC_MAX_TXRX_DESC;
ring->tx_max_pending = IONIC_MAX_TX_DESC;
ring->tx_pending = lif->ntxq_descs;
ring->rx_max_pending = IONIC_MAX_TXRX_DESC;
ring->rx_max_pending = IONIC_MAX_RX_DESC;
ring->rx_pending = lif->nrxq_descs;
}
......@@ -554,7 +558,7 @@ static u32 ionic_get_priv_flags(struct net_device *netdev)
u32 priv_flags = 0;
if (test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
priv_flags |= PRIV_F_SW_DBG_STATS;
priv_flags |= IONIC_PRIV_F_SW_DBG_STATS;
return priv_flags;
}
......@@ -564,7 +568,7 @@ static int ionic_set_priv_flags(struct net_device *netdev, u32 priv_flags)
struct ionic_lif *lif = netdev_priv(netdev);
clear_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state);
if (priv_flags & PRIV_F_SW_DBG_STATS)
if (priv_flags & IONIC_PRIV_F_SW_DBG_STATS)
set_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state);
return 0;
......
......@@ -17,6 +17,16 @@
#include "ionic_ethtool.h"
#include "ionic_debugfs.h"
/* queuetype support level */
static const u8 ionic_qtype_versions[IONIC_QTYPE_MAX] = {
[IONIC_QTYPE_ADMINQ] = 0, /* 0 = Base version with CQ support */
[IONIC_QTYPE_NOTIFYQ] = 0, /* 0 = Base version */
[IONIC_QTYPE_RXQ] = 0, /* 0 = Base version with CQ+SG support */
[IONIC_QTYPE_TXQ] = 1, /* 0 = Base version with CQ+SG support
* 1 = ... with Tx SG version 1
*/
};
static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode);
static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
......@@ -27,6 +37,7 @@ static void ionic_lif_set_netdev_info(struct ionic_lif *lif);
static int ionic_start_queues(struct ionic_lif *lif);
static void ionic_stop_queues(struct ionic_lif *lif);
static void ionic_lif_queue_identify(struct ionic_lif *lif);
static void ionic_lif_deferred_work(struct work_struct *work)
{
......@@ -186,10 +197,10 @@ static int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
return 0;
}
static void ionic_intr_free(struct ionic_lif *lif, int index)
static void ionic_intr_free(struct ionic *ionic, int index)
{
if (index != INTR_INDEX_NOT_ASSIGNED && index < lif->ionic->nintrs)
clear_bit(index, lif->ionic->intrs);
if (index != IONIC_INTR_INDEX_NOT_ASSIGNED && index < ionic->nintrs)
clear_bit(index, ionic->intrs);
}
static int ionic_qcq_enable(struct ionic_qcq *qcq)
......@@ -299,7 +310,7 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
irq_set_affinity_hint(qcq->intr.vector, NULL);
devm_free_irq(dev, qcq->intr.vector, &qcq->napi);
qcq->intr.vector = 0;
ionic_intr_free(lif, qcq->intr.index);
ionic_intr_free(lif->ionic, qcq->intr.index);
}
devm_kfree(dev, qcq->cq.info);
......@@ -345,7 +356,7 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
struct ionic_qcq *n_qcq)
{
if (WARN_ON(n_qcq->flags & IONIC_QCQ_F_INTR)) {
ionic_intr_free(n_qcq->cq.lif, n_qcq->intr.index);
ionic_intr_free(n_qcq->cq.lif->ionic, n_qcq->intr.index);
n_qcq->flags &= ~IONIC_QCQ_F_INTR;
}
......@@ -444,7 +455,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
cpumask_set_cpu(new->intr.cpu,
&new->intr.affinity_mask);
} else {
new->intr.index = INTR_INDEX_NOT_ASSIGNED;
new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
}
new->cq.info = devm_kzalloc(dev, sizeof(*new->cq.info) * num_descs,
......@@ -497,7 +508,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
devm_free_irq(dev, new->intr.vector, &new->napi);
err_out_free_intr:
if (flags & IONIC_QCQ_F_INTR)
ionic_intr_free(lif, new->intr.index);
ionic_intr_free(lif->ionic, new->intr.index);
err_out:
dev_err(dev, "qcq alloc of %s%d failed %d\n", name, index, err);
return err;
......@@ -597,6 +608,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
.opcode = IONIC_CMD_Q_INIT,
.lif_index = cpu_to_le16(lif->index),
.type = q->type,
.ver = lif->qtype_info[q->type].version,
.index = cpu_to_le32(q->index),
.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
IONIC_QINIT_F_SG),
......@@ -614,6 +626,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "txq_init.index %d\n", ctx.cmd.q_init.index);
dev_dbg(dev, "txq_init.ring_base 0x%llx\n", ctx.cmd.q_init.ring_base);
dev_dbg(dev, "txq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
dev_dbg(dev, "txq_init.flags 0x%x\n", ctx.cmd.q_init.flags);
dev_dbg(dev, "txq_init.ver %d\n", ctx.cmd.q_init.ver);
q->tail = q->info;
q->head = q->tail;
......@@ -646,6 +660,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
.opcode = IONIC_CMD_Q_INIT,
.lif_index = cpu_to_le16(lif->index),
.type = q->type,
.ver = lif->qtype_info[q->type].version,
.index = cpu_to_le32(q->index),
.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
IONIC_QINIT_F_SG),
......@@ -663,6 +678,8 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "rxq_init.index %d\n", ctx.cmd.q_init.index);
dev_dbg(dev, "rxq_init.ring_base 0x%llx\n", ctx.cmd.q_init.ring_base);
dev_dbg(dev, "rxq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
dev_dbg(dev, "rxq_init.flags 0x%x\n", ctx.cmd.q_init.flags);
dev_dbg(dev, "rxq_init.ver %d\n", ctx.cmd.q_init.ver);
q->tail = q->info;
q->head = q->tail;
......@@ -726,7 +743,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
}
break;
default:
netdev_warn(netdev, "Notifyq unknown event ecode=%d eid=%lld\n",
netdev_warn(netdev, "Notifyq event ecode=%d eid=%lld\n",
comp->event.ecode, eid);
break;
}
......@@ -775,8 +792,8 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
return max(n_work, a_work);
}
static void ionic_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *ns)
void ionic_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *ns)
{
struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_lif_stats *ls;
......@@ -1509,17 +1526,25 @@ 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 flags;
unsigned int i;
int err = 0;
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);
flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
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),
sizeof(struct ionic_txq_sg_desc),
sg_desc_sz,
lif->kern_pid, &lif->txqcqs[i].qcq);
if (err)
goto err_out;
......@@ -1682,7 +1707,7 @@ int ionic_stop(struct net_device *netdev)
{
struct ionic_lif *lif = netdev_priv(netdev);
if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
if (!netif_device_present(netdev))
return 0;
ionic_stop_queues(lif);
......@@ -1699,6 +1724,9 @@ static int ionic_get_vf_config(struct net_device *netdev,
struct ionic *ionic = lif->ionic;
int ret = 0;
if (!netif_device_present(netdev))
return -EBUSY;
down_read(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1726,6 +1754,9 @@ static int ionic_get_vf_stats(struct net_device *netdev, int vf,
struct ionic_lif_stats *vs;
int ret = 0;
if (!netif_device_present(netdev))
return -EBUSY;
down_read(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1761,6 +1792,9 @@ static int ionic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
if (!(is_zero_ether_addr(mac) || is_valid_ether_addr(mac)))
return -EINVAL;
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1792,6 +1826,9 @@ static int ionic_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
if (proto != htons(ETH_P_8021Q))
return -EPROTONOSUPPORT;
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1818,6 +1855,9 @@ static int ionic_set_vf_rate(struct net_device *netdev, int vf,
if (tx_min)
return -EINVAL;
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1840,6 +1880,9 @@ static int ionic_set_vf_spoofchk(struct net_device *netdev, int vf, bool set)
u8 data = set; /* convert to u8 for config */
int ret;
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1862,6 +1905,9 @@ static int ionic_set_vf_trust(struct net_device *netdev, int vf, bool set)
u8 data = set; /* convert to u8 for config */
int ret;
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -1898,6 +1944,9 @@ static int ionic_set_vf_link_state(struct net_device *netdev, int vf, int set)
return -EINVAL;
}
if (!netif_device_present(netdev))
return -EBUSY;
down_write(&ionic->vf_op_lock);
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
......@@ -2065,9 +2114,17 @@ int ionic_lifs_alloc(struct ionic *ionic)
/* only build the first lif, others are for later features */
set_bit(0, ionic->lifbits);
lif = ionic_lif_alloc(ionic, 0);
if (IS_ERR_OR_NULL(lif)) {
clear_bit(0, ionic->lifbits);
return -ENOMEM;
}
return PTR_ERR_OR_ZERO(lif);
lif->lif_type = IONIC_LIF_TYPE_CLASSIC;
ionic_lif_queue_identify(lif);
return 0;
}
static void ionic_lif_reset(struct ionic_lif *lif)
......@@ -2291,6 +2348,7 @@ static int ionic_lif_notifyq_init(struct ionic_lif *lif)
.opcode = IONIC_CMD_Q_INIT,
.lif_index = cpu_to_le16(lif->index),
.type = q->type,
.ver = lif->qtype_info[q->type].version,
.index = cpu_to_le32(q->index),
.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
IONIC_QINIT_F_ENA),
......@@ -2573,6 +2631,80 @@ void ionic_lifs_unregister(struct ionic *ionic)
unregister_netdev(ionic->master_lif->netdev);
}
static void ionic_lif_queue_identify(struct ionic_lif *lif)
{
struct ionic *ionic = lif->ionic;
union ionic_q_identity *q_ident;
struct ionic_dev *idev;
int qtype;
int err;
idev = &lif->ionic->idev;
q_ident = (union ionic_q_identity *)&idev->dev_cmd_regs->data;
for (qtype = 0; qtype < ARRAY_SIZE(ionic_qtype_versions); qtype++) {
struct ionic_qtype_info *qti = &lif->qtype_info[qtype];
/* filter out the ones we know about */
switch (qtype) {
case IONIC_QTYPE_ADMINQ:
case IONIC_QTYPE_NOTIFYQ:
case IONIC_QTYPE_RXQ:
case IONIC_QTYPE_TXQ:
break;
default:
continue;
}
memset(qti, 0, sizeof(*qti));
mutex_lock(&ionic->dev_cmd_lock);
ionic_dev_cmd_queue_identify(idev, lif->lif_type, qtype,
ionic_qtype_versions[qtype]);
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
if (!err) {
qti->version = q_ident->version;
qti->supported = q_ident->supported;
qti->features = le64_to_cpu(q_ident->features);
qti->desc_sz = le16_to_cpu(q_ident->desc_sz);
qti->comp_sz = le16_to_cpu(q_ident->comp_sz);
qti->sg_desc_sz = le16_to_cpu(q_ident->sg_desc_sz);
qti->max_sg_elems = le16_to_cpu(q_ident->max_sg_elems);
qti->sg_desc_stride = le16_to_cpu(q_ident->sg_desc_stride);
}
mutex_unlock(&ionic->dev_cmd_lock);
if (err == -EINVAL) {
dev_err(ionic->dev, "qtype %d not supported\n", qtype);
continue;
} else if (err == -EIO) {
dev_err(ionic->dev, "q_ident failed, not supported on older FW\n");
return;
} else if (err) {
dev_err(ionic->dev, "q_ident failed, qtype %d: %d\n",
qtype, err);
return;
}
dev_dbg(ionic->dev, " qtype[%d].version = %d\n",
qtype, qti->version);
dev_dbg(ionic->dev, " qtype[%d].supported = 0x%02x\n",
qtype, qti->supported);
dev_dbg(ionic->dev, " qtype[%d].features = 0x%04llx\n",
qtype, qti->features);
dev_dbg(ionic->dev, " qtype[%d].desc_sz = %d\n",
qtype, qti->desc_sz);
dev_dbg(ionic->dev, " qtype[%d].comp_sz = %d\n",
qtype, qti->comp_sz);
dev_dbg(ionic->dev, " qtype[%d].sg_desc_sz = %d\n",
qtype, qti->sg_desc_sz);
dev_dbg(ionic->dev, " qtype[%d].max_sg_elems = %d\n",
qtype, qti->max_sg_elems);
dev_dbg(ionic->dev, " qtype[%d].sg_desc_stride = %d\n",
qtype, qti->sg_desc_stride);
}
}
int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
union ionic_lif_identity *lid)
{
......
......@@ -20,11 +20,13 @@ struct ionic_tx_stats {
u64 bytes;
u64 clean;
u64 linearize;
u64 no_csum;
u64 csum_none;
u64 csum;
u64 crc32_csum;
u64 tso;
u64 tso_bytes;
u64 frags;
u64 vlan_inserted;
u64 sg_cntr[IONIC_MAX_NUM_SG_CNTR];
};
......@@ -38,6 +40,7 @@ struct ionic_rx_stats {
u64 csum_error;
u64 buffers_posted;
u64 dropped;
u64 vlan_stripped;
};
#define IONIC_QCQ_F_INITED BIT(0)
......@@ -114,11 +117,17 @@ struct ionic_lif_sw_stats {
u64 rx_packets;
u64 rx_bytes;
u64 tx_tso;
u64 tx_no_csum;
u64 tx_tso_bytes;
u64 tx_csum_none;
u64 tx_csum;
u64 rx_csum_none;
u64 rx_csum_complete;
u64 rx_csum_error;
u64 hw_tx_dropped;
u64 hw_rx_dropped;
u64 hw_rx_over_errors;
u64 hw_rx_missed_errors;
u64 hw_tx_aborted_errors;
};
enum ionic_lif_state_flags {
......@@ -133,6 +142,17 @@ enum ionic_lif_state_flags {
IONIC_LIF_F_STATE_SIZE
};
struct ionic_qtype_info {
u8 version;
u8 supported;
u64 features;
u16 desc_sz;
u16 comp_sz;
u16 sg_desc_sz;
u16 max_sg_elems;
u16 sg_desc_stride;
};
#define IONIC_LIF_NAME_MAX_SZ 32
struct ionic_lif {
char name[IONIC_LIF_NAME_MAX_SZ];
......@@ -161,11 +181,13 @@ struct ionic_lif {
bool mc_overflow;
unsigned int nmcast;
bool uc_overflow;
u16 lif_type;
unsigned int nucast;
struct ionic_lif_info *info;
dma_addr_t info_pa;
u32 info_sz;
struct ionic_qtype_info qtype_info[IONIC_QTYPE_MAX];
u16 rss_types;
u8 rss_hash_key[IONIC_RSS_HASH_KEY_SIZE];
......@@ -227,6 +249,8 @@ static inline u32 ionic_coal_hw_to_usec(struct ionic *ionic, u32 units)
}
void ionic_link_status_check_request(struct ionic_lif *lif);
void ionic_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *ns);
void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
struct ionic_deferred_work *work);
int ionic_lifs_alloc(struct ionic *ionic);
......
......@@ -152,6 +152,8 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
return "IONIC_CMD_RX_FILTER_ADD";
case IONIC_CMD_RX_FILTER_DEL:
return "IONIC_CMD_RX_FILTER_DEL";
case IONIC_CMD_Q_IDENTIFY:
return "IONIC_CMD_Q_IDENTIFY";
case IONIC_CMD_Q_INIT:
return "IONIC_CMD_Q_INIT";
case IONIC_CMD_Q_CONTROL:
......@@ -356,7 +358,7 @@ int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds)
done = ionic_dev_cmd_done(idev);
if (done)
break;
msleep(20);
msleep(5);
hb = ionic_heartbeat_check(ionic);
} while (!done && !hb && time_before(jiffies, max_wait));
duration = jiffies - start_time;
......@@ -413,6 +415,7 @@ int ionic_setup(struct ionic *ionic)
err = ionic_dev_setup(ionic);
if (err)
return err;
ionic_reset(ionic);
return 0;
}
......
......@@ -15,11 +15,109 @@ static const struct ionic_stat_desc ionic_lif_stats_desc[] = {
IONIC_LIF_STAT_DESC(rx_packets),
IONIC_LIF_STAT_DESC(rx_bytes),
IONIC_LIF_STAT_DESC(tx_tso),
IONIC_LIF_STAT_DESC(tx_no_csum),
IONIC_LIF_STAT_DESC(tx_tso_bytes),
IONIC_LIF_STAT_DESC(tx_csum_none),
IONIC_LIF_STAT_DESC(tx_csum),
IONIC_LIF_STAT_DESC(rx_csum_none),
IONIC_LIF_STAT_DESC(rx_csum_complete),
IONIC_LIF_STAT_DESC(rx_csum_error),
IONIC_LIF_STAT_DESC(hw_tx_dropped),
IONIC_LIF_STAT_DESC(hw_rx_dropped),
IONIC_LIF_STAT_DESC(hw_rx_over_errors),
IONIC_LIF_STAT_DESC(hw_rx_missed_errors),
IONIC_LIF_STAT_DESC(hw_tx_aborted_errors),
};
static const struct ionic_stat_desc ionic_port_stats_desc[] = {
IONIC_PORT_STAT_DESC(frames_rx_ok),
IONIC_PORT_STAT_DESC(frames_rx_all),
IONIC_PORT_STAT_DESC(frames_rx_bad_fcs),
IONIC_PORT_STAT_DESC(frames_rx_bad_all),
IONIC_PORT_STAT_DESC(octets_rx_ok),
IONIC_PORT_STAT_DESC(octets_rx_all),
IONIC_PORT_STAT_DESC(frames_rx_unicast),
IONIC_PORT_STAT_DESC(frames_rx_multicast),
IONIC_PORT_STAT_DESC(frames_rx_broadcast),
IONIC_PORT_STAT_DESC(frames_rx_pause),
IONIC_PORT_STAT_DESC(frames_rx_bad_length),
IONIC_PORT_STAT_DESC(frames_rx_undersized),
IONIC_PORT_STAT_DESC(frames_rx_oversized),
IONIC_PORT_STAT_DESC(frames_rx_fragments),
IONIC_PORT_STAT_DESC(frames_rx_jabber),
IONIC_PORT_STAT_DESC(frames_rx_pripause),
IONIC_PORT_STAT_DESC(frames_rx_stomped_crc),
IONIC_PORT_STAT_DESC(frames_rx_too_long),
IONIC_PORT_STAT_DESC(frames_rx_vlan_good),
IONIC_PORT_STAT_DESC(frames_rx_dropped),
IONIC_PORT_STAT_DESC(frames_rx_less_than_64b),
IONIC_PORT_STAT_DESC(frames_rx_64b),
IONIC_PORT_STAT_DESC(frames_rx_65b_127b),
IONIC_PORT_STAT_DESC(frames_rx_128b_255b),
IONIC_PORT_STAT_DESC(frames_rx_256b_511b),
IONIC_PORT_STAT_DESC(frames_rx_512b_1023b),
IONIC_PORT_STAT_DESC(frames_rx_1024b_1518b),
IONIC_PORT_STAT_DESC(frames_rx_1519b_2047b),
IONIC_PORT_STAT_DESC(frames_rx_2048b_4095b),
IONIC_PORT_STAT_DESC(frames_rx_4096b_8191b),
IONIC_PORT_STAT_DESC(frames_rx_8192b_9215b),
IONIC_PORT_STAT_DESC(frames_rx_other),
IONIC_PORT_STAT_DESC(frames_tx_ok),
IONIC_PORT_STAT_DESC(frames_tx_all),
IONIC_PORT_STAT_DESC(frames_tx_bad),
IONIC_PORT_STAT_DESC(octets_tx_ok),
IONIC_PORT_STAT_DESC(octets_tx_total),
IONIC_PORT_STAT_DESC(frames_tx_unicast),
IONIC_PORT_STAT_DESC(frames_tx_multicast),
IONIC_PORT_STAT_DESC(frames_tx_broadcast),
IONIC_PORT_STAT_DESC(frames_tx_pause),
IONIC_PORT_STAT_DESC(frames_tx_pripause),
IONIC_PORT_STAT_DESC(frames_tx_vlan),
IONIC_PORT_STAT_DESC(frames_tx_less_than_64b),
IONIC_PORT_STAT_DESC(frames_tx_64b),
IONIC_PORT_STAT_DESC(frames_tx_65b_127b),
IONIC_PORT_STAT_DESC(frames_tx_128b_255b),
IONIC_PORT_STAT_DESC(frames_tx_256b_511b),
IONIC_PORT_STAT_DESC(frames_tx_512b_1023b),
IONIC_PORT_STAT_DESC(frames_tx_1024b_1518b),
IONIC_PORT_STAT_DESC(frames_tx_1519b_2047b),
IONIC_PORT_STAT_DESC(frames_tx_2048b_4095b),
IONIC_PORT_STAT_DESC(frames_tx_4096b_8191b),
IONIC_PORT_STAT_DESC(frames_tx_8192b_9215b),
IONIC_PORT_STAT_DESC(frames_tx_other),
IONIC_PORT_STAT_DESC(frames_tx_pri_0),
IONIC_PORT_STAT_DESC(frames_tx_pri_1),
IONIC_PORT_STAT_DESC(frames_tx_pri_2),
IONIC_PORT_STAT_DESC(frames_tx_pri_3),
IONIC_PORT_STAT_DESC(frames_tx_pri_4),
IONIC_PORT_STAT_DESC(frames_tx_pri_5),
IONIC_PORT_STAT_DESC(frames_tx_pri_6),
IONIC_PORT_STAT_DESC(frames_tx_pri_7),
IONIC_PORT_STAT_DESC(frames_rx_pri_0),
IONIC_PORT_STAT_DESC(frames_rx_pri_1),
IONIC_PORT_STAT_DESC(frames_rx_pri_2),
IONIC_PORT_STAT_DESC(frames_rx_pri_3),
IONIC_PORT_STAT_DESC(frames_rx_pri_4),
IONIC_PORT_STAT_DESC(frames_rx_pri_5),
IONIC_PORT_STAT_DESC(frames_rx_pri_6),
IONIC_PORT_STAT_DESC(frames_rx_pri_7),
IONIC_PORT_STAT_DESC(tx_pripause_0_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_1_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_2_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_3_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_4_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_5_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_6_1us_count),
IONIC_PORT_STAT_DESC(tx_pripause_7_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_0_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_1_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_2_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_3_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_4_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_5_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_6_1us_count),
IONIC_PORT_STAT_DESC(rx_pripause_7_1us_count),
IONIC_PORT_STAT_DESC(rx_pause_1us_count),
IONIC_PORT_STAT_DESC(frames_tx_truncated),
};
static const struct ionic_stat_desc ionic_tx_stats_desc[] = {
......@@ -29,6 +127,11 @@ static const struct ionic_stat_desc ionic_tx_stats_desc[] = {
IONIC_TX_STAT_DESC(dma_map_err),
IONIC_TX_STAT_DESC(linearize),
IONIC_TX_STAT_DESC(frags),
IONIC_TX_STAT_DESC(tso),
IONIC_TX_STAT_DESC(tso_bytes),
IONIC_TX_STAT_DESC(csum_none),
IONIC_TX_STAT_DESC(csum),
IONIC_TX_STAT_DESC(vlan_inserted),
};
static const struct ionic_stat_desc ionic_rx_stats_desc[] = {
......@@ -40,6 +143,7 @@ static const struct ionic_stat_desc ionic_rx_stats_desc[] = {
IONIC_RX_STAT_DESC(csum_complete),
IONIC_RX_STAT_DESC(csum_error),
IONIC_RX_STAT_DESC(dropped),
IONIC_RX_STAT_DESC(vlan_stripped),
};
static const struct ionic_stat_desc ionic_txq_stats_desc[] = {
......@@ -62,6 +166,7 @@ static const struct ionic_stat_desc ionic_dbg_napi_stats_desc[] = {
};
#define IONIC_NUM_LIF_STATS ARRAY_SIZE(ionic_lif_stats_desc)
#define IONIC_NUM_PORT_STATS ARRAY_SIZE(ionic_port_stats_desc)
#define IONIC_NUM_TX_STATS ARRAY_SIZE(ionic_tx_stats_desc)
#define IONIC_NUM_RX_STATS ARRAY_SIZE(ionic_rx_stats_desc)
#define IONIC_NUM_TX_Q_STATS ARRAY_SIZE(ionic_txq_stats_desc)
......@@ -76,6 +181,7 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
{
struct ionic_tx_stats *tstats;
struct ionic_rx_stats *rstats;
struct rtnl_link_stats64 ns;
struct ionic_qcq *txqcq;
struct ionic_qcq *rxqcq;
int q_num;
......@@ -89,7 +195,8 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
stats->tx_packets += tstats->pkts;
stats->tx_bytes += tstats->bytes;
stats->tx_tso += tstats->tso;
stats->tx_no_csum += tstats->no_csum;
stats->tx_tso_bytes += tstats->tso_bytes;
stats->tx_csum_none += tstats->csum_none;
stats->tx_csum += tstats->csum;
}
......@@ -103,6 +210,13 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
stats->rx_csum_error += rstats->csum_error;
}
}
ionic_get_stats64(lif->netdev, &ns);
stats->hw_tx_dropped = ns.tx_dropped;
stats->hw_rx_dropped = ns.rx_dropped;
stats->hw_rx_over_errors = ns.rx_over_errors;
stats->hw_rx_missed_errors = ns.rx_missed_errors;
stats->hw_tx_aborted_errors = ns.tx_aborted_errors;
}
static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
......@@ -118,6 +232,9 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
/* rx stats */
total += MAX_Q(lif) * 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 */
......@@ -144,6 +261,13 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
snprintf(*buf, ETH_GSTRING_LEN, ionic_lif_stats_desc[i].name);
*buf += ETH_GSTRING_LEN;
}
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 (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",
......@@ -225,6 +349,7 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **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;
......@@ -238,6 +363,13 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
(*buf)++;
}
port_stats = &lif->ionic->idev.port_info->stats;
for (i = 0; i < IONIC_NUM_PORT_STATS; i++) {
**buf = IONIC_READ_STAT_LE64(port_stats,
&ionic_port_stats_desc[i]);
(*buf)++;
}
for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
txstats = &lif_to_txstats(lif, q_num);
......
......@@ -11,6 +11,9 @@
.offset = IONIC_STAT_TO_OFFSET(type, stat_name) \
}
#define IONIC_PORT_STAT_DESC(stat_name) \
IONIC_STAT_DESC(struct ionic_port_stats, stat_name)
#define IONIC_LIF_STAT_DESC(stat_name) \
IONIC_STAT_DESC(struct ionic_lif_sw_stats, stat_name)
......@@ -45,6 +48,9 @@ extern const int ionic_num_stats_grps;
#define IONIC_READ_STAT64(base_ptr, desc_ptr) \
(*((u64 *)(((u8 *)(base_ptr)) + (desc_ptr)->offset)))
#define IONIC_READ_STAT_LE64(base_ptr, desc_ptr) \
__le64_to_cpu(*((u64 *)(((u8 *)(base_ptr)) + (desc_ptr)->offset)))
struct ionic_stat_desc {
char name[ETH_GSTRING_LEN];
u64 offset;
......
......@@ -10,8 +10,10 @@
#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 void ionic_rx_clean(struct ionic_queue *q,
struct ionic_desc_info *desc_info,
struct ionic_cq_info *cq_info,
void *cb_arg);
static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
ionic_desc_cb cb_func, void *cb_arg)
......@@ -140,8 +142,10 @@ static struct sk_buff *ionic_rx_copybreak(struct ionic_queue *q,
return skb;
}
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 void ionic_rx_clean(struct ionic_queue *q,
struct ionic_desc_info *desc_info,
struct ionic_cq_info *cq_info,
void *cb_arg)
{
struct ionic_rxq_comp *comp = cq_info->cq_desc;
struct ionic_qcq *qcq = q_to_qcq(q);
......@@ -210,10 +214,11 @@ static void ionic_rx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_i
(comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_IP_BAD)))
stats->csum_error++;
if (likely(netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
if (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_VLAN)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
le16_to_cpu(comp->vlan_tci));
if (likely(netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
(comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_VLAN)) {
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
le16_to_cpu(comp->vlan_tci));
stats->vlan_stripped++;
}
if (le16_to_cpu(comp->len) <= q->lif->rx_copybreak)
......@@ -475,7 +480,8 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
return work_done;
}
static dma_addr_t ionic_tx_map_single(struct ionic_queue *q, void *data, size_t len)
static dma_addr_t ionic_tx_map_single(struct ionic_queue *q,
void *data, size_t len)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct device *dev = q->lif->ionic->dev;
......@@ -491,7 +497,8 @@ static dma_addr_t ionic_tx_map_single(struct ionic_queue *q, void *data, size_t
return dma_addr;
}
static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q, const skb_frag_t *frag,
static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q,
const skb_frag_t *frag,
size_t offset, size_t len)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
......@@ -507,8 +514,10 @@ static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q, const skb_frag_t *fra
return dma_addr;
}
static void ionic_tx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_info,
struct ionic_cq_info *cq_info, void *cb_arg)
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_txq_sg_elem *elem = sg_desc->elems;
......@@ -852,6 +861,7 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
stats->pkts += total_pkts;
stats->bytes += total_bytes;
stats->tso++;
stats->tso_bytes += total_bytes;
return 0;
......@@ -890,9 +900,12 @@ static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb)
flags, skb_shinfo(skb)->nr_frags, dma_addr);
desc->cmd = cpu_to_le64(cmd);
desc->len = cpu_to_le16(skb_headlen(skb));
desc->vlan_tci = cpu_to_le16(skb_vlan_tag_get(skb));
desc->csum_start = cpu_to_le16(skb_checksum_start_offset(skb));
desc->csum_offset = cpu_to_le16(skb->csum_offset);
if (has_vlan) {
desc->vlan_tci = cpu_to_le16(skb_vlan_tag_get(skb));
stats->vlan_inserted++;
}
if (skb->csum_not_inet)
stats->crc32_csum++;
......@@ -927,9 +940,12 @@ static int ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb)
flags, skb_shinfo(skb)->nr_frags, dma_addr);
desc->cmd = cpu_to_le64(cmd);
desc->len = cpu_to_le16(skb_headlen(skb));
desc->vlan_tci = cpu_to_le16(skb_vlan_tag_get(skb));
if (has_vlan) {
desc->vlan_tci = cpu_to_le16(skb_vlan_tag_get(skb));
stats->vlan_inserted++;
}
stats->no_csum++;
stats->csum_none++;
return 0;
}
......@@ -989,6 +1005,7 @@ static int ionic_tx(struct ionic_queue *q, struct sk_buff *skb)
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 err;
......@@ -997,7 +1014,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb)
return (skb->len / skb_shinfo(skb)->gso_size) + 1;
/* If non-TSO, just need 1 desc and nr_frags sg elems */
if (skb_shinfo(skb)->nr_frags <= IONIC_TX_MAX_SG_ELEMS)
if (skb_shinfo(skb)->nr_frags <= sg_elems)
return 1;
/* Too many frags, so linearize */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册