ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch
1 From 07fb72fb5b3d2faeeb742ae573aa54a4a1eeee12 Mon Sep 17 00:00:00 2001
2 From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
3 Date: Tue, 17 Sep 2019 20:36:08 +0300
4 Subject: [PATCH] dpaa2-eth: Enable Tx PFC
5
6 Configure the hardware to generate PFC frames based on Rx congestion
7 notifications. When a certain number of frames accumulate in the
8 ingress queues corresponding to a traffic class, priority flow control
9 frames are generated for that TC.
10
11 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
12 ---
13  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 49 ++++++++++++++++++++-
14  drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 11 +++++
15  drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h  | 25 +++++++++++
16  drivers/net/ethernet/freescale/dpaa2/dpni.c      | 46 +++++++++++++++++++
17  drivers/net/ethernet/freescale/dpaa2/dpni.h      | 56 ++++++++++++++++++++++++
18  5 files changed, 186 insertions(+), 1 deletion(-)
19
20 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
21 +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
22 @@ -3622,6 +3622,47 @@ static int dpaa2_eth_dcbnl_ieee_getpfc(s
23         return 0;
24  }
25  
26 +static inline bool is_prio_enabled(u8 pfc_en, u8 tc)
27 +{
28 +       return !!(pfc_en & (1 << tc));
29 +}
30 +
31 +static int set_pfc_cn(struct dpaa2_eth_priv *priv, u8 pfc_en)
32 +{
33 +       struct dpni_congestion_notification_cfg cfg = {0};
34 +       int i, err;
35 +
36 +       cfg.notification_mode = DPNI_CONG_OPT_FLOW_CONTROL;
37 +       cfg.units = DPNI_CONGESTION_UNIT_FRAMES;
38 +       cfg.message_iova = 0ULL;
39 +       cfg.message_ctx = 0ULL;
40 +
41 +       for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
42 +               if (is_prio_enabled(pfc_en, i)) {
43 +                       cfg.threshold_entry = DPAA2_ETH_CN_THRESH_ENTRY(priv);
44 +                       cfg.threshold_exit = DPAA2_ETH_CN_THRESH_EXIT(priv);
45 +               } else {
46 +                       /* For priorities not set in the pfc_en mask, we leave
47 +                        * the congestion thresholds at zero, which effectively
48 +                        * disables generation of PFC frames for them
49 +                        */
50 +                       cfg.threshold_entry = 0;
51 +                       cfg.threshold_exit = 0;
52 +               }
53 +
54 +               err = dpni_set_congestion_notification(priv->mc_io, 0,
55 +                                                      priv->mc_token,
56 +                                                      DPNI_QUEUE_RX, i, &cfg);
57 +               if (err) {
58 +                       netdev_err(priv->net_dev,
59 +                                  "dpni_set_congestion_notification failed\n");
60 +                       return err;
61 +               }
62 +       }
63 +
64 +       return 0;
65 +}
66 +
67  static int dpaa2_eth_dcbnl_ieee_setpfc(struct net_device *net_dev,
68                                        struct ieee_pfc *pfc)
69  {
70 @@ -3639,7 +3680,8 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s
71         /* We allow PFC configuration even if it won't have any effect until
72          * general pause frames are enabled
73          */
74 -       if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options))
75 +       if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options) ||
76 +           !dpaa2_eth_tx_pause_enabled(priv->link_state.options))
77                 netdev_warn(net_dev, "Pause support must be enabled in order for PFC to work!\n");
78  
79         link_cfg.rate = priv->link_state.rate;
80 @@ -3654,6 +3696,11 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s
81                 return err;
82         }
83  
84 +       /* Configure congestion notifications for the enabled priorities */
85 +       err = set_pfc_cn(priv, pfc->pfc_en);
86 +       if (err)
87 +               return err;
88 +
89         memcpy(&priv->pfc, pfc, sizeof(priv->pfc));
90  
91         return 0;
92 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
93 +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
94 @@ -65,6 +65,17 @@
95  #define DPAA2_ETH_CG_TAILDROP_THRESH(priv)                             \
96         (1024 * dpaa2_eth_queue_count(priv) / dpaa2_eth_tc_count(priv))
97  
98 +/* Congestion group notification threshold: when this many frames accumulate
99 + * on the Rx queues belonging to the same TC, the MAC is instructed to send
100 + * PFC frames for that TC.
101 + * When number of pending frames drops below exit threshold transmission of
102 + * PFC frames is stopped.
103 + */
104 +#define DPAA2_ETH_CN_THRESH_ENTRY(priv) \
105 +       (DPAA2_ETH_CG_TAILDROP_THRESH(priv) / 2)
106 +#define DPAA2_ETH_CN_THRESH_EXIT(priv) \
107 +       (DPAA2_ETH_CN_THRESH_ENTRY(priv) * 3 / 4)
108 +
109  /* Maximum number of buffers that can be acquired/released through a single
110   * QBMan command
111   */
112 --- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
113 +++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
114 @@ -601,4 +601,29 @@ struct dpni_cmd_remove_qos_entry {
115         __le64 mask_iova;
116  };
117  
118 +#define DPNI_DEST_TYPE_SHIFT           0
119 +#define DPNI_DEST_TYPE_SIZE            4
120 +#define DPNI_CONG_UNITS_SHIFT          4
121 +#define DPNI_CONG_UNITS_SIZE           2
122 +
123 +struct dpni_cmd_set_congestion_notification {
124 +       /* cmd word 0 */
125 +       u8 qtype;
126 +       u8 tc;
127 +       u8 pad[6];
128 +       /* cmd word 1 */
129 +       __le32 dest_id;
130 +       __le16 notification_mode;
131 +       u8 dest_priority;
132 +       /* from LSB: dest_type: 4 units:2 */
133 +       u8 type_units;
134 +       /* cmd word 2 */
135 +       __le64 message_iova;
136 +       /* cmd word 3 */
137 +       __le64 message_ctx;
138 +       /* cmd word 4 */
139 +       __le32 threshold_entry;
140 +       __le32 threshold_exit;
141 +};
142 +
143  #endif /* _FSL_DPNI_CMD_H */
144 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
145 +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
146 @@ -1355,6 +1355,52 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io
147  }
148  
149  /**
150 + * dpni_set_congestion_notification() - Set traffic class congestion
151 + *                                     notification configuration
152 + * @mc_io:     Pointer to MC portal's I/O object
153 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
154 + * @token:     Token of DPNI object
155 + * @qtype:     Type of queue - Rx, Tx and Tx confirm types are supported
156 + * @tc_id:     Traffic class selection (0-7)
157 + * @cfg:       Congestion notification configuration
158 + *
159 + * Return:     '0' on Success; error code otherwise.
160 + */
161 +int dpni_set_congestion_notification(
162 +                       struct fsl_mc_io *mc_io,
163 +                       u32 cmd_flags,
164 +                       u16 token,
165 +                       enum dpni_queue_type qtype,
166 +                       u8 tc_id,
167 +                       const struct dpni_congestion_notification_cfg *cfg)
168 +{
169 +       struct dpni_cmd_set_congestion_notification *cmd_params;
170 +       struct fsl_mc_command cmd = { 0 };
171 +
172 +       /* prepare command */
173 +       cmd.header =
174 +               mc_encode_cmd_header(DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
175 +                                    cmd_flags,
176 +                                    token);
177 +       cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
178 +       cmd_params->qtype = qtype;
179 +       cmd_params->tc = tc_id;
180 +       cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
181 +       cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
182 +       cmd_params->dest_priority = cfg->dest_cfg.priority;
183 +       dpni_set_field(cmd_params->type_units, DEST_TYPE,
184 +                      cfg->dest_cfg.dest_type);
185 +       dpni_set_field(cmd_params->type_units, CONG_UNITS, cfg->units);
186 +       cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
187 +       cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
188 +       cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
189 +       cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
190 +
191 +       /* send command to mc*/
192 +       return mc_send_command(mc_io, &cmd);
193 +}
194 +
195 +/**
196   * dpni_set_queue() - Set queue parameters
197   * @mc_io:     Pointer to MC portal's I/O object
198   * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
199 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.h
200 +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h
201 @@ -883,6 +883,62 @@ enum dpni_congestion_point {
202  };
203  
204  /**
205 + * struct dpni_dest_cfg - Structure representing DPNI destination parameters
206 + * @dest_type: Destination type
207 + * @dest_id:   Either DPIO ID or DPCON ID, depending on the destination type
208 + * @priority:  Priority selection within the DPIO or DPCON channel; valid
209 + *             values are 0-1 or 0-7, depending on the number of priorities
210 + *             in that channel; not relevant for 'DPNI_DEST_NONE' option
211 + */
212 +struct dpni_dest_cfg {
213 +       enum dpni_dest dest_type;
214 +       int dest_id;
215 +       u8 priority;
216 +};
217 +
218 +/* DPNI congestion options */
219 +
220 +/**
221 + * This congestion will trigger flow control or priority flow control.
222 + * This will have effect only if flow control is enabled with
223 + * dpni_set_link_cfg().
224 + */
225 +#define DPNI_CONG_OPT_FLOW_CONTROL             0x00000040
226 +
227 +/**
228 + * struct dpni_congestion_notification_cfg - congestion notification
229 + *                                     configuration
230 + * @units: Units type
231 + * @threshold_entry: Above this threshold we enter a congestion state.
232 + *             set it to '0' to disable it
233 + * @threshold_exit: Below this threshold we exit the congestion state.
234 + * @message_ctx: The context that will be part of the CSCN message
235 + * @message_iova: I/O virtual address (must be in DMA-able memory),
236 + *             must be 16B aligned; valid only if 'DPNI_CONG_OPT_WRITE_MEM_<X>'
237 + *             is contained in 'options'
238 + * @dest_cfg: CSCN can be send to either DPIO or DPCON WQ channel
239 + * @notification_mode: Mask of available options; use 'DPNI_CONG_OPT_<X>' values
240 + */
241 +
242 +struct dpni_congestion_notification_cfg {
243 +       enum dpni_congestion_unit units;
244 +       u32 threshold_entry;
245 +       u32 threshold_exit;
246 +       u64 message_ctx;
247 +       u64 message_iova;
248 +       struct dpni_dest_cfg dest_cfg;
249 +       u16 notification_mode;
250 +};
251 +
252 +int dpni_set_congestion_notification(
253 +                       struct fsl_mc_io *mc_io,
254 +                       u32 cmd_flags,
255 +                       u16 token,
256 +                       enum dpni_queue_type qtype,
257 +                       u8 tc_id,
258 +                       const struct dpni_congestion_notification_cfg *cfg);
259 +
260 +/**
261   * struct dpni_taildrop - Structure representing the taildrop
262   * @enable:    Indicates whether the taildrop is active or not.
263   * @units:     Indicates the unit of THRESHOLD. Queue taildrop only supports