 d6a9a92e32
			
		
	
	d6a9a92e32
	
	
	
		
			
			Seemingly unneeded based on new upstream code so manually deleted: layerscape: 820-usb-0007-usb-dwc3-gadget-increase-timeout-value-for-send-ep-c.patch Manually merged: generic-hack: 251-sound_kconfig.patch All other modifications made by update_kernel.sh Build system: x86_64 Build-tested: ipq806x/R7800, ath79/generic, bcm27xx/bcm2711 Run-tested: ipq806x/R7800, lantiq/Easybox 904 xDSL No dmesg regressions, everything functional Signed-off-by: John Audia <graysky@archlinux.us> [add lantiq test report, minor commit message clarification] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
		
			
				
	
	
		
			264 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			264 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 936ce2452068cb0f6d48ca7d77d6b975802c19ae Mon Sep 17 00:00:00 2001
 | |
| From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
 | |
| Date: Tue, 3 Sep 2019 14:13:32 +0300
 | |
| Subject: [PATCH] dpaa2-eth: Add support for Rx traffic classes
 | |
| 
 | |
| The firmware reserves for each DPNI a number of RX frame queues
 | |
| equal to the number of configured flows x number of configured
 | |
| traffic classes.
 | |
| 
 | |
| Current driver configuration directs all incoming traffic to
 | |
| FQs corresponding to TC0, leaving all other priority levels unused.
 | |
| 
 | |
| Start adding support for multiple ingress traffic classes, by
 | |
| configuring the FQs associated with all priority levels, not just
 | |
| TC0. All settings that are per-TC, such as those related to
 | |
| hashing and flow steering, are also updated.
 | |
| 
 | |
| Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
 | |
| ---
 | |
|  .../ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c   |  7 ++-
 | |
|  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 70 +++++++++++++++-------
 | |
|  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  4 +-
 | |
|  .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   | 19 ++++--
 | |
|  4 files changed, 68 insertions(+), 32 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c
 | |
| +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c
 | |
| @@ -81,8 +81,8 @@ static int dpaa2_dbg_fqs_show(struct seq
 | |
|  	int i, err;
 | |
|  
 | |
|  	seq_printf(file, "FQ stats for %s:\n", priv->net_dev->name);
 | |
| -	seq_printf(file, "%s%16s%16s%16s%16s\n",
 | |
| -		   "VFQID", "CPU", "Type", "Frames", "Pending frames");
 | |
| +	seq_printf(file, "%s%16s%16s%16s%16s%16s\n",
 | |
| +		   "VFQID", "CPU", "TC", "Type", "Frames", "Pending frames");
 | |
|  
 | |
|  	for (i = 0; i <  priv->num_fqs; i++) {
 | |
|  		fq = &priv->fq[i];
 | |
| @@ -90,9 +90,10 @@ static int dpaa2_dbg_fqs_show(struct seq
 | |
|  		if (err)
 | |
|  			fcnt = 0;
 | |
|  
 | |
| -		seq_printf(file, "%5d%16d%16s%16llu%16u\n",
 | |
| +		seq_printf(file, "%5d%16d%16d%16s%16llu%16u\n",
 | |
|  			   fq->fqid,
 | |
|  			   fq->target_cpu,
 | |
| +			   fq->tc,
 | |
|  			   fq_type_to_str(fq),
 | |
|  			   fq->stats.frames,
 | |
|  			   fcnt);
 | |
| --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
 | |
| +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
 | |
| @@ -1231,6 +1231,7 @@ static void disable_ch_napi(struct dpaa2
 | |
|  static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable)
 | |
|  {
 | |
|  	struct dpni_taildrop td = {0};
 | |
| +	struct dpaa2_eth_fq *fq;
 | |
|  	int i, err;
 | |
|  
 | |
|  	if (priv->rx_td_enabled == enable)
 | |
| @@ -1240,11 +1241,12 @@ static void dpaa2_eth_set_rx_taildrop(st
 | |
|  	td.threshold = DPAA2_ETH_TAILDROP_THRESH;
 | |
|  
 | |
|  	for (i = 0; i < priv->num_fqs; i++) {
 | |
| -		if (priv->fq[i].type != DPAA2_RX_FQ)
 | |
| +		fq = &priv->fq[i];
 | |
| +		if (fq->type != DPAA2_RX_FQ)
 | |
|  			continue;
 | |
|  		err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token,
 | |
| -					DPNI_CP_QUEUE, DPNI_QUEUE_RX, 0,
 | |
| -					priv->fq[i].flowid, &td);
 | |
| +					DPNI_CP_QUEUE, DPNI_QUEUE_RX,
 | |
| +					fq->tc, fq->flowid, &td);
 | |
|  		if (err) {
 | |
|  			netdev_err(priv->net_dev,
 | |
|  				   "dpni_set_taildrop() failed\n");
 | |
| @@ -2338,7 +2340,7 @@ static void set_fq_affinity(struct dpaa2
 | |
|  
 | |
|  static void setup_fqs(struct dpaa2_eth_priv *priv)
 | |
|  {
 | |
| -	int i;
 | |
| +	int i, j;
 | |
|  
 | |
|  	/* We have one TxConf FQ per Tx flow.
 | |
|  	 * The number of Tx and Rx queues is the same.
 | |
| @@ -2350,10 +2352,13 @@ static void setup_fqs(struct dpaa2_eth_p
 | |
|  		priv->fq[priv->num_fqs++].flowid = (u16)i;
 | |
|  	}
 | |
|  
 | |
| -	for (i = 0; i < dpaa2_eth_queue_count(priv); i++) {
 | |
| -		priv->fq[priv->num_fqs].type = DPAA2_RX_FQ;
 | |
| -		priv->fq[priv->num_fqs].consume = dpaa2_eth_rx;
 | |
| -		priv->fq[priv->num_fqs++].flowid = (u16)i;
 | |
| +	for (j = 0; j < dpaa2_eth_tc_count(priv); j++) {
 | |
| +		for (i = 0; i < dpaa2_eth_queue_count(priv); i++) {
 | |
| +			priv->fq[priv->num_fqs].type = DPAA2_RX_FQ;
 | |
| +			priv->fq[priv->num_fqs].consume = dpaa2_eth_rx;
 | |
| +			priv->fq[priv->num_fqs].tc = (u8)j;
 | |
| +			priv->fq[priv->num_fqs++].flowid = (u16)i;
 | |
| +		}
 | |
|  	}
 | |
|  
 | |
|  	/* For each FQ, decide on which core to process incoming frames */
 | |
| @@ -2701,7 +2706,7 @@ static int setup_rx_flow(struct dpaa2_et
 | |
|  	int err;
 | |
|  
 | |
|  	err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
 | |
| -			     DPNI_QUEUE_RX, 0, fq->flowid, &queue, &qid);
 | |
| +			     DPNI_QUEUE_RX, fq->tc, fq->flowid, &queue, &qid);
 | |
|  	if (err) {
 | |
|  		dev_err(dev, "dpni_get_queue(RX) failed\n");
 | |
|  		return err;
 | |
| @@ -2714,7 +2719,7 @@ static int setup_rx_flow(struct dpaa2_et
 | |
|  	queue.destination.priority = 1;
 | |
|  	queue.user_context = (u64)(uintptr_t)fq;
 | |
|  	err = dpni_set_queue(priv->mc_io, 0, priv->mc_token,
 | |
| -			     DPNI_QUEUE_RX, 0, fq->flowid,
 | |
| +			     DPNI_QUEUE_RX, fq->tc, fq->flowid,
 | |
|  			     DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST,
 | |
|  			     &queue);
 | |
|  	if (err) {
 | |
| @@ -2723,6 +2728,10 @@ static int setup_rx_flow(struct dpaa2_et
 | |
|  	}
 | |
|  
 | |
|  	/* xdp_rxq setup */
 | |
| +	/* only once for each channel */
 | |
| +	if (fq->tc > 0)
 | |
| +		return 0;
 | |
| +
 | |
|  	err = xdp_rxq_info_reg(&fq->channel->xdp_rxq, priv->net_dev,
 | |
|  			       fq->flowid);
 | |
|  	if (err) {
 | |
| @@ -2860,7 +2869,7 @@ static int config_legacy_hash_key(struct
 | |
|  {
 | |
|  	struct device *dev = priv->net_dev->dev.parent;
 | |
|  	struct dpni_rx_tc_dist_cfg dist_cfg;
 | |
| -	int err;
 | |
| +	int i, err = 0;
 | |
|  
 | |
|  	memset(&dist_cfg, 0, sizeof(dist_cfg));
 | |
|  
 | |
| @@ -2868,9 +2877,14 @@ static int config_legacy_hash_key(struct
 | |
|  	dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
 | |
|  	dist_cfg.dist_mode = DPNI_DIST_MODE_HASH;
 | |
|  
 | |
| -	err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token, 0, &dist_cfg);
 | |
| -	if (err)
 | |
| -		dev_err(dev, "dpni_set_rx_tc_dist failed\n");
 | |
| +	for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
 | |
| +		err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token,
 | |
| +					  i, &dist_cfg);
 | |
| +		if (err) {
 | |
| +			dev_err(dev, "dpni_set_rx_tc_dist failed\n");
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
|  
 | |
|  	return err;
 | |
|  }
 | |
| @@ -2880,7 +2894,7 @@ static int config_hash_key(struct dpaa2_
 | |
|  {
 | |
|  	struct device *dev = priv->net_dev->dev.parent;
 | |
|  	struct dpni_rx_dist_cfg dist_cfg;
 | |
| -	int err;
 | |
| +	int i, err = 0;
 | |
|  
 | |
|  	memset(&dist_cfg, 0, sizeof(dist_cfg));
 | |
|  
 | |
| @@ -2888,9 +2902,15 @@ static int config_hash_key(struct dpaa2_
 | |
|  	dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
 | |
|  	dist_cfg.enable = 1;
 | |
|  
 | |
| -	err = dpni_set_rx_hash_dist(priv->mc_io, 0, priv->mc_token, &dist_cfg);
 | |
| -	if (err)
 | |
| -		dev_err(dev, "dpni_set_rx_hash_dist failed\n");
 | |
| +	for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
 | |
| +		dist_cfg.tc = i;
 | |
| +		err = dpni_set_rx_hash_dist(priv->mc_io, 0, priv->mc_token,
 | |
| +					    &dist_cfg);
 | |
| +		if (err) {
 | |
| +			dev_err(dev, "dpni_set_rx_hash_dist failed\n");
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
|  
 | |
|  	return err;
 | |
|  }
 | |
| @@ -2900,7 +2920,7 @@ static int config_cls_key(struct dpaa2_e
 | |
|  {
 | |
|  	struct device *dev = priv->net_dev->dev.parent;
 | |
|  	struct dpni_rx_dist_cfg dist_cfg;
 | |
| -	int err;
 | |
| +	int i, err = 0;
 | |
|  
 | |
|  	memset(&dist_cfg, 0, sizeof(dist_cfg));
 | |
|  
 | |
| @@ -2908,9 +2928,15 @@ static int config_cls_key(struct dpaa2_e
 | |
|  	dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
 | |
|  	dist_cfg.enable = 1;
 | |
|  
 | |
| -	err = dpni_set_rx_fs_dist(priv->mc_io, 0, priv->mc_token, &dist_cfg);
 | |
| -	if (err)
 | |
| -		dev_err(dev, "dpni_set_rx_fs_dist failed\n");
 | |
| +	for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
 | |
| +		dist_cfg.tc = i;
 | |
| +		err = dpni_set_rx_fs_dist(priv->mc_io, 0, priv->mc_token,
 | |
| +					  &dist_cfg);
 | |
| +		if (err) {
 | |
| +			dev_err(dev, "dpni_set_rx_fs_dist failed\n");
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
|  
 | |
|  	return err;
 | |
|  }
 | |
| --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
 | |
| +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
 | |
| @@ -291,7 +291,9 @@ struct dpaa2_eth_ch_stats {
 | |
|  
 | |
|  /* Maximum number of queues associated with a DPNI */
 | |
|  #define DPAA2_ETH_MAX_TCS		8
 | |
| -#define DPAA2_ETH_MAX_RX_QUEUES		16
 | |
| +#define DPAA2_ETH_MAX_RX_QUEUES_PER_TC	16
 | |
| +#define DPAA2_ETH_MAX_RX_QUEUES		\
 | |
| +	(DPAA2_ETH_MAX_RX_QUEUES_PER_TC * DPAA2_ETH_MAX_TCS)
 | |
|  #define DPAA2_ETH_MAX_TX_QUEUES		16
 | |
|  #define DPAA2_ETH_MAX_QUEUES		(DPAA2_ETH_MAX_RX_QUEUES + \
 | |
|  					DPAA2_ETH_MAX_TX_QUEUES)
 | |
| --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
 | |
| +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
 | |
| @@ -502,7 +502,7 @@ static int do_cls_rule(struct net_device
 | |
|  	dma_addr_t key_iova;
 | |
|  	u64 fields = 0;
 | |
|  	void *key_buf;
 | |
| -	int err;
 | |
| +	int i, err;
 | |
|  
 | |
|  	if (fs->ring_cookie != RX_CLS_FLOW_DISC &&
 | |
|  	    fs->ring_cookie >= dpaa2_eth_queue_count(priv))
 | |
| @@ -562,11 +562,18 @@ static int do_cls_rule(struct net_device
 | |
|  			fs_act.options |= DPNI_FS_OPT_DISCARD;
 | |
|  		else
 | |
|  			fs_act.flow_id = fs->ring_cookie;
 | |
| -		err = dpni_add_fs_entry(priv->mc_io, 0, priv->mc_token, 0,
 | |
| -					fs->location, &rule_cfg, &fs_act);
 | |
| -	} else {
 | |
| -		err = dpni_remove_fs_entry(priv->mc_io, 0, priv->mc_token, 0,
 | |
| -					   &rule_cfg);
 | |
| +	}
 | |
| +	for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
 | |
| +		if (add)
 | |
| +			err = dpni_add_fs_entry(priv->mc_io, 0, priv->mc_token,
 | |
| +						i, fs->location, &rule_cfg,
 | |
| +						&fs_act);
 | |
| +		else
 | |
| +			err = dpni_remove_fs_entry(priv->mc_io, 0,
 | |
| +						   priv->mc_token, i,
 | |
| +						   &rule_cfg);
 | |
| +		if (err)
 | |
| +			break;
 | |
|  	}
 | |
|  
 | |
|  	dma_unmap_single(dev, key_iova, rule_cfg.key_size * 2, DMA_TO_DEVICE);
 |