diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-12-15 14:52:16 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-12-15 14:52:16 -0300 |
commit | 8d91c1e411f55d7ea91b1183a2e9f8088fb4d5be (patch) | |
tree | e9891aa6c295060d065adffd610c4f49ecf884f3 /drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | |
parent | a71852147516bc1cb5b0b3cbd13639bfd4022dc8 (diff) |
Linux-libre 4.3.2-gnu
Diffstat (limited to 'drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | 182 |
1 files changed, 132 insertions, 50 deletions
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c index a4228e664..af54c1094 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c @@ -35,10 +35,10 @@ struct nicvf_stat { } static const struct nicvf_stat nicvf_hw_stats[] = { - NICVF_HW_STAT(rx_bytes_ok), - NICVF_HW_STAT(rx_ucast_frames_ok), - NICVF_HW_STAT(rx_bcast_frames_ok), - NICVF_HW_STAT(rx_mcast_frames_ok), + NICVF_HW_STAT(rx_bytes), + NICVF_HW_STAT(rx_ucast_frames), + NICVF_HW_STAT(rx_bcast_frames), + NICVF_HW_STAT(rx_mcast_frames), NICVF_HW_STAT(rx_fcs_errors), NICVF_HW_STAT(rx_l2_errors), NICVF_HW_STAT(rx_drop_red), @@ -49,6 +49,30 @@ static const struct nicvf_stat nicvf_hw_stats[] = { NICVF_HW_STAT(rx_drop_mcast), NICVF_HW_STAT(rx_drop_l3_bcast), NICVF_HW_STAT(rx_drop_l3_mcast), + NICVF_HW_STAT(rx_bgx_truncated_pkts), + NICVF_HW_STAT(rx_jabber_errs), + NICVF_HW_STAT(rx_fcs_errs), + NICVF_HW_STAT(rx_bgx_errs), + NICVF_HW_STAT(rx_prel2_errs), + NICVF_HW_STAT(rx_l2_hdr_malformed), + NICVF_HW_STAT(rx_oversize), + NICVF_HW_STAT(rx_undersize), + NICVF_HW_STAT(rx_l2_len_mismatch), + NICVF_HW_STAT(rx_l2_pclp), + NICVF_HW_STAT(rx_ip_ver_errs), + NICVF_HW_STAT(rx_ip_csum_errs), + NICVF_HW_STAT(rx_ip_hdr_malformed), + NICVF_HW_STAT(rx_ip_payload_malformed), + NICVF_HW_STAT(rx_ip_ttl_errs), + NICVF_HW_STAT(rx_l3_pclp), + NICVF_HW_STAT(rx_l4_malformed), + NICVF_HW_STAT(rx_l4_csum_errs), + NICVF_HW_STAT(rx_udp_len_errs), + NICVF_HW_STAT(rx_l4_port_errs), + NICVF_HW_STAT(rx_tcp_flag_errs), + NICVF_HW_STAT(rx_tcp_offset_errs), + NICVF_HW_STAT(rx_l4_pclp), + NICVF_HW_STAT(rx_truncated_pkts), NICVF_HW_STAT(tx_bytes_ok), NICVF_HW_STAT(tx_ucast_frames_ok), NICVF_HW_STAT(tx_bcast_frames_ok), @@ -125,10 +149,33 @@ static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl) nic->msg_enable = lvl; } +static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset) +{ + int stats, qidx; + int start_qidx = qset * MAX_RCV_QUEUES_PER_QS; + + for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { + for (stats = 0; stats < nicvf_n_queue_stats; stats++) { + sprintf(*data, "rxq%d: %s", qidx + start_qidx, + nicvf_queue_stats[stats].name); + *data += ETH_GSTRING_LEN; + } + } + + for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { + for (stats = 0; stats < nicvf_n_queue_stats; stats++) { + sprintf(*data, "txq%d: %s", qidx + start_qidx, + nicvf_queue_stats[stats].name); + *data += ETH_GSTRING_LEN; + } + } +} + static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data) { struct nicvf *nic = netdev_priv(netdev); - int stats, qidx; + int stats; + int sqs; if (sset != ETH_SS_STATS) return; @@ -143,20 +190,12 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data) data += ETH_GSTRING_LEN; } - for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { - for (stats = 0; stats < nicvf_n_queue_stats; stats++) { - sprintf(data, "rxq%d: %s", qidx, - nicvf_queue_stats[stats].name); - data += ETH_GSTRING_LEN; - } - } + nicvf_get_qset_strings(nic, &data, 0); - for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { - for (stats = 0; stats < nicvf_n_queue_stats; stats++) { - sprintf(data, "txq%d: %s", qidx, - nicvf_queue_stats[stats].name); - data += ETH_GSTRING_LEN; - } + for (sqs = 0; sqs < nic->sqs_count; sqs++) { + if (!nic->snicvf[sqs]) + continue; + nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1); } for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) { @@ -173,21 +212,58 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data) static int nicvf_get_sset_count(struct net_device *netdev, int sset) { struct nicvf *nic = netdev_priv(netdev); + int qstats_count; + int sqs; if (sset != ETH_SS_STATS) return -EINVAL; + qstats_count = nicvf_n_queue_stats * + (nic->qs->rq_cnt + nic->qs->sq_cnt); + for (sqs = 0; sqs < nic->sqs_count; sqs++) { + struct nicvf *snic; + + snic = nic->snicvf[sqs]; + if (!snic) + continue; + qstats_count += nicvf_n_queue_stats * + (snic->qs->rq_cnt + snic->qs->sq_cnt); + } + return nicvf_n_hw_stats + nicvf_n_drv_stats + - (nicvf_n_queue_stats * - (nic->qs->rq_cnt + nic->qs->sq_cnt)) + + qstats_count + BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT; } +static void nicvf_get_qset_stats(struct nicvf *nic, + struct ethtool_stats *stats, u64 **data) +{ + int stat, qidx; + + if (!nic) + return; + + for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { + nicvf_update_rq_stats(nic, qidx); + for (stat = 0; stat < nicvf_n_queue_stats; stat++) + *((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats) + [nicvf_queue_stats[stat].index]; + } + + for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { + nicvf_update_sq_stats(nic, qidx); + for (stat = 0; stat < nicvf_n_queue_stats; stat++) + *((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats) + [nicvf_queue_stats[stat].index]; + } +} + static void nicvf_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct nicvf *nic = netdev_priv(netdev); - int stat, qidx; + int stat; + int sqs; nicvf_update_stats(nic); @@ -195,22 +271,18 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev, nicvf_update_lmac_stats(nic); for (stat = 0; stat < nicvf_n_hw_stats; stat++) - *(data++) = ((u64 *)&nic->stats) + *(data++) = ((u64 *)&nic->hw_stats) [nicvf_hw_stats[stat].index]; for (stat = 0; stat < nicvf_n_drv_stats; stat++) *(data++) = ((u64 *)&nic->drv_stats) [nicvf_drv_stats[stat].index]; - for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { - for (stat = 0; stat < nicvf_n_queue_stats; stat++) - *(data++) = ((u64 *)&nic->qs->rq[qidx].stats) - [nicvf_queue_stats[stat].index]; - } + nicvf_get_qset_stats(nic, stats, &data); - for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { - for (stat = 0; stat < nicvf_n_queue_stats; stat++) - *(data++) = ((u64 *)&nic->qs->sq[qidx].stats) - [nicvf_queue_stats[stat].index]; + for (sqs = 0; sqs < nic->sqs_count; sqs++) { + if (!nic->snicvf[sqs]) + continue; + nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data); } for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++) @@ -369,7 +441,7 @@ static int nicvf_get_rxnfc(struct net_device *dev, switch (info->cmd) { case ETHTOOL_GRXRINGS: - info->data = nic->qs->rq_cnt; + info->data = nic->rx_queues; ret = 0; break; case ETHTOOL_GRXFH: @@ -501,17 +573,15 @@ static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir, struct nicvf_rss_info *rss = &nic->rss_info; int idx; - if ((nic->qs->rq_cnt <= 1) || (nic->cpi_alg != CPI_ALG_NONE)) { - rss->enable = false; - rss->hash_bits = 0; - return -EIO; - } - - /* We do not allow change in unsupported parameters */ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; - rss->enable = true; + if (!rss->enable) { + netdev_err(nic->netdev, + "RSS is disabled, cannot change settings\n"); + return -EIO; + } + if (indir) { for (idx = 0; idx < rss->rss_size; idx++) rss->ind_tbl[idx] = indir[idx]; @@ -534,11 +604,11 @@ static void nicvf_get_channels(struct net_device *dev, memset(channel, 0, sizeof(*channel)); - channel->max_rx = MAX_RCV_QUEUES_PER_QS; - channel->max_tx = MAX_SND_QUEUES_PER_QS; + channel->max_rx = nic->max_queues; + channel->max_tx = nic->max_queues; - channel->rx_count = nic->qs->rq_cnt; - channel->tx_count = nic->qs->sq_cnt; + channel->rx_count = nic->rx_queues; + channel->tx_count = nic->tx_queues; } /* Set no of Tx, Rx queues to be used */ @@ -548,22 +618,34 @@ static int nicvf_set_channels(struct net_device *dev, struct nicvf *nic = netdev_priv(dev); int err = 0; bool if_up = netif_running(dev); + int cqcount; if (!channel->rx_count || !channel->tx_count) return -EINVAL; - if (channel->rx_count > MAX_RCV_QUEUES_PER_QS) + if (channel->rx_count > nic->max_queues) return -EINVAL; - if (channel->tx_count > MAX_SND_QUEUES_PER_QS) + if (channel->tx_count > nic->max_queues) return -EINVAL; if (if_up) nicvf_stop(dev); - nic->qs->rq_cnt = channel->rx_count; - nic->qs->sq_cnt = channel->tx_count; + cqcount = max(channel->rx_count, channel->tx_count); + + if (cqcount > MAX_CMP_QUEUES_PER_QS) { + nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS); + nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1; + } else { + nic->sqs_count = 0; + } + + nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS); + nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS); nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt); - err = nicvf_set_real_num_queues(dev, nic->qs->sq_cnt, nic->qs->rq_cnt); + nic->rx_queues = channel->rx_count; + nic->tx_queues = channel->tx_count; + err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues); if (err) return err; @@ -571,7 +653,7 @@ static int nicvf_set_channels(struct net_device *dev, nicvf_open(dev); netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", - nic->qs->sq_cnt, nic->qs->rq_cnt); + nic->tx_queues, nic->rx_queues); return err; } |