forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
....@@ -64,87 +64,28 @@
6464 return 0;
6565 }
6666
67
-static int mlxsw_sp_port_pg_prio_map(struct mlxsw_sp_port *mlxsw_sp_port,
68
- u8 *prio_tc)
67
+static int mlxsw_sp_port_headroom_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
68
+ struct ieee_ets *ets)
6969 {
70
- char pptb_pl[MLXSW_REG_PPTB_LEN];
71
- int i;
72
-
73
- mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port);
74
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
75
- mlxsw_reg_pptb_prio_to_buff_pack(pptb_pl, i, prio_tc[i]);
76
-
77
- return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb),
78
- pptb_pl);
79
-}
80
-
81
-static bool mlxsw_sp_ets_has_pg(u8 *prio_tc, u8 pg)
82
-{
83
- int i;
84
-
85
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
86
- if (prio_tc[i] == pg)
87
- return true;
88
- return false;
89
-}
90
-
91
-static int mlxsw_sp_port_pg_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
92
- u8 *old_prio_tc, u8 *new_prio_tc)
93
-{
94
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
95
- char pbmc_pl[MLXSW_REG_PBMC_LEN];
96
- int err, i;
97
-
98
- mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0, 0);
99
- err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
100
- if (err)
101
- return err;
102
-
103
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
104
- u8 pg = old_prio_tc[i];
105
-
106
- if (!mlxsw_sp_ets_has_pg(new_prio_tc, pg))
107
- mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, pg, 0);
108
- }
109
-
110
- return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
111
-}
112
-
113
-static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
114
- struct ieee_ets *ets)
115
-{
116
- bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
117
- struct ieee_ets *my_ets = mlxsw_sp_port->dcb.ets;
11870 struct net_device *dev = mlxsw_sp_port->dev;
71
+ struct mlxsw_sp_hdroom hdroom;
72
+ int prio;
11973 int err;
12074
121
- /* Create the required PGs, but don't destroy existing ones, as
122
- * traffic is still directed to them.
123
- */
124
- err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu,
125
- ets->prio_tc, pause_en,
126
- mlxsw_sp_port->dcb.pfc);
75
+ hdroom = *mlxsw_sp_port->hdroom;
76
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++)
77
+ hdroom.prios.prio[prio].ets_buf_idx = ets->prio_tc[prio];
78
+ mlxsw_sp_hdroom_prios_reset_buf_idx(&hdroom);
79
+ mlxsw_sp_hdroom_bufs_reset_lossiness(&hdroom);
80
+ mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom);
81
+
82
+ err = mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom);
12783 if (err) {
12884 netdev_err(dev, "Failed to configure port's headroom\n");
12985 return err;
13086 }
13187
132
- err = mlxsw_sp_port_pg_prio_map(mlxsw_sp_port, ets->prio_tc);
133
- if (err) {
134
- netdev_err(dev, "Failed to set PG-priority mapping\n");
135
- goto err_port_prio_pg_map;
136
- }
137
-
138
- err = mlxsw_sp_port_pg_destroy(mlxsw_sp_port, my_ets->prio_tc,
139
- ets->prio_tc);
140
- if (err)
141
- netdev_warn(dev, "Failed to remove ununsed PGs\n");
142
-
14388 return 0;
144
-
145
-err_port_prio_pg_map:
146
- mlxsw_sp_port_pg_destroy(mlxsw_sp_port, ets->prio_tc, my_ets->prio_tc);
147
- return err;
14889 }
14990
15091 static int __mlxsw_sp_dcbnl_ieee_setets(struct mlxsw_sp_port *mlxsw_sp_port,
....@@ -160,7 +101,7 @@
160101 u8 weight = ets->tc_tx_bw[i];
161102
162103 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
163
- MLXSW_REG_QEEC_HIERARCY_SUBGROUP, i,
104
+ MLXSW_REG_QEEC_HR_SUBGROUP, i,
164105 0, dwrr, weight);
165106 if (err) {
166107 netdev_err(dev, "Failed to link subgroup ETS element %d to group\n",
....@@ -180,7 +121,7 @@
180121 }
181122
182123 /* Ingress configuration. */
183
- err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, ets);
124
+ err = mlxsw_sp_port_headroom_ets_set(mlxsw_sp_port, ets);
184125 if (err)
185126 goto err_port_headroom_set;
186127
....@@ -198,7 +139,7 @@
198139 u8 weight = my_ets->tc_tx_bw[i];
199140
200141 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
201
- MLXSW_REG_QEEC_HIERARCY_SUBGROUP, i,
142
+ MLXSW_REG_QEEC_HR_SUBGROUP, i,
202143 0, dwrr, weight);
203144 }
204145 return err;
....@@ -227,8 +168,6 @@
227168 static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev,
228169 struct dcb_app *app)
229170 {
230
- int prio;
231
-
232171 if (app->priority >= IEEE_8021QAZ_MAX_TCS) {
233172 netdev_err(dev, "APP entry with priority value %u is invalid\n",
234173 app->priority);
....@@ -241,17 +180,6 @@
241180 netdev_err(dev, "DSCP APP entry with protocol value %u is invalid\n",
242181 app->protocol);
243182 return -EINVAL;
244
- }
245
-
246
- /* Warn about any DSCP APP entries with the same PID. */
247
- prio = fls(dcb_ieee_getapp_mask(dev, app));
248
- if (prio--) {
249
- if (prio < app->priority)
250
- netdev_warn(dev, "Choosing priority %d for DSCP %d in favor of previously-active value of %d\n",
251
- app->priority, app->protocol, prio);
252
- else if (prio > app->priority)
253
- netdev_warn(dev, "Ignoring new priority %d for DSCP %d in favor of current value of %d\n",
254
- app->priority, app->protocol, prio);
255183 }
256184 break;
257185
....@@ -369,6 +297,17 @@
369297 }
370298
371299 static int
300
+mlxsw_sp_port_dcb_app_update_qpdp(struct mlxsw_sp_port *mlxsw_sp_port,
301
+ u8 default_prio)
302
+{
303
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
304
+ char qpdp_pl[MLXSW_REG_QPDP_LEN];
305
+
306
+ mlxsw_reg_qpdp_pack(qpdp_pl, mlxsw_sp_port->local_port, default_prio);
307
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpdp), qpdp_pl);
308
+}
309
+
310
+static int
372311 mlxsw_sp_port_dcb_app_update_qpdpm(struct mlxsw_sp_port *mlxsw_sp_port,
373312 struct dcb_ieee_app_dscp_map *map)
374313 {
....@@ -405,6 +344,12 @@
405344 int err;
406345
407346 default_prio = mlxsw_sp_port_dcb_app_default_prio(mlxsw_sp_port);
347
+ err = mlxsw_sp_port_dcb_app_update_qpdp(mlxsw_sp_port, default_prio);
348
+ if (err) {
349
+ netdev_err(mlxsw_sp_port->dev, "Couldn't configure port default priority\n");
350
+ return err;
351
+ }
352
+
408353 have_dscp = mlxsw_sp_port_dcb_app_prio_dscp_map(mlxsw_sp_port,
409354 &prio_map);
410355
....@@ -507,9 +452,9 @@
507452
508453 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
509454 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
510
- MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
455
+ MLXSW_REG_QEEC_HR_SUBGROUP,
511456 i, 0,
512
- maxrate->tc_maxrate[i]);
457
+ maxrate->tc_maxrate[i], 0);
513458 if (err) {
514459 netdev_err(dev, "Failed to set maxrate for TC %d\n", i);
515460 goto err_port_ets_maxrate_set;
....@@ -523,8 +468,9 @@
523468 err_port_ets_maxrate_set:
524469 for (i--; i >= 0; i--)
525470 mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
526
- MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
527
- i, 0, my_maxrate->tc_maxrate[i]);
471
+ MLXSW_REG_QEEC_HR_SUBGROUP,
472
+ i, 0,
473
+ my_maxrate->tc_maxrate[i], 0);
528474 return err;
529475 }
530476
....@@ -587,6 +533,9 @@
587533 {
588534 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
589535 bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
536
+ struct mlxsw_sp_hdroom orig_hdroom;
537
+ struct mlxsw_sp_hdroom hdroom;
538
+ int prio;
590539 int err;
591540
592541 if (pause_en && pfc->pfc_en) {
....@@ -594,9 +543,21 @@
594543 return -EINVAL;
595544 }
596545
597
- err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu,
598
- mlxsw_sp_port->dcb.ets->prio_tc,
599
- pause_en, pfc);
546
+ orig_hdroom = *mlxsw_sp_port->hdroom;
547
+
548
+ hdroom = orig_hdroom;
549
+ if (pfc->pfc_en)
550
+ hdroom.delay_bytes = DIV_ROUND_UP(pfc->delay, BITS_PER_BYTE);
551
+ else
552
+ hdroom.delay_bytes = 0;
553
+
554
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++)
555
+ hdroom.prios.prio[prio].lossy = !(pfc->pfc_en & BIT(prio));
556
+
557
+ mlxsw_sp_hdroom_bufs_reset_lossiness(&hdroom);
558
+ mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom);
559
+
560
+ err = mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom);
600561 if (err) {
601562 netdev_err(dev, "Failed to configure port's headroom for PFC\n");
602563 return err;
....@@ -614,10 +575,64 @@
614575 return 0;
615576
616577 err_port_pfc_set:
617
- __mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu,
618
- mlxsw_sp_port->dcb.ets->prio_tc, pause_en,
619
- mlxsw_sp_port->dcb.pfc);
578
+ mlxsw_sp_hdroom_configure(mlxsw_sp_port, &orig_hdroom);
620579 return err;
580
+}
581
+
582
+static int mlxsw_sp_dcbnl_getbuffer(struct net_device *dev, struct dcbnl_buffer *buf)
583
+{
584
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
585
+ struct mlxsw_sp_hdroom *hdroom = mlxsw_sp_port->hdroom;
586
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
587
+ int prio;
588
+ int i;
589
+
590
+ buf->total_size = 0;
591
+
592
+ BUILD_BUG_ON(DCBX_MAX_BUFFERS > MLXSW_SP_PB_COUNT);
593
+ for (i = 0; i < MLXSW_SP_PB_COUNT; i++) {
594
+ u32 bytes = mlxsw_sp_cells_bytes(mlxsw_sp, hdroom->bufs.buf[i].size_cells);
595
+
596
+ if (i < DCBX_MAX_BUFFERS)
597
+ buf->buffer_size[i] = bytes;
598
+ buf->total_size += bytes;
599
+ }
600
+
601
+ buf->total_size += mlxsw_sp_cells_bytes(mlxsw_sp, hdroom->int_buf.size_cells);
602
+
603
+ for (prio = 0; prio < IEEE_8021Q_MAX_PRIORITIES; prio++)
604
+ buf->prio2buffer[prio] = hdroom->prios.prio[prio].buf_idx;
605
+
606
+ return 0;
607
+}
608
+
609
+static int mlxsw_sp_dcbnl_setbuffer(struct net_device *dev, struct dcbnl_buffer *buf)
610
+{
611
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
612
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
613
+ struct mlxsw_sp_hdroom hdroom;
614
+ int prio;
615
+ int i;
616
+
617
+ hdroom = *mlxsw_sp_port->hdroom;
618
+
619
+ if (hdroom.mode != MLXSW_SP_HDROOM_MODE_TC) {
620
+ netdev_err(dev, "The use of dcbnl_setbuffer is only allowed if egress is configured using TC\n");
621
+ return -EINVAL;
622
+ }
623
+
624
+ for (prio = 0; prio < IEEE_8021Q_MAX_PRIORITIES; prio++)
625
+ hdroom.prios.prio[prio].set_buf_idx = buf->prio2buffer[prio];
626
+
627
+ BUILD_BUG_ON(DCBX_MAX_BUFFERS > MLXSW_SP_PB_COUNT);
628
+ for (i = 0; i < DCBX_MAX_BUFFERS; i++)
629
+ hdroom.bufs.buf[i].set_size_cells = mlxsw_sp_bytes_cells(mlxsw_sp,
630
+ buf->buffer_size[i]);
631
+
632
+ mlxsw_sp_hdroom_prios_reset_buf_idx(&hdroom);
633
+ mlxsw_sp_hdroom_bufs_reset_lossiness(&hdroom);
634
+ mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom);
635
+ return mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom);
621636 }
622637
623638 static const struct dcbnl_rtnl_ops mlxsw_sp_dcbnl_ops = {
....@@ -632,6 +647,9 @@
632647
633648 .getdcbx = mlxsw_sp_dcbnl_getdcbx,
634649 .setdcbx = mlxsw_sp_dcbnl_setdcbx,
650
+
651
+ .dcbnl_getbuffer = mlxsw_sp_dcbnl_getbuffer,
652
+ .dcbnl_setbuffer = mlxsw_sp_dcbnl_setbuffer,
635653 };
636654
637655 static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)