ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch
1 From 73b0aa73b401810424afa90bf58663a56ad9d51a Mon Sep 17 00:00:00 2001
2 From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
3 Date: Fri, 5 May 2017 19:07:50 +0300
4 Subject: [PATCH] dpaa2-eth: Add Rx error queue
5
6 Until now all error frames on the ingress path were discarded
7 in hardware. For debug purposes, add an option to have these
8 frames delivered to the cpu, on a dedicated queue.
9
10 TODO: Remove Kconfig option, find another way to enable
11 Rx error queue support
12
13 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
14 ---
15  drivers/net/ethernet/freescale/dpaa2/Kconfig     | 10 +++
16  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 97 ++++++++++++++++++++++++
17  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h |  5 +-
18  3 files changed, 111 insertions(+), 1 deletion(-)
19
20 --- a/drivers/net/ethernet/freescale/dpaa2/Kconfig
21 +++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig
22 @@ -15,6 +15,16 @@ config FSL_DPAA2_ETH_DCB
23         depends on DCB
24         help
25           Enable Priority-Based Flow Control (PFC) support in the driver
26 +
27 +config FSL_DPAA2_ETH_USE_ERR_QUEUE
28 +       bool "Enable Rx error queue"
29 +       default n
30 +       help
31 +         Allow Rx error frames to be enqueued on an error queue
32 +         and processed by the driver (by default they are dropped
33 +         in hardware).
34 +         This may impact performance, recommended for debugging
35 +         purposes only.
36  endif
37  
38  config FSL_DPAA2_PTP_CLOCK
39 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
40 +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
41 @@ -449,6 +449,53 @@ err_frame_format:
42         percpu_stats->rx_dropped++;
43  }
44  
45 +#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE
46 +/* Processing of Rx frames received on the error FQ
47 + * We check and print the error bits and then free the frame
48 + */
49 +static void dpaa2_eth_rx_err(struct dpaa2_eth_priv *priv,
50 +                            struct dpaa2_eth_channel *ch,
51 +                            const struct dpaa2_fd *fd,
52 +                            struct dpaa2_eth_fq *fq __always_unused)
53 +{
54 +       struct device *dev = priv->net_dev->dev.parent;
55 +       dma_addr_t addr = dpaa2_fd_get_addr(fd);
56 +       void *vaddr;
57 +       struct rtnl_link_stats64 *percpu_stats;
58 +       struct dpaa2_fas *fas;
59 +       u32 status = 0;
60 +       u32 fd_errors;
61 +       bool has_fas_errors = false;
62 +
63 +       vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
64 +       dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, DMA_BIDIRECTIONAL);
65 +
66 +       /* check frame errors in the FD field */
67 +       fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_RX_ERR_MASK;
68 +       if (likely(fd_errors)) {
69 +               has_fas_errors = (fd_errors & FD_CTRL_FAERR) &&
70 +                                !!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV);
71 +               if (net_ratelimit())
72 +                       netdev_dbg(priv->net_dev, "RX frame FD err: %08x\n",
73 +                                  fd_errors);
74 +       }
75 +
76 +       /* check frame errors in the FAS field */
77 +       if (has_fas_errors) {
78 +               fas = dpaa2_get_fas(vaddr, false);
79 +               status = le32_to_cpu(fas->status);
80 +               if (net_ratelimit())
81 +                       netdev_dbg(priv->net_dev, "Rx frame FAS err: 0x%08x\n",
82 +                                  status & DPAA2_FAS_RX_ERR_MASK);
83 +       }
84 +       free_rx_fd(priv, fd, vaddr);
85 +
86 +       percpu_stats = this_cpu_ptr(priv->percpu_stats);
87 +       percpu_stats->rx_errors++;
88 +       ch->buf_count--;
89 +}
90 +#endif
91 +
92  /* Consume all frames pull-dequeued into the store. This is the simplest way to
93   * make sure we don't accidentally issue another volatile dequeue which would
94   * overwrite (leak) frames already in the store.
95 @@ -2351,6 +2398,7 @@ static void set_fq_affinity(struct dpaa2
96                 fq = &priv->fq[i];
97                 switch (fq->type) {
98                 case DPAA2_RX_FQ:
99 +               case DPAA2_RX_ERR_FQ:
100                         fq->target_cpu = rx_cpu;
101                         rx_cpu = cpumask_next(rx_cpu, &priv->dpio_cpumask);
102                         if (rx_cpu >= nr_cpu_ids)
103 @@ -2394,6 +2442,12 @@ static void setup_fqs(struct dpaa2_eth_p
104                 }
105         }
106  
107 +#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE
108 +       /* We have exactly one Rx error queue per DPNI */
109 +       priv->fq[priv->num_fqs].type = DPAA2_RX_ERR_FQ;
110 +       priv->fq[priv->num_fqs++].consume = dpaa2_eth_rx_err;
111 +#endif
112 +
113         /* For each FQ, decide on which core to process incoming frames */
114         set_fq_affinity(priv);
115  }
116 @@ -2939,6 +2993,40 @@ static int setup_tx_flow(struct dpaa2_et
117         return 0;
118  }
119  
120 +#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE
121 +static int setup_rx_err_flow(struct dpaa2_eth_priv *priv,
122 +                            struct dpaa2_eth_fq *fq)
123 +{
124 +       struct device *dev = priv->net_dev->dev.parent;
125 +       struct dpni_queue q = { { 0 } };
126 +       struct dpni_queue_id qid;
127 +       u8 q_opt = DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST;
128 +       int err;
129 +
130 +       err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
131 +                            DPNI_QUEUE_RX_ERR, 0, 0, &q, &qid);
132 +       if (err) {
133 +               dev_err(dev, "dpni_get_queue() failed (%d)\n", err);
134 +               return err;
135 +       }
136 +
137 +       fq->fqid = qid.fqid;
138 +
139 +       q.destination.id = fq->channel->dpcon_id;
140 +       q.destination.type = DPNI_DEST_DPCON;
141 +       q.destination.priority = 1;
142 +       q.user_context = (u64)fq;
143 +       err = dpni_set_queue(priv->mc_io, 0, priv->mc_token,
144 +                            DPNI_QUEUE_RX_ERR, 0, 0, q_opt, &q);
145 +       if (err) {
146 +               dev_err(dev, "dpni_set_queue() failed (%d)\n", err);
147 +               return err;
148 +       }
149 +
150 +       return 0;
151 +}
152 +#endif
153 +
154  /* Supported header fields for Rx hash distribution key */
155  static const struct dpaa2_eth_dist_fields dist_fields[] = {
156         {
157 @@ -3308,7 +3396,11 @@ static int bind_dpni(struct dpaa2_eth_pr
158         /* Configure handling of error frames */
159         err_cfg.errors = DPAA2_FAS_RX_ERR_MASK;
160         err_cfg.set_frame_annotation = 1;
161 +#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE
162 +       err_cfg.error_action = DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE;
163 +#else
164         err_cfg.error_action = DPNI_ERROR_ACTION_DISCARD;
165 +#endif
166         err = dpni_set_errors_behavior(priv->mc_io, 0, priv->mc_token,
167                                        &err_cfg);
168         if (err) {
169 @@ -3325,6 +3417,11 @@ static int bind_dpni(struct dpaa2_eth_pr
170                 case DPAA2_TX_CONF_FQ:
171                         err = setup_tx_flow(priv, &priv->fq[i]);
172                         break;
173 +#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE
174 +               case DPAA2_RX_ERR_FQ:
175 +                       err = setup_rx_err_flow(priv, &priv->fq[i]);
176 +                       break;
177 +#endif
178                 default:
179                         dev_err(dev, "Invalid FQ type %d\n", priv->fq[i].type);
180                         return -EINVAL;
181 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
182 +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
183 @@ -318,8 +318,10 @@ struct dpaa2_eth_ch_stats {
184  #define DPAA2_ETH_MAX_RX_QUEUES                \
185         (DPAA2_ETH_MAX_RX_QUEUES_PER_TC * DPAA2_ETH_MAX_TCS)
186  #define DPAA2_ETH_MAX_TX_QUEUES                16
187 +#define DPAA2_ETH_MAX_RX_ERR_QUEUES    1
188  #define DPAA2_ETH_MAX_QUEUES           (DPAA2_ETH_MAX_RX_QUEUES + \
189 -                                       DPAA2_ETH_MAX_TX_QUEUES)
190 +                                       DPAA2_ETH_MAX_TX_QUEUES + \
191 +                                       DPAA2_ETH_MAX_RX_ERR_QUEUES)
192  #define DPAA2_ETH_MAX_NETDEV_QUEUES    \
193         (DPAA2_ETH_MAX_TX_QUEUES * DPAA2_ETH_MAX_TCS)
194  
195 @@ -328,6 +330,7 @@ struct dpaa2_eth_ch_stats {
196  enum dpaa2_eth_fq_type {
197         DPAA2_RX_FQ = 0,
198         DPAA2_TX_CONF_FQ,
199 +       DPAA2_RX_ERR_FQ
200  };
201  
202  struct dpaa2_eth_priv;