xref: /linux/drivers/net/ethernet/mellanox/mlx5/core/en/channels.c (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */
3 
4 #include "channels.h"
5 #include "en.h"
6 #include "en/dim.h"
7 #include "en/ptp.h"
8 
mlx5e_channels_get_num(struct mlx5e_channels * chs)9 unsigned int mlx5e_channels_get_num(struct mlx5e_channels *chs)
10 {
11 	return chs->num;
12 }
13 
mlx5e_channels_get(struct mlx5e_channels * chs,unsigned int ix)14 static struct mlx5e_channel *mlx5e_channels_get(struct mlx5e_channels *chs, unsigned int ix)
15 {
16 	WARN_ON_ONCE(ix >= mlx5e_channels_get_num(chs));
17 	return chs->c[ix];
18 }
19 
mlx5e_channels_is_xsk(struct mlx5e_channels * chs,unsigned int ix)20 bool mlx5e_channels_is_xsk(struct mlx5e_channels *chs, unsigned int ix)
21 {
22 	struct mlx5e_channel *c = mlx5e_channels_get(chs, ix);
23 
24 	return test_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
25 }
26 
mlx5e_channels_get_regular_rqn(struct mlx5e_channels * chs,unsigned int ix,u32 * rqn,u32 * vhca_id)27 void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
28 				    u32 *vhca_id)
29 {
30 	struct mlx5e_channel *c = mlx5e_channels_get(chs, ix);
31 
32 	*rqn = c->rq.rqn;
33 	if (vhca_id)
34 		*vhca_id = MLX5_CAP_GEN(c->mdev, vhca_id);
35 }
36 
mlx5e_channels_get_xsk_rqn(struct mlx5e_channels * chs,unsigned int ix,u32 * rqn,u32 * vhca_id)37 void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
38 				u32 *vhca_id)
39 {
40 	struct mlx5e_channel *c = mlx5e_channels_get(chs, ix);
41 
42 	WARN_ON_ONCE(!test_bit(MLX5E_CHANNEL_STATE_XSK, c->state));
43 
44 	*rqn = c->xskrq.rqn;
45 	if (vhca_id)
46 		*vhca_id = MLX5_CAP_GEN(c->mdev, vhca_id);
47 }
48 
mlx5e_channels_get_ptp_rqn(struct mlx5e_channels * chs,u32 * rqn)49 bool mlx5e_channels_get_ptp_rqn(struct mlx5e_channels *chs, u32 *rqn)
50 {
51 	struct mlx5e_ptp *c = chs->ptp;
52 
53 	if (!c || !test_bit(MLX5E_PTP_STATE_RX, c->state))
54 		return false;
55 
56 	*rqn = c->rq.rqn;
57 	return true;
58 }
59 
mlx5e_channels_rx_change_dim(struct mlx5e_channels * chs,bool enable)60 int mlx5e_channels_rx_change_dim(struct mlx5e_channels *chs, bool enable)
61 {
62 	int i;
63 
64 	for (i = 0; i < chs->num; i++) {
65 		int err = mlx5e_dim_rx_change(&chs->c[i]->rq, enable);
66 
67 		if (err)
68 			return err;
69 	}
70 
71 	return 0;
72 }
73 
mlx5e_channels_tx_change_dim(struct mlx5e_channels * chs,bool enable)74 int mlx5e_channels_tx_change_dim(struct mlx5e_channels *chs, bool enable)
75 {
76 	int i, tc;
77 
78 	for (i = 0; i < chs->num; i++) {
79 		for (tc = 0; tc < mlx5e_get_dcb_num_tc(&chs->params); tc++) {
80 			int err = mlx5e_dim_tx_change(&chs->c[i]->sq[tc], enable);
81 
82 			if (err)
83 				return err;
84 		}
85 	}
86 
87 	return 0;
88 }
89 
mlx5e_channels_rx_toggle_dim(struct mlx5e_channels * chs)90 int mlx5e_channels_rx_toggle_dim(struct mlx5e_channels *chs)
91 {
92 	int i;
93 
94 	for (i = 0; i < chs->num; i++) {
95 		/* If dim is enabled for the channel, reset the dim state so the
96 		 * collected statistics will be reset. This is useful for
97 		 * supporting legacy interfaces that allow things like changing
98 		 * the CQ period mode for all channels without disturbing
99 		 * individual channel configurations.
100 		 */
101 		if (chs->c[i]->rq.dim) {
102 			int err;
103 
104 			mlx5e_dim_rx_change(&chs->c[i]->rq, false);
105 			err = mlx5e_dim_rx_change(&chs->c[i]->rq, true);
106 			if (err)
107 				return err;
108 		}
109 	}
110 
111 	return 0;
112 }
113 
mlx5e_channels_tx_toggle_dim(struct mlx5e_channels * chs)114 int mlx5e_channels_tx_toggle_dim(struct mlx5e_channels *chs)
115 {
116 	int i, tc;
117 
118 	for (i = 0; i < chs->num; i++) {
119 		for (tc = 0; tc < mlx5e_get_dcb_num_tc(&chs->params); tc++) {
120 			int err;
121 
122 			/* If dim is enabled for the channel, reset the dim
123 			 * state so the collected statistics will be reset. This
124 			 * is useful for supporting legacy interfaces that allow
125 			 * things like changing the CQ period mode for all
126 			 * channels without disturbing individual channel
127 			 * configurations.
128 			 */
129 			if (!chs->c[i]->sq[tc].dim)
130 				continue;
131 
132 			mlx5e_dim_tx_change(&chs->c[i]->sq[tc], false);
133 			err = mlx5e_dim_tx_change(&chs->c[i]->sq[tc], true);
134 			if (err)
135 				return err;
136 		}
137 	}
138 
139 	return 0;
140 }
141