]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/octeontx2/otx2_flow_ctrl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include "otx2_ethdev.h"
8 otx2_nix_rxchan_bpid_cfg(struct rte_eth_dev
*eth_dev
, bool enb
)
10 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
11 struct otx2_fc_info
*fc
= &dev
->fc_info
;
12 struct otx2_mbox
*mbox
= dev
->mbox
;
13 struct nix_bp_cfg_req
*req
;
14 struct nix_bp_cfg_rsp
*rsp
;
17 if (otx2_dev_is_sdp(dev
))
21 req
= otx2_mbox_alloc_msg_nix_bp_enable(mbox
);
24 req
->bpid_per_chan
= 0;
26 rc
= otx2_mbox_process_msg(mbox
, (void *)&rsp
);
27 if (rc
|| req
->chan_cnt
!= rsp
->chan_cnt
) {
28 otx2_err("Insufficient BPIDs, alloc=%u < req=%u rc=%d",
29 rsp
->chan_cnt
, req
->chan_cnt
, rc
);
33 fc
->bpid
[0] = rsp
->chan_bpid
[0];
35 req
= otx2_mbox_alloc_msg_nix_bp_disable(mbox
);
39 rc
= otx2_mbox_process(mbox
);
41 memset(fc
->bpid
, 0, sizeof(uint16_t) * NIX_MAX_CHAN
);
48 otx2_nix_flow_ctrl_get(struct rte_eth_dev
*eth_dev
,
49 struct rte_eth_fc_conf
*fc_conf
)
51 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
52 struct cgx_pause_frm_cfg
*req
, *rsp
;
53 struct otx2_mbox
*mbox
= dev
->mbox
;
56 if (otx2_dev_is_lbk(dev
)) {
57 fc_conf
->mode
= RTE_FC_NONE
;
61 req
= otx2_mbox_alloc_msg_cgx_cfg_pause_frm(mbox
);
64 rc
= otx2_mbox_process_msg(mbox
, (void *)&rsp
);
68 if (rsp
->rx_pause
&& rsp
->tx_pause
)
69 fc_conf
->mode
= RTE_FC_FULL
;
70 else if (rsp
->rx_pause
)
71 fc_conf
->mode
= RTE_FC_RX_PAUSE
;
72 else if (rsp
->tx_pause
)
73 fc_conf
->mode
= RTE_FC_TX_PAUSE
;
75 fc_conf
->mode
= RTE_FC_NONE
;
82 otx2_nix_cq_bp_cfg(struct rte_eth_dev
*eth_dev
, bool enb
)
84 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
85 struct otx2_fc_info
*fc
= &dev
->fc_info
;
86 struct otx2_mbox
*mbox
= dev
->mbox
;
87 struct nix_aq_enq_req
*aq
;
88 struct otx2_eth_rxq
*rxq
;
91 for (i
= 0; i
< eth_dev
->data
->nb_rx_queues
; i
++) {
92 rxq
= eth_dev
->data
->rx_queues
[i
];
94 aq
= otx2_mbox_alloc_msg_nix_aq_enq(mbox
);
96 /* The shared memory buffer can be full.
99 otx2_mbox_msg_send(mbox
, 0);
100 rc
= otx2_mbox_wait_for_rsp(mbox
, 0);
104 aq
= otx2_mbox_alloc_msg_nix_aq_enq(mbox
);
109 aq
->ctype
= NIX_AQ_CTYPE_CQ
;
110 aq
->op
= NIX_AQ_INSTOP_WRITE
;
113 aq
->cq
.bpid
= fc
->bpid
[0];
114 aq
->cq_mask
.bpid
= ~(aq
->cq_mask
.bpid
);
115 aq
->cq
.bp
= rxq
->cq_drop
;
116 aq
->cq_mask
.bp
= ~(aq
->cq_mask
.bp
);
119 aq
->cq
.bp_ena
= !!enb
;
120 aq
->cq_mask
.bp_ena
= ~(aq
->cq_mask
.bp_ena
);
123 otx2_mbox_msg_send(mbox
, 0);
124 rc
= otx2_mbox_wait_for_rsp(mbox
, 0);
132 otx2_nix_rx_fc_cfg(struct rte_eth_dev
*eth_dev
, bool enb
)
134 return otx2_nix_cq_bp_cfg(eth_dev
, enb
);
138 otx2_nix_flow_ctrl_set(struct rte_eth_dev
*eth_dev
,
139 struct rte_eth_fc_conf
*fc_conf
)
141 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
142 struct otx2_fc_info
*fc
= &dev
->fc_info
;
143 struct otx2_mbox
*mbox
= dev
->mbox
;
144 struct cgx_pause_frm_cfg
*req
;
145 uint8_t tx_pause
, rx_pause
;
148 if (otx2_dev_is_lbk(dev
)) {
149 otx2_info("No flow control support for LBK bound ethports");
153 if (fc_conf
->high_water
|| fc_conf
->low_water
|| fc_conf
->pause_time
||
154 fc_conf
->mac_ctrl_frame_fwd
|| fc_conf
->autoneg
) {
155 otx2_info("Flowctrl parameter is not supported");
159 if (fc_conf
->mode
== fc
->mode
)
162 rx_pause
= (fc_conf
->mode
== RTE_FC_FULL
) ||
163 (fc_conf
->mode
== RTE_FC_RX_PAUSE
);
164 tx_pause
= (fc_conf
->mode
== RTE_FC_FULL
) ||
165 (fc_conf
->mode
== RTE_FC_TX_PAUSE
);
167 /* Check if TX pause frame is already enabled or not */
168 if (fc
->tx_pause
^ tx_pause
) {
169 if (otx2_dev_is_Ax(dev
) && eth_dev
->data
->dev_started
) {
170 /* on Ax, CQ should be in disabled state
171 * while setting flow control configuration.
173 otx2_info("Stop the port=%d for setting flow control\n",
174 eth_dev
->data
->port_id
);
177 /* TX pause frames, enable/disable flowctrl on RX side. */
178 rc
= otx2_nix_rx_fc_cfg(eth_dev
, tx_pause
);
183 req
= otx2_mbox_alloc_msg_cgx_cfg_pause_frm(mbox
);
185 req
->rx_pause
= rx_pause
;
186 req
->tx_pause
= tx_pause
;
188 rc
= otx2_mbox_process(mbox
);
192 fc
->tx_pause
= tx_pause
;
193 fc
->rx_pause
= rx_pause
;
194 fc
->mode
= fc_conf
->mode
;
200 otx2_nix_update_flow_ctrl_mode(struct rte_eth_dev
*eth_dev
)
202 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
203 struct otx2_fc_info
*fc
= &dev
->fc_info
;
204 struct rte_eth_fc_conf fc_conf
;
206 if (otx2_dev_is_lbk(dev
) || otx2_dev_is_sdp(dev
))
209 memset(&fc_conf
, 0, sizeof(struct rte_eth_fc_conf
));
210 fc_conf
.mode
= fc
->mode
;
212 /* To avoid Link credit deadlock on Ax, disable Tx FC if it's enabled */
213 if (otx2_dev_is_Ax(dev
) &&
214 (dev
->npc_flow
.switch_header_type
!= OTX2_PRIV_FLAGS_HIGIG
) &&
215 (fc_conf
.mode
== RTE_FC_FULL
|| fc_conf
.mode
== RTE_FC_RX_PAUSE
)) {
217 (fc_conf
.mode
== RTE_FC_FULL
||
218 fc_conf
.mode
== RTE_FC_TX_PAUSE
) ?
219 RTE_FC_TX_PAUSE
: RTE_FC_NONE
;
222 return otx2_nix_flow_ctrl_set(eth_dev
, &fc_conf
);
226 otx2_nix_flow_ctrl_init(struct rte_eth_dev
*eth_dev
)
228 struct otx2_eth_dev
*dev
= otx2_eth_pmd_priv(eth_dev
);
229 struct otx2_fc_info
*fc
= &dev
->fc_info
;
230 struct rte_eth_fc_conf fc_conf
;
233 if (otx2_dev_is_lbk(dev
) || otx2_dev_is_sdp(dev
))
236 memset(&fc_conf
, 0, sizeof(struct rte_eth_fc_conf
));
237 /* Both Rx & Tx flow ctrl get enabled(RTE_FC_FULL) in HW
238 * by AF driver, update those info in PMD structure.
240 rc
= otx2_nix_flow_ctrl_get(eth_dev
, &fc_conf
);
244 fc
->mode
= fc_conf
.mode
;
245 fc
->rx_pause
= (fc_conf
.mode
== RTE_FC_FULL
) ||
246 (fc_conf
.mode
== RTE_FC_RX_PAUSE
);
247 fc
->tx_pause
= (fc_conf
.mode
== RTE_FC_FULL
) ||
248 (fc_conf
.mode
== RTE_FC_TX_PAUSE
);