Skip to content

Commit 9df2ed0

Browse files
Manish Chopradavem330
authored andcommitted
qed: Add statistics support
Device statistics can be gathered on-demand. This adds the qed support for reading the statistics [both function and port] from the device, and adds to the public API a method for requesting the current statistics. Signed-off-by: Manish Chopra <Manish.Chopra@qlogic.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a2ec617 commit 9df2ed0

File tree

6 files changed

+296
-1
lines changed

6 files changed

+296
-1
lines changed

drivers/net/ethernet/qlogic/qed/qed.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,20 @@ struct qed_qm_info {
212212
u32 pf_rl;
213213
};
214214

215+
struct storm_stats {
216+
u32 address;
217+
u32 len;
218+
};
219+
220+
struct qed_storm_stats {
221+
struct storm_stats mstats;
222+
struct storm_stats pstats;
223+
struct storm_stats tstats;
224+
struct storm_stats ustats;
225+
};
226+
215227
struct qed_fw_data {
228+
struct fw_ver_info *fw_ver_info;
216229
const u8 *modes_tree_buf;
217230
union init_op *init_ops;
218231
const u32 *arr_data;
@@ -296,6 +309,7 @@ struct qed_hwfn {
296309

297310
/* QM init */
298311
struct qed_qm_info qm_info;
312+
struct qed_storm_stats storm_stats;
299313

300314
/* Buffer for unzipping firmware data */
301315
void *unzip_buf;

drivers/net/ethernet/qlogic/qed/qed_dev.c

Lines changed: 243 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,10 @@ int qed_hw_init(struct qed_dev *cdev,
649649
bool allow_npar_tx_switch,
650650
const u8 *bin_fw_data)
651651
{
652-
u32 load_code, param;
652+
struct qed_storm_stats *p_stat;
653+
u32 load_code, param, *p_address;
653654
int rc, mfw_rc, i;
655+
u8 fw_vport = 0;
654656

655657
rc = qed_init_fw_data(cdev, bin_fw_data);
656658
if (rc != 0)
@@ -659,6 +661,10 @@ int qed_hw_init(struct qed_dev *cdev,
659661
for_each_hwfn(cdev, i) {
660662
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
661663

664+
rc = qed_fw_vport(p_hwfn, 0, &fw_vport);
665+
if (rc != 0)
666+
return rc;
667+
662668
/* Enable DMAE in PXP */
663669
rc = qed_change_pci_hwfn(p_hwfn, p_hwfn->p_main_ptt, true);
664670

@@ -722,6 +728,25 @@ int qed_hw_init(struct qed_dev *cdev,
722728
}
723729

724730
p_hwfn->hw_init_done = true;
731+
732+
/* init PF stats */
733+
p_stat = &p_hwfn->storm_stats;
734+
p_stat->mstats.address = BAR0_MAP_REG_MSDM_RAM +
735+
MSTORM_QUEUE_STAT_OFFSET(fw_vport);
736+
p_stat->mstats.len = sizeof(struct eth_mstorm_per_queue_stat);
737+
738+
p_stat->ustats.address = BAR0_MAP_REG_USDM_RAM +
739+
USTORM_QUEUE_STAT_OFFSET(fw_vport);
740+
p_stat->ustats.len = sizeof(struct eth_ustorm_per_queue_stat);
741+
742+
p_stat->pstats.address = BAR0_MAP_REG_PSDM_RAM +
743+
PSTORM_QUEUE_STAT_OFFSET(fw_vport);
744+
p_stat->pstats.len = sizeof(struct eth_pstorm_per_queue_stat);
745+
746+
p_address = &p_stat->tstats.address;
747+
*p_address = BAR0_MAP_REG_TSDM_RAM +
748+
TSTORM_PORT_STAT_OFFSET(MFW_PORT(p_hwfn));
749+
p_stat->tstats.len = sizeof(struct tstorm_per_port_stat);
725750
}
726751

727752
return 0;
@@ -1494,6 +1519,223 @@ void qed_chain_free(struct qed_dev *cdev,
14941519
p_chain->p_phys_addr);
14951520
}
14961521

1522+
static void __qed_get_vport_stats(struct qed_dev *cdev,
1523+
struct qed_eth_stats *stats)
1524+
{
1525+
int i, j;
1526+
1527+
memset(stats, 0, sizeof(*stats));
1528+
1529+
for_each_hwfn(cdev, i) {
1530+
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
1531+
struct eth_mstorm_per_queue_stat mstats;
1532+
struct eth_ustorm_per_queue_stat ustats;
1533+
struct eth_pstorm_per_queue_stat pstats;
1534+
struct tstorm_per_port_stat tstats;
1535+
struct port_stats port_stats;
1536+
struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
1537+
1538+
if (!p_ptt) {
1539+
DP_ERR(p_hwfn, "Failed to acquire ptt\n");
1540+
continue;
1541+
}
1542+
1543+
memset(&mstats, 0, sizeof(mstats));
1544+
qed_memcpy_from(p_hwfn, p_ptt, &mstats,
1545+
p_hwfn->storm_stats.mstats.address,
1546+
p_hwfn->storm_stats.mstats.len);
1547+
1548+
memset(&ustats, 0, sizeof(ustats));
1549+
qed_memcpy_from(p_hwfn, p_ptt, &ustats,
1550+
p_hwfn->storm_stats.ustats.address,
1551+
p_hwfn->storm_stats.ustats.len);
1552+
1553+
memset(&pstats, 0, sizeof(pstats));
1554+
qed_memcpy_from(p_hwfn, p_ptt, &pstats,
1555+
p_hwfn->storm_stats.pstats.address,
1556+
p_hwfn->storm_stats.pstats.len);
1557+
1558+
memset(&tstats, 0, sizeof(tstats));
1559+
qed_memcpy_from(p_hwfn, p_ptt, &tstats,
1560+
p_hwfn->storm_stats.tstats.address,
1561+
p_hwfn->storm_stats.tstats.len);
1562+
1563+
memset(&port_stats, 0, sizeof(port_stats));
1564+
1565+
if (p_hwfn->mcp_info)
1566+
qed_memcpy_from(p_hwfn, p_ptt, &port_stats,
1567+
p_hwfn->mcp_info->port_addr +
1568+
offsetof(struct public_port, stats),
1569+
sizeof(port_stats));
1570+
qed_ptt_release(p_hwfn, p_ptt);
1571+
1572+
stats->no_buff_discards +=
1573+
HILO_64_REGPAIR(mstats.no_buff_discard);
1574+
stats->packet_too_big_discard +=
1575+
HILO_64_REGPAIR(mstats.packet_too_big_discard);
1576+
stats->ttl0_discard +=
1577+
HILO_64_REGPAIR(mstats.ttl0_discard);
1578+
stats->tpa_coalesced_pkts +=
1579+
HILO_64_REGPAIR(mstats.tpa_coalesced_pkts);
1580+
stats->tpa_coalesced_events +=
1581+
HILO_64_REGPAIR(mstats.tpa_coalesced_events);
1582+
stats->tpa_aborts_num +=
1583+
HILO_64_REGPAIR(mstats.tpa_aborts_num);
1584+
stats->tpa_coalesced_bytes +=
1585+
HILO_64_REGPAIR(mstats.tpa_coalesced_bytes);
1586+
1587+
stats->rx_ucast_bytes +=
1588+
HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
1589+
stats->rx_mcast_bytes +=
1590+
HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
1591+
stats->rx_bcast_bytes +=
1592+
HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
1593+
stats->rx_ucast_pkts +=
1594+
HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
1595+
stats->rx_mcast_pkts +=
1596+
HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
1597+
stats->rx_bcast_pkts +=
1598+
HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
1599+
1600+
stats->mftag_filter_discards +=
1601+
HILO_64_REGPAIR(tstats.mftag_filter_discard);
1602+
stats->mac_filter_discards +=
1603+
HILO_64_REGPAIR(tstats.eth_mac_filter_discard);
1604+
1605+
stats->tx_ucast_bytes +=
1606+
HILO_64_REGPAIR(pstats.sent_ucast_bytes);
1607+
stats->tx_mcast_bytes +=
1608+
HILO_64_REGPAIR(pstats.sent_mcast_bytes);
1609+
stats->tx_bcast_bytes +=
1610+
HILO_64_REGPAIR(pstats.sent_bcast_bytes);
1611+
stats->tx_ucast_pkts +=
1612+
HILO_64_REGPAIR(pstats.sent_ucast_pkts);
1613+
stats->tx_mcast_pkts +=
1614+
HILO_64_REGPAIR(pstats.sent_mcast_pkts);
1615+
stats->tx_bcast_pkts +=
1616+
HILO_64_REGPAIR(pstats.sent_bcast_pkts);
1617+
stats->tx_err_drop_pkts +=
1618+
HILO_64_REGPAIR(pstats.error_drop_pkts);
1619+
stats->rx_64_byte_packets += port_stats.pmm.r64;
1620+
stats->rx_127_byte_packets += port_stats.pmm.r127;
1621+
stats->rx_255_byte_packets += port_stats.pmm.r255;
1622+
stats->rx_511_byte_packets += port_stats.pmm.r511;
1623+
stats->rx_1023_byte_packets += port_stats.pmm.r1023;
1624+
stats->rx_1518_byte_packets += port_stats.pmm.r1518;
1625+
stats->rx_1522_byte_packets += port_stats.pmm.r1522;
1626+
stats->rx_2047_byte_packets += port_stats.pmm.r2047;
1627+
stats->rx_4095_byte_packets += port_stats.pmm.r4095;
1628+
stats->rx_9216_byte_packets += port_stats.pmm.r9216;
1629+
stats->rx_16383_byte_packets += port_stats.pmm.r16383;
1630+
stats->rx_crc_errors += port_stats.pmm.rfcs;
1631+
stats->rx_mac_crtl_frames += port_stats.pmm.rxcf;
1632+
stats->rx_pause_frames += port_stats.pmm.rxpf;
1633+
stats->rx_pfc_frames += port_stats.pmm.rxpp;
1634+
stats->rx_align_errors += port_stats.pmm.raln;
1635+
stats->rx_carrier_errors += port_stats.pmm.rfcr;
1636+
stats->rx_oversize_packets += port_stats.pmm.rovr;
1637+
stats->rx_jabbers += port_stats.pmm.rjbr;
1638+
stats->rx_undersize_packets += port_stats.pmm.rund;
1639+
stats->rx_fragments += port_stats.pmm.rfrg;
1640+
stats->tx_64_byte_packets += port_stats.pmm.t64;
1641+
stats->tx_65_to_127_byte_packets += port_stats.pmm.t127;
1642+
stats->tx_128_to_255_byte_packets += port_stats.pmm.t255;
1643+
stats->tx_256_to_511_byte_packets += port_stats.pmm.t511;
1644+
stats->tx_512_to_1023_byte_packets += port_stats.pmm.t1023;
1645+
stats->tx_1024_to_1518_byte_packets += port_stats.pmm.t1518;
1646+
stats->tx_1519_to_2047_byte_packets += port_stats.pmm.t2047;
1647+
stats->tx_2048_to_4095_byte_packets += port_stats.pmm.t4095;
1648+
stats->tx_4096_to_9216_byte_packets += port_stats.pmm.t9216;
1649+
stats->tx_9217_to_16383_byte_packets += port_stats.pmm.t16383;
1650+
stats->tx_pause_frames += port_stats.pmm.txpf;
1651+
stats->tx_pfc_frames += port_stats.pmm.txpp;
1652+
stats->tx_lpi_entry_count += port_stats.pmm.tlpiec;
1653+
stats->tx_total_collisions += port_stats.pmm.tncl;
1654+
stats->rx_mac_bytes += port_stats.pmm.rbyte;
1655+
stats->rx_mac_uc_packets += port_stats.pmm.rxuca;
1656+
stats->rx_mac_mc_packets += port_stats.pmm.rxmca;
1657+
stats->rx_mac_bc_packets += port_stats.pmm.rxbca;
1658+
stats->rx_mac_frames_ok += port_stats.pmm.rxpok;
1659+
stats->tx_mac_bytes += port_stats.pmm.tbyte;
1660+
stats->tx_mac_uc_packets += port_stats.pmm.txuca;
1661+
stats->tx_mac_mc_packets += port_stats.pmm.txmca;
1662+
stats->tx_mac_bc_packets += port_stats.pmm.txbca;
1663+
stats->tx_mac_ctrl_frames += port_stats.pmm.txcf;
1664+
1665+
for (j = 0; j < 8; j++) {
1666+
stats->brb_truncates += port_stats.brb.brb_truncate[j];
1667+
stats->brb_discards += port_stats.brb.brb_discard[j];
1668+
}
1669+
}
1670+
}
1671+
1672+
void qed_get_vport_stats(struct qed_dev *cdev,
1673+
struct qed_eth_stats *stats)
1674+
{
1675+
u32 i;
1676+
1677+
if (!cdev) {
1678+
memset(stats, 0, sizeof(*stats));
1679+
return;
1680+
}
1681+
1682+
__qed_get_vport_stats(cdev, stats);
1683+
1684+
if (!cdev->reset_stats)
1685+
return;
1686+
1687+
/* Reduce the statistics baseline */
1688+
for (i = 0; i < sizeof(struct qed_eth_stats) / sizeof(u64); i++)
1689+
((u64 *)stats)[i] -= ((u64 *)cdev->reset_stats)[i];
1690+
}
1691+
1692+
/* zeroes V-PORT specific portion of stats (Port stats remains untouched) */
1693+
void qed_reset_vport_stats(struct qed_dev *cdev)
1694+
{
1695+
int i;
1696+
1697+
for_each_hwfn(cdev, i) {
1698+
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
1699+
struct eth_mstorm_per_queue_stat mstats;
1700+
struct eth_ustorm_per_queue_stat ustats;
1701+
struct eth_pstorm_per_queue_stat pstats;
1702+
struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
1703+
1704+
if (!p_ptt) {
1705+
DP_ERR(p_hwfn, "Failed to acquire ptt\n");
1706+
continue;
1707+
}
1708+
1709+
memset(&mstats, 0, sizeof(mstats));
1710+
qed_memcpy_to(p_hwfn, p_ptt,
1711+
p_hwfn->storm_stats.mstats.address,
1712+
&mstats,
1713+
p_hwfn->storm_stats.mstats.len);
1714+
1715+
memset(&ustats, 0, sizeof(ustats));
1716+
qed_memcpy_to(p_hwfn, p_ptt,
1717+
p_hwfn->storm_stats.ustats.address,
1718+
&ustats,
1719+
p_hwfn->storm_stats.ustats.len);
1720+
1721+
memset(&pstats, 0, sizeof(pstats));
1722+
qed_memcpy_to(p_hwfn, p_ptt,
1723+
p_hwfn->storm_stats.pstats.address,
1724+
&pstats,
1725+
p_hwfn->storm_stats.pstats.len);
1726+
1727+
qed_ptt_release(p_hwfn, p_ptt);
1728+
}
1729+
1730+
/* PORT statistics are not necessarily reset, so we need to
1731+
* read and create a baseline for future statistics.
1732+
*/
1733+
if (!cdev->reset_stats)
1734+
DP_INFO(cdev, "Reset stats not allocated\n");
1735+
else
1736+
__qed_get_vport_stats(cdev, cdev->reset_stats);
1737+
}
1738+
14971739
int qed_fw_l2_queue(struct qed_hwfn *p_hwfn,
14981740
u16 src_id, u16 *dst_id)
14991741
{

drivers/net/ethernet/qlogic/qed/qed_dev_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn);
156156
*/
157157
void qed_ptt_release(struct qed_hwfn *p_hwfn,
158158
struct qed_ptt *p_ptt);
159+
void qed_get_vport_stats(struct qed_dev *cdev,
160+
struct qed_eth_stats *stats);
161+
void qed_reset_vport_stats(struct qed_dev *cdev);
159162

160163
enum qed_dmae_address_type_t {
161164
QED_DMAE_ADDRESS_HOST_VIRT,

drivers/net/ethernet/qlogic/qed/qed_hsi.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,36 @@ struct core_conn_context {
355355
struct regpair ustorm_st_padding[2] /* padding */;
356356
};
357357

358+
struct eth_mstorm_per_queue_stat {
359+
struct regpair ttl0_discard;
360+
struct regpair packet_too_big_discard;
361+
struct regpair no_buff_discard;
362+
struct regpair not_active_discard;
363+
struct regpair tpa_coalesced_pkts;
364+
struct regpair tpa_coalesced_events;
365+
struct regpair tpa_aborts_num;
366+
struct regpair tpa_coalesced_bytes;
367+
};
368+
369+
struct eth_pstorm_per_queue_stat {
370+
struct regpair sent_ucast_bytes;
371+
struct regpair sent_mcast_bytes;
372+
struct regpair sent_bcast_bytes;
373+
struct regpair sent_ucast_pkts;
374+
struct regpair sent_mcast_pkts;
375+
struct regpair sent_bcast_pkts;
376+
struct regpair error_drop_pkts;
377+
};
378+
379+
struct eth_ustorm_per_queue_stat {
380+
struct regpair rcv_ucast_bytes;
381+
struct regpair rcv_mcast_bytes;
382+
struct regpair rcv_bcast_bytes;
383+
struct regpair rcv_ucast_pkts;
384+
struct regpair rcv_mcast_pkts;
385+
struct regpair rcv_bcast_pkts;
386+
};
387+
358388
/* Event Ring Next Page Address */
359389
struct event_ring_next_addr {
360390
struct regpair addr /* Next Page Address */;

drivers/net/ethernet/qlogic/qed/qed_l2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,8 @@ static int qed_start_vport(struct qed_dev *cdev,
12981298
vport_id, mtu);
12991299
}
13001300

1301+
qed_reset_vport_stats(cdev);
1302+
13011303
return 0;
13021304
}
13031305

@@ -1680,6 +1682,7 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
16801682
.filter_config = &qed_configure_filter,
16811683
.fastpath_stop = &qed_fastpath_stop,
16821684
.eth_cqe_completion = &qed_fp_cqe_completion,
1685+
.get_vport_stats = &qed_get_vport_stats,
16831686
};
16841687

16851688
const struct qed_eth_ops *qed_get_eth_ops(u32 version)

include/linux/qed/qed_eth_if.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ struct qed_eth_ops {
154154
int (*eth_cqe_completion)(struct qed_dev *cdev,
155155
u8 rss_id,
156156
struct eth_slow_path_rx_cqe *cqe);
157+
158+
void (*get_vport_stats)(struct qed_dev *cdev,
159+
struct qed_eth_stats *stats);
157160
};
158161

159162
const struct qed_eth_ops *qed_get_eth_ops(u32 version);

0 commit comments

Comments
 (0)