Skip to content

Commit b79f91f

Browse files
committed
Merge branch 'net-atlantic-QoS-implementation'
Igor Russkikh says: ==================== net: atlantic: QoS implementation This patch series adds support for mqprio rate limiters and multi-TC: * max_rate is supported on both A1 and A2; * min_rate is supported on A2 only; This is a joint work of Mark and Dmitry. To implement this feature, a couple of rearrangements and code improvements were done, in areas of TC/ring management, allocation control, etc. One of the problems we faced is conflicting ptp functionality, which consumes a whole traffic class due to hardware limitations. Patches below have a more detailed description on how PTP and multi-TC co-exist right now. v2: * accommodated review comments (-Wmissing-prototypes and -Wunused-but-set-variable findings); * added user notification in case of conflicting multi-TC<->PTP configuration; * added automatic PTP disabling, if a conflicting configuration is detected; * removed module param, which was used for PTP disabling in v1; v1: https://patchwork.ozlabs.org/cover/1294380/ ==================== Acked-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents 59b8d27 + 40f05e5 commit b79f91f

26 files changed

+1197
-381
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
8888
"InDroppedDma",
8989
};
9090

91-
static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
92-
"Queue[%d] InPackets",
93-
"Queue[%d] OutPackets",
94-
"Queue[%d] Restarts",
95-
"Queue[%d] InJumboPackets",
96-
"Queue[%d] InLroPackets",
97-
"Queue[%d] InErrors",
91+
static const char * const aq_ethtool_queue_stat_names[] = {
92+
"%sQueue[%d] InPackets",
93+
"%sQueue[%d] OutPackets",
94+
"%sQueue[%d] Restarts",
95+
"%sQueue[%d] InJumboPackets",
96+
"%sQueue[%d] InLroPackets",
97+
"%sQueue[%d] InErrors",
9898
};
9999

100100
#if IS_ENABLED(CONFIG_MACSEC)
@@ -166,7 +166,8 @@ static u32 aq_ethtool_n_stats(struct net_device *ndev)
166166
struct aq_nic_s *nic = netdev_priv(ndev);
167167
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
168168
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
169-
ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;
169+
ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs *
170+
cfg->tcs;
170171

171172
#if IS_ENABLED(CONFIG_MACSEC)
172173
if (nic->macsec_cfg) {
@@ -223,40 +224,51 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
223224
static void aq_ethtool_get_strings(struct net_device *ndev,
224225
u32 stringset, u8 *data)
225226
{
226-
struct aq_nic_s *aq_nic = netdev_priv(ndev);
227+
struct aq_nic_s *nic = netdev_priv(ndev);
227228
struct aq_nic_cfg_s *cfg;
228229
u8 *p = data;
229230
int i, si;
230231
#if IS_ENABLED(CONFIG_MACSEC)
231232
int sa;
232233
#endif
233234

234-
cfg = aq_nic_get_cfg(aq_nic);
235+
cfg = aq_nic_get_cfg(nic);
235236

236237
switch (stringset) {
237-
case ETH_SS_STATS:
238+
case ETH_SS_STATS: {
239+
const int stat_cnt = ARRAY_SIZE(aq_ethtool_queue_stat_names);
240+
char tc_string[8];
241+
int tc;
242+
243+
memset(tc_string, 0, sizeof(tc_string));
238244
memcpy(p, aq_ethtool_stat_names,
239245
sizeof(aq_ethtool_stat_names));
240246
p = p + sizeof(aq_ethtool_stat_names);
241-
for (i = 0; i < cfg->vecs; i++) {
242-
for (si = 0;
243-
si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
244-
si++) {
245-
snprintf(p, ETH_GSTRING_LEN,
246-
aq_ethtool_queue_stat_names[si], i);
247-
p += ETH_GSTRING_LEN;
247+
248+
for (tc = 0; tc < cfg->tcs; tc++) {
249+
if (cfg->is_qos)
250+
snprintf(tc_string, 8, "TC%d ", tc);
251+
252+
for (i = 0; i < cfg->vecs; i++) {
253+
for (si = 0; si < stat_cnt; si++) {
254+
snprintf(p, ETH_GSTRING_LEN,
255+
aq_ethtool_queue_stat_names[si],
256+
tc_string,
257+
AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
258+
p += ETH_GSTRING_LEN;
259+
}
248260
}
249261
}
250262
#if IS_ENABLED(CONFIG_MACSEC)
251-
if (!aq_nic->macsec_cfg)
263+
if (!nic->macsec_cfg)
252264
break;
253265

254266
memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
255267
p = p + sizeof(aq_macsec_stat_names);
256268
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
257269
struct aq_macsec_txsc *aq_txsc;
258270

259-
if (!(test_bit(i, &aq_nic->macsec_cfg->txsc_idx_busy)))
271+
if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
260272
continue;
261273

262274
for (si = 0;
@@ -266,7 +278,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
266278
aq_macsec_txsc_stat_names[si], i);
267279
p += ETH_GSTRING_LEN;
268280
}
269-
aq_txsc = &aq_nic->macsec_cfg->aq_txsc[i];
281+
aq_txsc = &nic->macsec_cfg->aq_txsc[i];
270282
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
271283
if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
272284
continue;
@@ -283,10 +295,10 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
283295
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
284296
struct aq_macsec_rxsc *aq_rxsc;
285297

286-
if (!(test_bit(i, &aq_nic->macsec_cfg->rxsc_idx_busy)))
298+
if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
287299
continue;
288300

289-
aq_rxsc = &aq_nic->macsec_cfg->aq_rxsc[i];
301+
aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
290302
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
291303
if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
292304
continue;
@@ -302,6 +314,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
302314
}
303315
#endif
304316
break;
317+
}
305318
case ETH_SS_PRIV_FLAGS:
306319
memcpy(p, aq_ethtool_priv_flag_names,
307320
sizeof(aq_ethtool_priv_flag_names));
@@ -780,8 +793,6 @@ static int aq_set_ringparam(struct net_device *ndev,
780793
dev_close(ndev);
781794
}
782795

783-
aq_nic_free_vectors(aq_nic);
784-
785796
cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
786797
cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
787798
cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
@@ -790,15 +801,10 @@ static int aq_set_ringparam(struct net_device *ndev,
790801
cfg->txds = min(cfg->txds, hw_caps->txds_max);
791802
cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
792803

793-
for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < cfg->vecs;
794-
aq_nic->aq_vecs++) {
795-
aq_nic->aq_vec[aq_nic->aq_vecs] =
796-
aq_vec_alloc(aq_nic, aq_nic->aq_vecs, cfg);
797-
if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
798-
err = -ENOMEM;
799-
goto err_exit;
800-
}
801-
}
804+
err = aq_nic_realloc_vectors(aq_nic);
805+
if (err)
806+
goto err_exit;
807+
802808
if (ndev_running)
803809
err = dev_open(ndev, NULL);
804810

drivers/net/ethernet/aquantia/atlantic/aq_filters.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic,
153153
struct aq_hw_rx_fltrs_s *rx_fltrs,
154154
struct ethtool_rx_flow_spec *fsp)
155155
{
156+
struct aq_nic_cfg_s *cfg = &aq_nic->aq_nic_cfg;
157+
156158
if (fsp->location < AQ_RX_FIRST_LOC_FVLANID ||
157159
fsp->location > AQ_RX_LAST_LOC_FVLANID) {
158160
netdev_err(aq_nic->ndev,
@@ -170,10 +172,10 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic,
170172
return -EINVAL;
171173
}
172174

173-
if (fsp->ring_cookie > aq_nic->aq_nic_cfg.num_rss_queues) {
175+
if (fsp->ring_cookie > cfg->num_rss_queues * cfg->tcs) {
174176
netdev_err(aq_nic->ndev,
175177
"ethtool: queue number must be in range [0, %d]",
176-
aq_nic->aq_nic_cfg.num_rss_queues - 1);
178+
cfg->num_rss_queues * cfg->tcs - 1);
177179
return -EINVAL;
178180
}
179181
return 0;
@@ -262,6 +264,7 @@ static bool __must_check
262264
aq_rule_is_not_correct(struct aq_nic_s *aq_nic,
263265
struct ethtool_rx_flow_spec *fsp)
264266
{
267+
struct aq_nic_cfg_s *cfg = &aq_nic->aq_nic_cfg;
265268
bool rule_is_not_correct = false;
266269

267270
if (!aq_nic) {
@@ -274,11 +277,11 @@ aq_rule_is_not_correct(struct aq_nic_s *aq_nic,
274277
} else if (aq_check_filter(aq_nic, fsp)) {
275278
rule_is_not_correct = true;
276279
} else if (fsp->ring_cookie != RX_CLS_FLOW_DISC) {
277-
if (fsp->ring_cookie >= aq_nic->aq_nic_cfg.num_rss_queues) {
280+
if (fsp->ring_cookie >= cfg->num_rss_queues * cfg->tcs) {
278281
netdev_err(aq_nic->ndev,
279282
"ethtool: The specified action is invalid.\n"
280283
"Maximum allowable value action is %u.\n",
281-
aq_nic->aq_nic_cfg.num_rss_queues - 1);
284+
cfg->num_rss_queues * cfg->tcs - 1);
282285
rule_is_not_correct = true;
283286
}
284287
}

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#define AQ_HW_MAC_COUNTER_HZ 312500000ll
1919
#define AQ_HW_PHY_COUNTER_HZ 160000000ll
2020

21+
enum aq_tc_mode {
22+
AQ_TC_MODE_INVALID = -1,
23+
AQ_TC_MODE_8TCS,
24+
AQ_TC_MODE_4TCS,
25+
};
26+
2127
#define AQ_RX_FIRST_LOC_FVLANID 0U
2228
#define AQ_RX_LAST_LOC_FVLANID 15U
2329
#define AQ_RX_FIRST_LOC_FETHERT 16U
@@ -29,6 +35,9 @@
2935
(AQ_RX_LAST_LOC_FVLANID - AQ_RX_FIRST_LOC_FVLANID + 1U)
3036
#define AQ_RX_QUEUE_NOT_ASSIGNED 0xFFU
3137

38+
/* Used for rate to Mbps conversion */
39+
#define AQ_MBPS_DIVISOR 125000 /* 1000000 / 8 */
40+
3241
/* NIC H/W capabilities */
3342
struct aq_hw_caps_s {
3443
u64 hw_features;
@@ -46,7 +55,7 @@ struct aq_hw_caps_s {
4655
u32 mac_regs_count;
4756
u32 hw_alive_check_addr;
4857
u8 msix_irqs;
49-
u8 tcs;
58+
u8 tcs_max;
5059
u8 rxd_alignment;
5160
u8 rxd_size;
5261
u8 txd_alignment;
@@ -118,8 +127,11 @@ struct aq_stats_s {
118127
#define AQ_HW_TXD_MULTIPLE 8U
119128
#define AQ_HW_RXD_MULTIPLE 8U
120129

130+
#define AQ_HW_QUEUES_MAX 32U
121131
#define AQ_HW_MULTICAST_ADDRESS_MAX 32U
122132

133+
#define AQ_HW_PTP_TC 2U
134+
123135
#define AQ_HW_LED_BLINK 0x2U
124136
#define AQ_HW_LED_DEFAULT 0x0U
125137

@@ -268,6 +280,8 @@ struct aq_hw_ops {
268280
int (*hw_rss_hash_set)(struct aq_hw_s *self,
269281
struct aq_rss_parameters *rss_params);
270282

283+
int (*hw_tc_rate_limit_set)(struct aq_hw_s *self);
284+
271285
int (*hw_get_regs)(struct aq_hw_s *self,
272286
const struct aq_hw_caps_s *aq_hw_caps,
273287
u32 *regs_buff);
@@ -279,10 +293,6 @@ struct aq_hw_ops {
279293
int (*hw_set_offload)(struct aq_hw_s *self,
280294
struct aq_nic_cfg_s *aq_nic_cfg);
281295

282-
int (*hw_tx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);
283-
284-
int (*hw_rx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);
285-
286296
int (*hw_ring_hwts_rx_fill)(struct aq_hw_s *self,
287297
struct aq_ring_s *aq_ring);
288298

drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,29 @@ int aq_hw_err_from_flags(struct aq_hw_s *hw)
7979
err_exit:
8080
return err;
8181
}
82+
83+
int aq_hw_num_tcs(struct aq_hw_s *hw)
84+
{
85+
switch (hw->aq_nic_cfg->tc_mode) {
86+
case AQ_TC_MODE_8TCS:
87+
return 8;
88+
case AQ_TC_MODE_4TCS:
89+
return 4;
90+
default:
91+
break;
92+
}
93+
94+
return 1;
95+
}
96+
97+
int aq_hw_q_per_tc(struct aq_hw_s *hw)
98+
{
99+
switch (hw->aq_nic_cfg->tc_mode) {
100+
case AQ_TC_MODE_8TCS:
101+
return 4;
102+
case AQ_TC_MODE_4TCS:
103+
return 8;
104+
default:
105+
return 4;
106+
}
107+
}

drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
3434
void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
3535
u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
3636
int aq_hw_err_from_flags(struct aq_hw_s *hw);
37+
int aq_hw_num_tcs(struct aq_hw_s *hw);
38+
int aq_hw_q_per_tc(struct aq_hw_s *hw);
3739

3840
#endif /* AQ_HW_UTILS_H */

drivers/net/ethernet/aquantia/atlantic/aq_macsec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ static int aq_mdo_add_secy(struct macsec_context *ctx)
478478

479479
set_bit(txsc_idx, &cfg->txsc_idx_busy);
480480

481-
return 0;
481+
return ret;
482482
}
483483

484484
static int aq_mdo_upd_secy(struct macsec_context *ctx)

0 commit comments

Comments
 (0)