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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
92a84c7806
@ -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;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 @@ err_out_free_irq:
|
||||
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);
|
||||
|
||||
return PTR_ERR_OR_ZERO(lif);
|
||||
lif = ionic_lif_alloc(ionic, 0);
|
||||
if (IS_ERR_OR_NULL(lif)) {
|
||||
clear_bit(0, ionic->lifbits);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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 @@ try_again:
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user