diff options
| -rw-r--r-- | drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 31 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 37 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/dpaa2/dpni.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/dpaa2/dpni.h | 40 | 
4 files changed, 93 insertions, 17 deletions
| diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 5402867272be..162d7d8fb295 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1348,7 +1348,7 @@ static u32 ingress_fq_count(struct dpaa2_eth_priv *priv)  	return total;  } -static void wait_for_fq_empty(struct dpaa2_eth_priv *priv) +static void wait_for_ingress_fq_empty(struct dpaa2_eth_priv *priv)  {  	int retries = 10;  	u32 pending; @@ -1360,6 +1360,31 @@ static void wait_for_fq_empty(struct dpaa2_eth_priv *priv)  	} while (pending && --retries);  } +#define DPNI_TX_PENDING_VER_MAJOR	7 +#define DPNI_TX_PENDING_VER_MINOR	13 +static void wait_for_egress_fq_empty(struct dpaa2_eth_priv *priv) +{ +	union dpni_statistics stats; +	int retries = 10; +	int err; + +	if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_TX_PENDING_VER_MAJOR, +				   DPNI_TX_PENDING_VER_MINOR) < 0) +		goto out; + +	do { +		err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, 6, +					  &stats); +		if (err) +			goto out; +		if (stats.page_6.tx_pending_frames == 0) +			return; +	} while (--retries); + +out: +	msleep(500); +} +  static int dpaa2_eth_stop(struct net_device *net_dev)  {  	struct dpaa2_eth_priv *priv = netdev_priv(net_dev); @@ -1379,7 +1404,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev)  	 * on WRIOP. After it finishes, wait until all remaining frames on Rx  	 * and Tx conf queues are consumed on NAPI poll.  	 */ -	msleep(500); +	wait_for_egress_fq_empty(priv);  	do {  		dpni_disable(priv->mc_io, 0, priv->mc_token); @@ -1395,7 +1420,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev)  		 */  	} -	wait_for_fq_empty(priv); +	wait_for_ingress_fq_empty(priv);  	disable_ch_napi(priv);  	/* Empty the buffer pool */ diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c index 93076fe01b45..0aa1c34019bb 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c @@ -28,6 +28,11 @@ static char dpaa2_ethtool_stats[][ETH_GSTRING_LEN] = {  	"[hw] rx nobuffer discards",  	"[hw] tx discarded frames",  	"[hw] tx confirmed frames", +	"[hw] tx dequeued bytes", +	"[hw] tx dequeued frames", +	"[hw] tx rejected bytes", +	"[hw] tx rejected frames", +	"[hw] tx pending frames",  };  #define DPAA2_ETH_NUM_STATS	ARRAY_SIZE(dpaa2_ethtool_stats) @@ -188,27 +193,33 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,  	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);  	struct dpaa2_eth_drv_stats *extras;  	struct dpaa2_eth_ch_stats *ch_stats; +	int dpni_stats_page_size[DPNI_STATISTICS_CNT] = { +		sizeof(dpni_stats.page_0), +		sizeof(dpni_stats.page_1), +		sizeof(dpni_stats.page_2), +		sizeof(dpni_stats.page_3), +		sizeof(dpni_stats.page_4), +		sizeof(dpni_stats.page_5), +		sizeof(dpni_stats.page_6), +	};  	memset(data, 0,  	       sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS));  	/* Print standard counters, from DPNI statistics */ -	for (j = 0; j <= 2; j++) { +	for (j = 0; j <= 6; j++) { +		/* We're not interested in pages 4 & 5 for now */ +		if (j == 4 || j == 5) +			continue;  		err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token,  					  j, &dpni_stats); -		if (err != 0) +		if (err == -EINVAL) +			/* Older firmware versions don't support all pages */ +			memset(&dpni_stats, 0, sizeof(dpni_stats)); +		else  			netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j); -		switch (j) { -		case 0: -			num_cnt = sizeof(dpni_stats.page_0) / sizeof(u64); -			break; -		case 1: -			num_cnt = sizeof(dpni_stats.page_1) / sizeof(u64); -			break; -		case 2: -			num_cnt = sizeof(dpni_stats.page_2) / sizeof(u64); -			break; -		} + +		num_cnt = dpni_stats_page_size[j] / sizeof(u64);  		for (k = 0; k < num_cnt; k++)  			*(data + i++) = dpni_stats.raw.counter[k];  	} diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c b/drivers/net/ethernet/freescale/dpaa2/dpni.c index 05e30893dee6..dd54e6953aeb 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c @@ -1470,7 +1470,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_io,   * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'   * @token:	Token of DPNI object   * @page:	Selects the statistics page to retrieve, see - *		DPNI_GET_STATISTICS output. Pages are numbered 0 to 2. + *		DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.   * @stat:	Structure containing the statistics   *   * Return:	'0' on Success; Error code otherwise. diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.h b/drivers/net/ethernet/freescale/dpaa2/dpni.h index 3e8fc6c7a8da..fd583911b6c0 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h @@ -416,6 +416,26 @@ int dpni_get_tx_data_offset(struct fsl_mc_io	*mc_io,   *	lack of buffers   * @page_2.egress_discarded_frames: Egress discarded frame count   * @page_2.egress_confirmed_frames: Egress confirmed frame count + * @page3: Page_3 statistics structure + * @page_3.egress_dequeue_bytes: Cumulative count of the number of bytes + *	dequeued from egress FQs + * @page_3.egress_dequeue_frames: Cumulative count of the number of frames + *	dequeued from egress FQs + * @page_3.egress_reject_bytes: Cumulative count of the number of bytes in + *	egress frames whose enqueue was rejected + * @page_3.egress_reject_frames: Cumulative count of the number of egress + *	frames whose enqueue was rejected + * @page_4: Page_4 statistics structure: congestion points + * @page_4.cgr_reject_frames: number of rejected frames due to congestion point + * @page_4.cgr_reject_bytes: number of rejected bytes due to congestion point + * @page_5: Page_5 statistics structure: policer + * @page_5.policer_cnt_red: NUmber of red colored frames + * @page_5.policer_cnt_yellow: number of yellow colored frames + * @page_5.policer_cnt_green: number of green colored frames + * @page_5.policer_cnt_re_red: number of recolored red frames + * @page_5.policer_cnt_re_yellow: number of recolored yellow frames + * @page_6: Page_6 statistics structure + * @page_6.tx_pending_frames: total number of frames pending in egress FQs   * @raw: raw statistics structure, used to index counters   */  union dpni_statistics { @@ -443,6 +463,26 @@ union dpni_statistics {  		u64 egress_confirmed_frames;  	} page_2;  	struct { +		u64 egress_dequeue_bytes; +		u64 egress_dequeue_frames; +		u64 egress_reject_bytes; +		u64 egress_reject_frames; +	} page_3; +	struct { +		u64 cgr_reject_frames; +		u64 cgr_reject_bytes; +	} page_4; +	struct { +		u64 policer_cnt_red; +		u64 policer_cnt_yellow; +		u64 policer_cnt_green; +		u64 policer_cnt_re_red; +		u64 policer_cnt_re_yellow; +	} page_5; +	struct { +		u64 tx_pending_frames; +	} page_6; +	struct {  		u64 counter[DPNI_STATISTICS_CNT];  	} raw;  }; | 
