65d81f337da5de8126923f1b323012ef3fc6881d
[openwrt/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch
1 From 7a342f60e569047e1632f6af91f503993769a2ec Mon Sep 17 00:00:00 2001
2 From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
3 Date: Tue, 17 Sep 2019 19:51:15 +0300
4 Subject: [PATCH] dpaa2-eth: Enable Rx PFC
5
6 Instruct the hardware to respond to received PFC frames.
7
8 Current firmware doesn't allow us to selectively enable PFC
9 on the Rx side for some priorities only, so we will react to
10 all incoming PFC frames (and stop transmitting on the traffic
11 classes specified in the frame).
12
13 PFC depends on the PAUSE flag also being set in link options.
14 Don't set it implicitly when user configures PFC, but issue
15 a warning if the two settings are not in sync.
16
17 For the Tx side, setting the PFC_PAUSE flag in the link options
18 is necessary but not sufficient, so PFC frame generation is
19 not enabled yet.
20
21 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
22 ---
23 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 23 +++++++++++++++++++++++
24 drivers/net/ethernet/freescale/dpaa2/dpni.h | 5 +++++
25 2 files changed, 28 insertions(+)
26
27 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
28 +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
29 @@ -3618,6 +3618,9 @@ static int dpaa2_eth_dcbnl_ieee_getpfc(s
30 {
31 struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
32
33 + if (!(priv->link_state.options & DPNI_LINK_OPT_PFC_PAUSE))
34 + return 0;
35 +
36 memcpy(pfc, &priv->pfc, sizeof(priv->pfc));
37 pfc->pfc_cap = dpaa2_eth_tc_count(priv);
38
39 @@ -3628,6 +3631,8 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s
40 struct ieee_pfc *pfc)
41 {
42 struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
43 + struct dpni_link_cfg link_cfg = {0};
44 + int err;
45
46 if (pfc->mbc || pfc->delay)
47 return -EOPNOTSUPP;
48 @@ -3636,6 +3641,24 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s
49 if (priv->pfc.pfc_en == pfc->pfc_en)
50 return 0;
51
52 + /* We allow PFC configuration even if it won't have any effect until
53 + * general pause frames are enabled
54 + */
55 + if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options))
56 + netdev_warn(net_dev, "Pause support must be enabled in order for PFC to work!\n");
57 +
58 + link_cfg.rate = priv->link_state.rate;
59 + link_cfg.options = priv->link_state.options;
60 + if (pfc->pfc_en)
61 + link_cfg.options |= DPNI_LINK_OPT_PFC_PAUSE;
62 + else
63 + link_cfg.options &= ~DPNI_LINK_OPT_PFC_PAUSE;
64 + err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &link_cfg);
65 + if (err) {
66 + netdev_err(net_dev, "dpni_set_link_cfg failed\n");
67 + return err;
68 + }
69 +
70 memcpy(&priv->pfc, pfc, sizeof(priv->pfc));
71
72 return 0;
73 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.h
74 +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h
75 @@ -514,6 +514,11 @@ int dpni_get_statistics(struct fsl_mc_io
76 #define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
77
78 /**
79 + * Enable priority flow control pause frames
80 + */
81 +#define DPNI_LINK_OPT_PFC_PAUSE 0x0000000000000010ULL
82 +
83 +/**
84 * struct - Structure representing DPNI link configuration
85 * @rate: Rate
86 * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values