Skip to content

Commit 4540c29

Browse files
macris-xiaokuba-moo
authored andcommitted
nfp: ethtool: support TX/RX pause frame on/off
Add support for ethtool -A tx on/off and rx on/off. Signed-off-by: Yu Xiao <yu.xiao@corigine.com> Signed-off-by: Louis Peens <louis.peens@corigine.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://lore.kernel.org/r/20231127055116.6668-1-louis.peens@corigine.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a379972 commit 4540c29

File tree

3 files changed

+124
-4
lines changed

3 files changed

+124
-4
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,6 +2235,30 @@ static int nfp_net_set_channels(struct net_device *netdev,
22352235
return nfp_net_set_num_rings(nn, total_rx, total_tx);
22362236
}
22372237

2238+
static int nfp_port_set_pauseparam(struct net_device *netdev,
2239+
struct ethtool_pauseparam *pause)
2240+
{
2241+
struct nfp_eth_table_port *eth_port;
2242+
struct nfp_port *port;
2243+
int err;
2244+
2245+
port = nfp_port_from_netdev(netdev);
2246+
eth_port = nfp_port_get_eth_port(port);
2247+
if (!eth_port)
2248+
return -EOPNOTSUPP;
2249+
2250+
if (pause->autoneg != AUTONEG_DISABLE)
2251+
return -EOPNOTSUPP;
2252+
2253+
err = nfp_eth_set_pauseparam(port->app->cpp, eth_port->index,
2254+
pause->tx_pause, pause->rx_pause);
2255+
if (!err)
2256+
/* Only refresh if we did something */
2257+
nfp_net_refresh_port_table(port);
2258+
2259+
return err < 0 ? err : 0;
2260+
}
2261+
22382262
static void nfp_port_get_pauseparam(struct net_device *netdev,
22392263
struct ethtool_pauseparam *pause)
22402264
{
@@ -2246,10 +2270,10 @@ static void nfp_port_get_pauseparam(struct net_device *netdev,
22462270
if (!eth_port)
22472271
return;
22482272

2249-
/* Currently pause frame support is fixed */
2273+
/* Currently pause frame autoneg is fixed */
22502274
pause->autoneg = AUTONEG_DISABLE;
2251-
pause->rx_pause = 1;
2252-
pause->tx_pause = 1;
2275+
pause->rx_pause = eth_port->rx_pause;
2276+
pause->tx_pause = eth_port->tx_pause;
22532277
}
22542278

22552279
static int nfp_net_set_phys_id(struct net_device *netdev,
@@ -2475,6 +2499,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
24752499
.set_link_ksettings = nfp_net_set_link_ksettings,
24762500
.get_fecparam = nfp_port_get_fecparam,
24772501
.set_fecparam = nfp_port_set_fecparam,
2502+
.set_pauseparam = nfp_port_set_pauseparam,
24782503
.get_pauseparam = nfp_port_get_pauseparam,
24792504
.set_phys_id = nfp_net_set_phys_id,
24802505
};
@@ -2499,6 +2524,7 @@ const struct ethtool_ops nfp_port_ethtool_ops = {
24992524
.set_link_ksettings = nfp_net_set_link_ksettings,
25002525
.get_fecparam = nfp_port_get_fecparam,
25012526
.set_fecparam = nfp_port_set_fecparam,
2527+
.set_pauseparam = nfp_port_set_pauseparam,
25022528
.get_pauseparam = nfp_port_get_pauseparam,
25032529
.set_phys_id = nfp_net_set_phys_id,
25042530
};

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ enum nfp_ethtool_link_mode_list {
189189
* @ports.enabled: is enabled?
190190
* @ports.tx_enabled: is TX enabled?
191191
* @ports.rx_enabled: is RX enabled?
192+
* @ports.rx_pause: Switch of RX pause frame
193+
* @ports.tx_pause: Switch of Tx pause frame
192194
* @ports.override_changed: is media reconfig pending?
193195
*
194196
* @ports.port_type: one of %PORT_* defines for ethtool
@@ -227,6 +229,8 @@ struct nfp_eth_table {
227229
bool tx_enabled;
228230
bool rx_enabled;
229231
bool supp_aneg;
232+
bool rx_pause;
233+
bool tx_pause;
230234

231235
bool override_changed;
232236

@@ -255,6 +259,8 @@ int
255259
nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode);
256260

257261
int nfp_eth_set_idmode(struct nfp_cpp *cpp, unsigned int idx, bool state);
262+
int nfp_eth_set_pauseparam(struct nfp_cpp *cpp, unsigned int idx,
263+
unsigned int tx_pause, unsigned int rx_pause);
258264

259265
static inline bool nfp_eth_can_support_fec(struct nfp_eth_table_port *eth_port)
260266
{

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23)
4343
#define NSP_ETH_STATE_FEC GENMASK_ULL(27, 26)
4444
#define NSP_ETH_STATE_ACT_FEC GENMASK_ULL(29, 28)
45+
#define NSP_ETH_STATE_TX_PAUSE BIT_ULL(31)
46+
#define NSP_ETH_STATE_RX_PAUSE BIT_ULL(32)
4547

4648
#define NSP_ETH_CTRL_CONFIGURED BIT_ULL(0)
4749
#define NSP_ETH_CTRL_ENABLED BIT_ULL(1)
@@ -52,6 +54,8 @@
5254
#define NSP_ETH_CTRL_SET_ANEG BIT_ULL(6)
5355
#define NSP_ETH_CTRL_SET_FEC BIT_ULL(7)
5456
#define NSP_ETH_CTRL_SET_IDMODE BIT_ULL(8)
57+
#define NSP_ETH_CTRL_SET_TX_PAUSE BIT_ULL(10)
58+
#define NSP_ETH_CTRL_SET_RX_PAUSE BIT_ULL(11)
5559

5660
enum nfp_eth_raw {
5761
NSP_ETH_RAW_PORT = 0,
@@ -180,6 +184,15 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,
180184

181185
dst->act_fec = FIELD_GET(NSP_ETH_STATE_ACT_FEC, state);
182186
dst->supp_aneg = FIELD_GET(NSP_ETH_PORT_SUPP_ANEG, port);
187+
188+
if (nfp_nsp_get_abi_ver_minor(nsp) < 37) {
189+
dst->tx_pause = true;
190+
dst->rx_pause = true;
191+
return;
192+
}
193+
194+
dst->tx_pause = FIELD_GET(NSP_ETH_STATE_TX_PAUSE, state);
195+
dst->rx_pause = FIELD_GET(NSP_ETH_STATE_RX_PAUSE, state);
183196
}
184197

185198
static void
@@ -497,7 +510,7 @@ int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, bool configed)
497510
static int
498511
nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int raw_idx,
499512
const u64 mask, const unsigned int shift,
500-
unsigned int val, const u64 ctrl_bit)
513+
u64 val, const u64 ctrl_bit)
501514
{
502515
union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
503516
unsigned int idx = nfp_nsp_config_idx(nsp);
@@ -629,6 +642,81 @@ nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode)
629642
return nfp_eth_config_commit_end(nsp);
630643
}
631644

645+
/**
646+
* __nfp_eth_set_txpause() - set tx pause control bit
647+
* @nsp: NFP NSP handle returned from nfp_eth_config_start()
648+
* @tx_pause: TX pause switch
649+
*
650+
* Set TX pause switch.
651+
*
652+
* Return: 0 or -ERRNO.
653+
*/
654+
static int __nfp_eth_set_txpause(struct nfp_nsp *nsp, unsigned int tx_pause)
655+
{
656+
return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE, NSP_ETH_STATE_TX_PAUSE,
657+
tx_pause, NSP_ETH_CTRL_SET_TX_PAUSE);
658+
}
659+
660+
/**
661+
* __nfp_eth_set_rxpause() - set rx pause control bit
662+
* @nsp: NFP NSP handle returned from nfp_eth_config_start()
663+
* @rx_pause: RX pause switch
664+
*
665+
* Set RX pause switch.
666+
*
667+
* Return: 0 or -ERRNO.
668+
*/
669+
static int __nfp_eth_set_rxpause(struct nfp_nsp *nsp, unsigned int rx_pause)
670+
{
671+
return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE, NSP_ETH_STATE_RX_PAUSE,
672+
rx_pause, NSP_ETH_CTRL_SET_RX_PAUSE);
673+
}
674+
675+
/**
676+
* nfp_eth_set_pauseparam() - Set TX/RX pause switch.
677+
* @cpp: NFP CPP handle
678+
* @idx: NFP chip-wide port index
679+
* @tx_pause: TX pause switch
680+
* @rx_pause: RX pause switch
681+
*
682+
* Return:
683+
* 0 - configuration successful;
684+
* 1 - no changes were needed;
685+
* -ERRNO - configuration failed.
686+
*/
687+
int
688+
nfp_eth_set_pauseparam(struct nfp_cpp *cpp, unsigned int idx,
689+
unsigned int tx_pause, unsigned int rx_pause)
690+
{
691+
struct nfp_nsp *nsp;
692+
int err;
693+
694+
nsp = nfp_eth_config_start(cpp, idx);
695+
if (IS_ERR(nsp))
696+
return PTR_ERR(nsp);
697+
698+
if (nfp_nsp_get_abi_ver_minor(nsp) < 37) {
699+
nfp_err(nfp_nsp_cpp(nsp),
700+
"set pause parameter operation not supported, please update flash\n");
701+
nfp_eth_config_cleanup_end(nsp);
702+
return -EOPNOTSUPP;
703+
}
704+
705+
err = __nfp_eth_set_txpause(nsp, tx_pause);
706+
if (err) {
707+
nfp_eth_config_cleanup_end(nsp);
708+
return err;
709+
}
710+
711+
err = __nfp_eth_set_rxpause(nsp, rx_pause);
712+
if (err) {
713+
nfp_eth_config_cleanup_end(nsp);
714+
return err;
715+
}
716+
717+
return nfp_eth_config_commit_end(nsp);
718+
}
719+
632720
/**
633721
* __nfp_eth_set_speed() - set interface speed/rate
634722
* @nsp: NFP NSP handle returned from nfp_eth_config_start()

0 commit comments

Comments
 (0)