Commit 92a84c78 authored by David S. Miller's avatar 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: default avatarDavid S. Miller <davem@davemloft.net>
parents 6b9ea5ff 7c7b58ec
......@@ -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;
......
......@@ -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)
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));
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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment