Merge branch 'cxgb4-next'
authorDavid S. Miller <davem@davemloft.net>
Thu, 4 Jun 2015 06:40:20 +0000 (23:40 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 4 Jun 2015 06:40:20 +0000 (23:40 -0700)
Hariprasad Shenai says:

====================
cxgb4: Adds support for various ethtool stats

This patch series adds the following:
Adds support to dump adapter specific stats in ethtool
Adds support to dump channel stats in ethtool
Adds support to dump loopback port stats in ethtool
Remove wake-on-lan get/set ethtool support

This patch series has been created against net-next tree and includes
patches on cxgb4 driver.

We have included all the maintainers of respective drivers. Kindly review
the change and let us know in case of any review comments.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/infiniband/hw/cxgb4/provider.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h

index 66bd6a2ad83b04f34e2b5fbb822e0b8ff062359b..d95a0c300b03390ef99443be108cb0bf1372fc40 100644 (file)
@@ -445,10 +445,10 @@ static int c4iw_get_mib(struct ib_device *ibdev,
 
        cxgb4_get_tcp_stats(c4iw_dev->rdev.lldi.pdev, &v4, &v6);
        memset(stats, 0, sizeof *stats);
-       stats->iw.tcpInSegs = v4.tcpInSegs + v6.tcpInSegs;
-       stats->iw.tcpOutSegs = v4.tcpOutSegs + v6.tcpOutSegs;
-       stats->iw.tcpRetransSegs = v4.tcpRetransSegs + v6.tcpRetransSegs;
-       stats->iw.tcpOutRsts = v4.tcpOutRsts + v6.tcpOutSegs;
+       stats->iw.tcpInSegs = v4.tcp_in_segs + v6.tcp_in_segs;
+       stats->iw.tcpOutSegs = v4.tcp_out_segs + v6.tcp_out_segs;
+       stats->iw.tcpRetransSegs = v4.tcp_retrans_segs + v6.tcp_retrans_segs;
+       stats->iw.tcpOutRsts = v4.tcp_out_rsts + v6.tcp_out_rsts;
 
        return 0;
 }
index 4d3a8c20eb1262f5fe4a915325684140322498fd..bf2b822d0e8ebb9f89a678ac8313fd210b99eedf 100644 (file)
@@ -198,23 +198,45 @@ struct lb_port_stats {
 };
 
 struct tp_tcp_stats {
-       u32 tcpOutRsts;
-       u64 tcpInSegs;
-       u64 tcpOutSegs;
-       u64 tcpRetransSegs;
+       u32 tcp_out_rsts;
+       u64 tcp_in_segs;
+       u64 tcp_out_segs;
+       u64 tcp_retrans_segs;
+};
+
+struct tp_usm_stats {
+       u32 frames;
+       u32 drops;
+       u64 octets;
+};
+
+struct tp_fcoe_stats {
+       u32 frames_ddp;
+       u32 frames_drop;
+       u64 octets_ddp;
 };
 
 struct tp_err_stats {
-       u32 macInErrs[4];
-       u32 hdrInErrs[4];
-       u32 tcpInErrs[4];
-       u32 tnlCongDrops[4];
-       u32 ofldChanDrops[4];
-       u32 tnlTxDrops[4];
-       u32 ofldVlanDrops[4];
-       u32 tcp6InErrs[4];
-       u32 ofldNoNeigh;
-       u32 ofldCongDefer;
+       u32 mac_in_errs[4];
+       u32 hdr_in_errs[4];
+       u32 tcp_in_errs[4];
+       u32 tnl_cong_drops[4];
+       u32 ofld_chan_drops[4];
+       u32 tnl_tx_drops[4];
+       u32 ofld_vlan_drops[4];
+       u32 tcp6_in_errs[4];
+       u32 ofld_no_neigh;
+       u32 ofld_cong_defer;
+};
+
+struct tp_cpl_stats {
+       u32 req[4];
+       u32 rsp[4];
+};
+
+struct tp_rdma_stats {
+       u32 rqe_dfr_pkt;
+       u32 rqe_dfr_mod;
 };
 
 struct sge_params {
@@ -446,6 +468,7 @@ struct port_info {
        u8     rss_mode;
        struct link_config link_cfg;
        u16   *rss;
+       struct port_stats stats_base;
 #ifdef CONFIG_CHELSIO_T4_DCB
        struct port_dcb_info dcb;     /* Data Center Bridging support */
 #endif
@@ -686,6 +709,12 @@ struct l2t_data;
 
 #endif
 
+struct doorbell_stats {
+       u32 db_drop;
+       u32 db_empty;
+       u32 db_full;
+};
+
 struct adapter {
        void __iomem *regs;
        void __iomem *bar2;
@@ -703,13 +732,12 @@ struct adapter {
        struct cxgb4_virt_res vres;
        unsigned int swintr;
 
-       unsigned int wol;
-
        struct {
                unsigned short vec;
                char desc[IFNAMSIZ + 10];
        } msix_info[MAX_INGQ + 1];
 
+       struct doorbell_stats db_stats;
        struct sge sge;
 
        struct net_device *port[MAX_NPORTS];
@@ -864,6 +892,11 @@ enum {
        VLAN_REWRITE
 };
 
+static inline int is_offload(const struct adapter *adap)
+{
+       return adap->params.offload;
+}
+
 static inline int is_t6(enum chip_type chip)
 {
        return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T6;
@@ -1287,13 +1320,23 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr);
 void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres);
 const char *t4_get_port_type_description(enum fw_port_type port_type);
 void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
+void t4_get_port_stats_offset(struct adapter *adap, int idx,
+                             struct port_stats *stats,
+                             struct port_stats *offset);
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
 void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
 void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN]);
 void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
                            unsigned int mask, unsigned int val);
 void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr);
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
+void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st);
+void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st);
+void t4_get_usm_stats(struct adapter *adap, struct tp_usm_stats *st);
 void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
                         struct tp_tcp_stats *v6);
+void t4_get_fcoe_stats(struct adapter *adap, unsigned int idx,
+                      struct tp_fcoe_stats *st);
 void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
                  const unsigned short *alpha, const unsigned short *beta);
 
index 13d5101a0d9f648ce914bf2cb14b0b85a0d43f2d..0194c91a04862a96c5eacd7571ccd29a276b74f7 100644 (file)
@@ -108,15 +108,82 @@ static const char stats_strings[][ETH_GSTRING_LEN] = {
        "VLANinsertions     ",
        "GROpackets         ",
        "GROmerged          ",
-       "WriteCoalSuccess   ",
-       "WriteCoalFail      ",
+};
+
+static char adapter_stats_strings[][ETH_GSTRING_LEN] = {
+       "db_drop                ",
+       "db_full                ",
+       "db_empty               ",
+       "tcp_ipv4_out_rsts      ",
+       "tcp_ipv4_in_segs       ",
+       "tcp_ipv4_out_segs      ",
+       "tcp_ipv4_retrans_segs  ",
+       "tcp_ipv6_out_rsts      ",
+       "tcp_ipv6_in_segs       ",
+       "tcp_ipv6_out_segs      ",
+       "tcp_ipv6_retrans_segs  ",
+       "usm_ddp_frames         ",
+       "usm_ddp_octets         ",
+       "usm_ddp_drops          ",
+       "rdma_no_rqe_mod_defer  ",
+       "rdma_no_rqe_pkt_defer  ",
+       "tp_err_ofld_no_neigh   ",
+       "tp_err_ofld_cong_defer ",
+       "write_coal_success     ",
+       "write_coal_fail        ",
+};
+
+static char channel_stats_strings[][ETH_GSTRING_LEN] = {
+       "--------Channel--------- ",
+       "tp_cpl_requests        ",
+       "tp_cpl_responses       ",
+       "tp_mac_in_errs         ",
+       "tp_hdr_in_errs         ",
+       "tp_tcp_in_errs         ",
+       "tp_tcp6_in_errs        ",
+       "tp_tnl_cong_drops      ",
+       "tp_tnl_tx_drops        ",
+       "tp_ofld_vlan_drops     ",
+       "tp_ofld_chan_drops     ",
+       "fcoe_octets_ddp        ",
+       "fcoe_frames_ddp        ",
+       "fcoe_frames_drop       ",
+};
+
+static char loopback_stats_strings[][ETH_GSTRING_LEN] = {
+       "-------Loopback----------- ",
+       "octets_ok              ",
+       "frames_ok              ",
+       "bcast_frames           ",
+       "mcast_frames           ",
+       "ucast_frames           ",
+       "error_frames           ",
+       "frames_64              ",
+       "frames_65_to_127       ",
+       "frames_128_to_255      ",
+       "frames_256_to_511      ",
+       "frames_512_to_1023     ",
+       "frames_1024_to_1518    ",
+       "frames_1519_to_max     ",
+       "frames_dropped         ",
+       "bg0_frames_dropped     ",
+       "bg1_frames_dropped     ",
+       "bg2_frames_dropped     ",
+       "bg3_frames_dropped     ",
+       "bg0_frames_trunc       ",
+       "bg1_frames_trunc       ",
+       "bg2_frames_trunc       ",
+       "bg3_frames_trunc       ",
 };
 
 static int get_sset_count(struct net_device *dev, int sset)
 {
        switch (sset) {
        case ETH_SS_STATS:
-               return ARRAY_SIZE(stats_strings);
+               return ARRAY_SIZE(stats_strings) +
+                      ARRAY_SIZE(adapter_stats_strings) +
+                      ARRAY_SIZE(channel_stats_strings) +
+                      ARRAY_SIZE(loopback_stats_strings);
        default:
                return -EOPNOTSUPP;
        }
@@ -168,8 +235,18 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 
 static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
 {
-       if (stringset == ETH_SS_STATS)
+       if (stringset == ETH_SS_STATS) {
                memcpy(data, stats_strings, sizeof(stats_strings));
+               data += sizeof(stats_strings);
+               memcpy(data, adapter_stats_strings,
+                      sizeof(adapter_stats_strings));
+               data += sizeof(adapter_stats_strings);
+               memcpy(data, channel_stats_strings,
+                      sizeof(channel_stats_strings));
+               data += sizeof(channel_stats_strings);
+               memcpy(data, loopback_stats_strings,
+                      sizeof(loopback_stats_strings));
+       }
 }
 
 /* port stats maintained per queue of the port. They should be in the same
@@ -185,6 +262,45 @@ struct queue_port_stats {
        u64 gro_merged;
 };
 
+struct adapter_stats {
+       u64 db_drop;
+       u64 db_full;
+       u64 db_empty;
+       u64 tcp_v4_out_rsts;
+       u64 tcp_v4_in_segs;
+       u64 tcp_v4_out_segs;
+       u64 tcp_v4_retrans_segs;
+       u64 tcp_v6_out_rsts;
+       u64 tcp_v6_in_segs;
+       u64 tcp_v6_out_segs;
+       u64 tcp_v6_retrans_segs;
+       u64 frames;
+       u64 octets;
+       u64 drops;
+       u64 rqe_dfr_mod;
+       u64 rqe_dfr_pkt;
+       u64 ofld_no_neigh;
+       u64 ofld_cong_defer;
+       u64 wc_success;
+       u64 wc_fail;
+};
+
+struct channel_stats {
+       u64 cpl_req;
+       u64 cpl_rsp;
+       u64 mac_in_errs;
+       u64 hdr_in_errs;
+       u64 tcp_in_errs;
+       u64 tcp6_in_errs;
+       u64 tnl_cong_drops;
+       u64 tnl_tx_drops;
+       u64 ofld_vlan_drops;
+       u64 ofld_chan_drops;
+       u64 octets_ddp;
+       u64 frames_ddp;
+       u64 frames_drop;
+};
+
 static void collect_sge_port_stats(const struct adapter *adap,
                                   const struct port_info *p,
                                   struct queue_port_stats *s)
@@ -205,30 +321,121 @@ static void collect_sge_port_stats(const struct adapter *adap,
        }
 }
 
+static void collect_adapter_stats(struct adapter *adap, struct adapter_stats *s)
+{
+       struct tp_tcp_stats v4, v6;
+       struct tp_rdma_stats rdma_stats;
+       struct tp_err_stats err_stats;
+       struct tp_usm_stats usm_stats;
+       u64 val1, val2;
+
+       memset(s, 0, sizeof(*s));
+
+       spin_lock(&adap->stats_lock);
+       t4_tp_get_tcp_stats(adap, &v4, &v6);
+       t4_tp_get_rdma_stats(adap, &rdma_stats);
+       t4_get_usm_stats(adap, &usm_stats);
+       t4_tp_get_err_stats(adap, &err_stats);
+       spin_unlock(&adap->stats_lock);
+
+       s->db_drop = adap->db_stats.db_drop;
+       s->db_full = adap->db_stats.db_full;
+       s->db_empty = adap->db_stats.db_empty;
+
+       s->tcp_v4_out_rsts = v4.tcp_out_rsts;
+       s->tcp_v4_in_segs = v4.tcp_in_segs;
+       s->tcp_v4_out_segs = v4.tcp_out_segs;
+       s->tcp_v4_retrans_segs = v4.tcp_retrans_segs;
+       s->tcp_v6_out_rsts = v6.tcp_out_rsts;
+       s->tcp_v6_in_segs = v6.tcp_in_segs;
+       s->tcp_v6_out_segs = v6.tcp_out_segs;
+       s->tcp_v6_retrans_segs = v6.tcp_retrans_segs;
+
+       if (is_offload(adap)) {
+               s->frames = usm_stats.frames;
+               s->octets = usm_stats.octets;
+               s->drops = usm_stats.drops;
+               s->rqe_dfr_mod = rdma_stats.rqe_dfr_mod;
+               s->rqe_dfr_pkt = rdma_stats.rqe_dfr_pkt;
+       }
+
+       s->ofld_no_neigh = err_stats.ofld_no_neigh;
+       s->ofld_cong_defer = err_stats.ofld_cong_defer;
+
+       if (!is_t4(adap->params.chip)) {
+               int v;
+
+               v = t4_read_reg(adap, SGE_STAT_CFG_A);
+               if (STATSOURCE_T5_G(v) == 7) {
+                       val2 = t4_read_reg(adap, SGE_STAT_MATCH_A);
+                       val1 = t4_read_reg(adap, SGE_STAT_TOTAL_A);
+                       s->wc_success = val1 - val2;
+                       s->wc_fail = val2;
+               }
+       }
+}
+
+static void collect_channel_stats(struct adapter *adap, struct channel_stats *s,
+                                 u8 i)
+{
+       struct tp_cpl_stats cpl_stats;
+       struct tp_err_stats err_stats;
+       struct tp_fcoe_stats fcoe_stats;
+
+       memset(s, 0, sizeof(*s));
+
+       spin_lock(&adap->stats_lock);
+       t4_tp_get_cpl_stats(adap, &cpl_stats);
+       t4_tp_get_err_stats(adap, &err_stats);
+       t4_get_fcoe_stats(adap, i, &fcoe_stats);
+       spin_unlock(&adap->stats_lock);
+
+       s->cpl_req = cpl_stats.req[i];
+       s->cpl_rsp = cpl_stats.rsp[i];
+       s->mac_in_errs = err_stats.mac_in_errs[i];
+       s->hdr_in_errs = err_stats.hdr_in_errs[i];
+       s->tcp_in_errs = err_stats.tcp_in_errs[i];
+       s->tcp6_in_errs = err_stats.tcp6_in_errs[i];
+       s->tnl_cong_drops = err_stats.tnl_cong_drops[i];
+       s->tnl_tx_drops = err_stats.tnl_tx_drops[i];
+       s->ofld_vlan_drops = err_stats.ofld_vlan_drops[i];
+       s->ofld_chan_drops = err_stats.ofld_chan_drops[i];
+       s->octets_ddp = fcoe_stats.octets_ddp;
+       s->frames_ddp = fcoe_stats.frames_ddp;
+       s->frames_drop = fcoe_stats.frames_drop;
+}
+
 static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
                      u64 *data)
 {
        struct port_info *pi = netdev_priv(dev);
        struct adapter *adapter = pi->adapter;
-       u32 val1, val2;
+       struct lb_port_stats s;
+       int i;
+       u64 *p0;
 
-       t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data);
+       t4_get_port_stats_offset(adapter, pi->tx_chan,
+                                (struct port_stats *)data,
+                                &pi->stats_base);
 
        data += sizeof(struct port_stats) / sizeof(u64);
        collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
        data += sizeof(struct queue_port_stats) / sizeof(u64);
-       if (!is_t4(adapter->params.chip)) {
-               t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7));
-               val1 = t4_read_reg(adapter, SGE_STAT_TOTAL_A);
-               val2 = t4_read_reg(adapter, SGE_STAT_MATCH_A);
-               *data = val1 - val2;
-               data++;
-               *data = val2;
-               data++;
-       } else {
-               memset(data, 0, 2 * sizeof(u64));
-               *data += 2;
-       }
+       collect_adapter_stats(adapter, (struct adapter_stats *)data);
+       data += sizeof(struct adapter_stats) / sizeof(u64);
+
+       *data++ = (u64)pi->port_id;
+       collect_channel_stats(adapter, (struct channel_stats *)data,
+                             pi->port_id);
+       data += sizeof(struct channel_stats) / sizeof(u64);
+
+       *data++ = (u64)pi->port_id;
+       memset(&s, 0, sizeof(s));
+       t4_get_lb_stats(adapter, pi->port_id, &s);
+
+       p0 = &s.octets;
+       for (i = 0; i < ARRAY_SIZE(loopback_stats_strings) - 1; i++)
+               *data++ = (unsigned long long)*p0++;
 }
 
 static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -740,37 +947,6 @@ static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
        return ret;
 }
 
-#define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC)
-#define BCAST_CRC 0xa0ccc1a6
-
-static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-       wol->supported = WAKE_BCAST | WAKE_MAGIC;
-       wol->wolopts = netdev2adap(dev)->wol;
-       memset(&wol->sopass, 0, sizeof(wol->sopass));
-}
-
-static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-       int err = 0;
-       struct port_info *pi = netdev_priv(dev);
-
-       if (wol->wolopts & ~WOL_SUPPORTED)
-               return -EINVAL;
-       t4_wol_magic_enable(pi->adapter, pi->tx_chan,
-                           (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL);
-       if (wol->wolopts & WAKE_BCAST) {
-               err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL,
-                                       ~0ULL, 0, false);
-               if (!err)
-                       err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1,
-                                               ~6ULL, ~0ULL, BCAST_CRC, true);
-       } else {
-               t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false);
-       }
-       return err;
-}
-
 static u32 get_rss_table_size(struct net_device *dev)
 {
        const struct port_info *pi = netdev_priv(dev);
@@ -900,8 +1076,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
        .get_ethtool_stats = get_stats,
        .get_regs_len      = get_regs_len,
        .get_regs          = get_regs,
-       .get_wol           = get_wol,
-       .set_wol           = set_wol,
        .get_rxnfc         = get_rxnfc,
        .get_rxfh_indir_size = get_rss_table_size,
        .get_rxfh          = get_rss_table,
index a589591e5b637a11b7f0fd0d563af024a07f5f9c..3057154840042e391e5d9b2c1ef123e6aa353408 100644 (file)
@@ -1353,11 +1353,6 @@ static u16 cxgb_select_queue(struct net_device *dev, struct sk_buff *skb,
        return fallback(dev, skb) % dev->real_num_tx_queues;
 }
 
-static inline int is_offload(const struct adapter *adap)
-{
-       return adap->params.offload;
-}
-
 static int closest_timer(const struct sge *s, int time)
 {
        int i, delta, match = 0, min_delta = INT_MAX;
@@ -2889,7 +2884,8 @@ static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev,
                spin_unlock(&adapter->stats_lock);
                return ns;
        }
-       t4_get_port_stats(adapter, p->tx_chan, &stats);
+       t4_get_port_stats_offset(adapter, p->tx_chan, &stats,
+                                &p->stats_base);
        spin_unlock(&adapter->stats_lock);
 
        ns->tx_bytes   = stats.tx_octets;
@@ -4680,6 +4676,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        err = -ENOMEM;
                        goto out_free_adapter;
                }
+               t4_write_reg(adapter, SGE_STAT_CFG_A,
+                            STATSOURCE_T5_V(7) | STATMODE_V(0));
        }
 
        setup_memwin(adapter);
index 35a44db29347d277e494099bfa557bfd6477369f..c21ab2686a690380b34f859be35a19194a6723c1 100644 (file)
@@ -3760,24 +3760,148 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
        if (v4) {
                t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val,
                                 ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST_A);
-               v4->tcpOutRsts = STAT(OUT_RST);
-               v4->tcpInSegs  = STAT64(IN_SEG);
-               v4->tcpOutSegs = STAT64(OUT_SEG);
-               v4->tcpRetransSegs = STAT64(RXT_SEG);
+               v4->tcp_out_rsts = STAT(OUT_RST);
+               v4->tcp_in_segs  = STAT64(IN_SEG);
+               v4->tcp_out_segs = STAT64(OUT_SEG);
+               v4->tcp_retrans_segs = STAT64(RXT_SEG);
        }
        if (v6) {
                t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val,
                                 ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST_A);
-               v6->tcpOutRsts = STAT(OUT_RST);
-               v6->tcpInSegs  = STAT64(IN_SEG);
-               v6->tcpOutSegs = STAT64(OUT_SEG);
-               v6->tcpRetransSegs = STAT64(RXT_SEG);
+               v6->tcp_out_rsts = STAT(OUT_RST);
+               v6->tcp_in_segs  = STAT64(IN_SEG);
+               v6->tcp_out_segs = STAT64(OUT_SEG);
+               v6->tcp_retrans_segs = STAT64(RXT_SEG);
        }
 #undef STAT64
 #undef STAT
 #undef STAT_IDX
 }
 
+/**
+ *     t4_tp_get_err_stats - read TP's error MIB counters
+ *     @adap: the adapter
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's error counters.
+ */
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
+{
+       /* T6 and later has 2 channels */
+       if (adap->params.arch.nchan == NCHAN) {
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->mac_in_errs, 12, TP_MIB_MAC_IN_ERR_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tnl_cong_drops, 8,
+                                TP_MIB_TNL_CNG_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tnl_tx_drops, 4,
+                                TP_MIB_TNL_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->ofld_vlan_drops, 4,
+                                TP_MIB_OFD_VLN_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tcp6_in_errs, 4,
+                                TP_MIB_TCP_V6IN_ERR_0_A);
+       } else {
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->mac_in_errs, 2, TP_MIB_MAC_IN_ERR_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->hdr_in_errs, 2, TP_MIB_HDR_IN_ERR_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tcp_in_errs, 2, TP_MIB_TCP_IN_ERR_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tnl_cong_drops, 2,
+                                TP_MIB_TNL_CNG_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->ofld_chan_drops, 2,
+                                TP_MIB_OFD_CHN_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tnl_tx_drops, 2, TP_MIB_TNL_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->ofld_vlan_drops, 2,
+                                TP_MIB_OFD_VLN_DROP_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                                st->tcp6_in_errs, 2, TP_MIB_TCP_V6IN_ERR_0_A);
+       }
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+                        &st->ofld_no_neigh, 2, TP_MIB_OFD_ARP_DROP_A);
+}
+
+/**
+ *     t4_tp_get_cpl_stats - read TP's CPL MIB counters
+ *     @adap: the adapter
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's CPL counters.
+ */
+void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st)
+{
+       /* T6 and later has 2 channels */
+       if (adap->params.arch.nchan == NCHAN) {
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, st->req,
+                                8, TP_MIB_CPL_IN_REQ_0_A);
+       } else {
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, st->req,
+                                2, TP_MIB_CPL_IN_REQ_0_A);
+               t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, st->rsp,
+                                2, TP_MIB_CPL_OUT_RSP_0_A);
+       }
+}
+
+/**
+ *     t4_tp_get_rdma_stats - read TP's RDMA MIB counters
+ *     @adap: the adapter
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's RDMA counters.
+ */
+void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st)
+{
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, &st->rqe_dfr_pkt,
+                        2, TP_MIB_RQE_DFR_PKT_A);
+}
+
+/**
+ *     t4_get_fcoe_stats - read TP's FCoE MIB counters for a port
+ *     @adap: the adapter
+ *     @idx: the port index
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's FCoE counters for the selected port.
+ */
+void t4_get_fcoe_stats(struct adapter *adap, unsigned int idx,
+                      struct tp_fcoe_stats *st)
+{
+       u32 val[2];
+
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, &st->frames_ddp,
+                        1, TP_MIB_FCOE_DDP_0_A + idx);
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, &st->frames_drop,
+                        1, TP_MIB_FCOE_DROP_0_A + idx);
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val,
+                        2, TP_MIB_FCOE_BYTE_0_HI_A + 2 * idx);
+       st->octets_ddp = ((u64)val[0] << 32) | val[1];
+}
+
+/**
+ *     t4_get_usm_stats - read TP's non-TCP DDP MIB counters
+ *     @adap: the adapter
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's counters for non-TCP directly-placed packets.
+ */
+void t4_get_usm_stats(struct adapter *adap, struct tp_usm_stats *st)
+{
+       u32 val[4];
+
+       t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val, 4,
+                        TP_MIB_USM_PKTS_A);
+       st->frames = val[0];
+       st->drops = val[1];
+       st->octets = ((u64)val[2] << 32) | val[3];
+}
+
 /**
  *     t4_read_mtu_tbl - returns the values in the HW path MTU table
  *     @adap: the adapter
@@ -4034,6 +4158,28 @@ const char *t4_get_port_type_description(enum fw_port_type port_type)
        return "UNKNOWN";
 }
 
+/**
+ *      t4_get_port_stats_offset - collect port stats relative to a previous
+ *                                 snapshot
+ *      @adap: The adapter
+ *      @idx: The port
+ *      @stats: Current stats to fill
+ *      @offset: Previous stats snapshot
+ */
+void t4_get_port_stats_offset(struct adapter *adap, int idx,
+                             struct port_stats *stats,
+                             struct port_stats *offset)
+{
+       u64 *s, *o;
+       int i;
+
+       t4_get_port_stats(adap, idx, stats);
+       for (i = 0, s = (u64 *)stats, o = (u64 *)offset;
+                       i < (sizeof(struct port_stats) / sizeof(u64));
+                       i++, s++, o++)
+               *s -= *o;
+}
+
 /**
  *     t4_get_port_stats - collect port statistics
  *     @adap: the adapter
@@ -4118,103 +4264,51 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
 }
 
 /**
- *     t4_wol_magic_enable - enable/disable magic packet WoL
- *     @adap: the adapter
- *     @port: the physical port index
- *     @addr: MAC address expected in magic packets, %NULL to disable
- *
- *     Enables/disables magic packet wake-on-LAN for the selected port.
- */
-void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
-                        const u8 *addr)
-{
-       u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg;
-
-       if (is_t4(adap->params.chip)) {
-               mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO);
-               mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI);
-               port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2_A);
-       } else {
-               mag_id_reg_l = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_LO);
-               mag_id_reg_h = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_HI);
-               port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2_A);
-       }
-
-       if (addr) {
-               t4_write_reg(adap, mag_id_reg_l,
-                            (addr[2] << 24) | (addr[3] << 16) |
-                            (addr[4] << 8) | addr[5]);
-               t4_write_reg(adap, mag_id_reg_h,
-                            (addr[0] << 8) | addr[1]);
-       }
-       t4_set_reg_field(adap, port_cfg_reg, MAGICEN_F,
-                        addr ? MAGICEN_F : 0);
-}
-
-/**
- *     t4_wol_pat_enable - enable/disable pattern-based WoL
+ *     t4_get_lb_stats - collect loopback port statistics
  *     @adap: the adapter
- *     @port: the physical port index
- *     @map: bitmap of which HW pattern filters to set
- *     @mask0: byte mask for bytes 0-63 of a packet
- *     @mask1: byte mask for bytes 64-127 of a packet
- *     @crc: Ethernet CRC for selected bytes
- *     @enable: enable/disable switch
+ *     @idx: the loopback port index
+ *     @p: the stats structure to fill
  *
- *     Sets the pattern filters indicated in @map to mask out the bytes
- *     specified in @mask0/@mask1 in received packets and compare the CRC of
- *     the resulting packet against @crc.  If @enable is %true pattern-based
- *     WoL is enabled, otherwise disabled.
+ *     Return HW statistics for the given loopback port.
  */
-int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
-                     u64 mask0, u64 mask1, unsigned int crc, bool enable)
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
 {
-       int i;
-       u32 port_cfg_reg;
-
-       if (is_t4(adap->params.chip))
-               port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2_A);
-       else
-               port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2_A);
-
-       if (!enable) {
-               t4_set_reg_field(adap, port_cfg_reg, PATEN_F, 0);
-               return 0;
-       }
-       if (map > 0xff)
-               return -EINVAL;
+       u32 bgmap = t4_get_mps_bg_map(adap, idx);
 
-#define EPIO_REG(name) \
+#define GET_STAT(name) \
+       t4_read_reg64(adap, \
        (is_t4(adap->params.chip) ? \
-        PORT_REG(port, XGMAC_PORT_EPIO_##name##_A) : \
-        T5_PORT_REG(port, MAC_PORT_EPIO_##name##_A))
+       PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L) : \
+       T5_PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
 
-       t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
-       t4_write_reg(adap, EPIO_REG(DATA2), mask1);
-       t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32);
+       p->octets           = GET_STAT(BYTES);
+       p->frames           = GET_STAT(FRAMES);
+       p->bcast_frames     = GET_STAT(BCAST);
+       p->mcast_frames     = GET_STAT(MCAST);
+       p->ucast_frames     = GET_STAT(UCAST);
+       p->error_frames     = GET_STAT(ERROR);
+
+       p->frames_64        = GET_STAT(64B);
+       p->frames_65_127    = GET_STAT(65B_127B);
+       p->frames_128_255   = GET_STAT(128B_255B);
+       p->frames_256_511   = GET_STAT(256B_511B);
+       p->frames_512_1023  = GET_STAT(512B_1023B);
+       p->frames_1024_1518 = GET_STAT(1024B_1518B);
+       p->frames_1519_max  = GET_STAT(1519B_MAX);
+       p->drop             = GET_STAT(DROP_FRAMES);
+
+       p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
+       p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
+       p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
+       p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
+       p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
+       p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
+       p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
+       p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
 
-       for (i = 0; i < NWOL_PAT; i++, map >>= 1) {
-               if (!(map & 1))
-                       continue;
-
-               /* write byte masks */
-               t4_write_reg(adap, EPIO_REG(DATA0), mask0);
-               t4_write_reg(adap, EPIO_REG(OP), ADDRESS_V(i) | EPIOWR_F);
-               t4_read_reg(adap, EPIO_REG(OP));                /* flush */
-               if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY_F)
-                       return -ETIMEDOUT;
-
-               /* write CRC */
-               t4_write_reg(adap, EPIO_REG(DATA0), crc);
-               t4_write_reg(adap, EPIO_REG(OP), ADDRESS_V(i + 32) | EPIOWR_F);
-               t4_read_reg(adap, EPIO_REG(OP));                /* flush */
-               if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY_F)
-                       return -ETIMEDOUT;
-       }
-#undef EPIO_REG
-
-       t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2_A), 0, PATEN_F);
-       return 0;
+#undef GET_STAT
+#undef GET_STAT_COM
 }
 
 /*     t4_mk_filtdelwr - create a delete filter WR
index 88067d90121cffadf5ca91c13aee8459574cf0a6..f9a2cb164737dac11fba1b96dbf3aef21537bf47 100644 (file)
@@ -52,8 +52,6 @@ enum {
        MBOX_LEN       = 64,    /* mailbox size in bytes */
        TRACE_LEN      = 112,   /* length of trace data and mask */
        FILTER_OPT_LEN = 36,    /* filter tuple width for optional components */
-       NWOL_PAT       = 8,     /* # of WoL patterns */
-       WOL_PAT_LEN    = 128,   /* length of WoL patterns */
 };
 
 enum {
index c7fc3d3068f966ff1af685a7a54686dc15722913..af3462db5adbbaed1aa2c2e7d992df224d01755f 100644 (file)
 #define SGE_STAT_MATCH_A       0x10e8
 #define SGE_STAT_CFG_A         0x10ec
 
+#define STATMODE_S    2
+#define STATMODE_V(x) ((x) << STATMODE_S)
+
 #define STATSOURCE_T5_S    9
+#define STATSOURCE_T5_M    0xfU
 #define STATSOURCE_T5_V(x) ((x) << STATSOURCE_T5_S)
+#define STATSOURCE_T5_G(x) (((x) >> STATSOURCE_T5_S) & STATSOURCE_T5_M)
 
 #define SGE_DBFIFO_STATUS2_A 0x1118
 
 #define CSUM_HAS_PSEUDO_HDR_F    CSUM_HAS_PSEUDO_HDR_V(1U)
 
 #define TP_MIB_MAC_IN_ERR_0_A  0x0
+#define TP_MIB_HDR_IN_ERR_0_A  0x4
+#define TP_MIB_TCP_IN_ERR_0_A  0x8
 #define TP_MIB_TCP_OUT_RST_A   0xc
 #define TP_MIB_TCP_IN_SEG_HI_A 0x10
 #define TP_MIB_TCP_IN_SEG_LO_A 0x11
 #define TP_MIB_TCP_RXT_SEG_HI_A        0x14
 #define TP_MIB_TCP_RXT_SEG_LO_A        0x15
 #define TP_MIB_TNL_CNG_DROP_0_A 0x18
+#define TP_MIB_OFD_CHN_DROP_0_A 0x1c
 #define TP_MIB_TCP_V6IN_ERR_0_A 0x28
 #define TP_MIB_TCP_V6OUT_RST_A 0x2c
 #define TP_MIB_OFD_ARP_DROP_A  0x36
+#define TP_MIB_CPL_IN_REQ_0_A  0x38
+#define TP_MIB_CPL_OUT_RSP_0_A 0x3c
 #define TP_MIB_TNL_DROP_0_A    0x44
+#define TP_MIB_FCOE_DDP_0_A    0x48
+#define TP_MIB_FCOE_DROP_0_A   0x4c
+#define TP_MIB_FCOE_BYTE_0_HI_A        0x50
 #define TP_MIB_OFD_VLN_DROP_0_A        0x58
+#define TP_MIB_USM_PKTS_A      0x5c
+#define TP_MIB_RQE_DFR_PKT_A   0x64
 
 #define ULP_TX_INT_CAUSE_A     0x8dcc
 
 #define MPS_PORT_STAT_LB_PORT_1519B_MAX_L 0x520
 #define MPS_PORT_STAT_LB_PORT_1519B_MAX_H 0x524
 #define MPS_PORT_STAT_LB_PORT_DROP_FRAMES 0x528
+#define MPS_PORT_STAT_LB_PORT_DROP_FRAMES_L 0x528
 #define MPS_PORT_STAT_RX_PORT_BYTES_L 0x540
 #define MPS_PORT_STAT_RX_PORT_BYTES_H 0x544
 #define MPS_PORT_STAT_RX_PORT_FRAMES_L 0x548