]> Git Repo - linux.git/blob - drivers/net/ethernet/marvell/octeontx2/af/mcs_cnf10kb.c
Linux 6.14-rc3
[linux.git] / drivers / net / ethernet / marvell / octeontx2 / af / mcs_cnf10kb.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell MCS driver
3  *
4  * Copyright (C) 2022 Marvell.
5  */
6
7 #include "mcs.h"
8 #include "mcs_reg.h"
9
10 static struct mcs_ops cnf10kb_mcs_ops   = {
11         .mcs_set_hw_capabilities        = cnf10kb_mcs_set_hw_capabilities,
12         .mcs_parser_cfg                 = cnf10kb_mcs_parser_cfg,
13         .mcs_tx_sa_mem_map_write        = cnf10kb_mcs_tx_sa_mem_map_write,
14         .mcs_rx_sa_mem_map_write        = cnf10kb_mcs_rx_sa_mem_map_write,
15         .mcs_flowid_secy_map            = cnf10kb_mcs_flowid_secy_map,
16         .mcs_bbe_intr_handler           = cnf10kb_mcs_bbe_intr_handler,
17         .mcs_pab_intr_handler           = cnf10kb_mcs_pab_intr_handler,
18 };
19
20 struct mcs_ops *cnf10kb_get_mac_ops(void)
21 {
22         return &cnf10kb_mcs_ops;
23 }
24
25 void cnf10kb_mcs_set_hw_capabilities(struct mcs *mcs)
26 {
27         struct hwinfo *hw = mcs->hw;
28
29         hw->tcam_entries = 64;          /* TCAM entries */
30         hw->secy_entries  = 64;         /* SecY entries */
31         hw->sc_entries = 64;            /* SC CAM entries */
32         hw->sa_entries = 128;           /* SA entries */
33         hw->lmac_cnt = 4;               /* lmacs/ports per mcs block */
34         hw->mcs_x2p_intf = 1;           /* x2p clabration intf */
35         hw->mcs_blks = 7;               /* MCS blocks */
36         hw->ip_vec = MCS_CNF10KB_INT_VEC_IP; /* IP vector */
37 }
38
39 void cnf10kb_mcs_parser_cfg(struct mcs *mcs)
40 {
41         u64 reg, val;
42
43         /* VLAN Ctag */
44         val = (0x8100ull & 0xFFFF) | BIT_ULL(20) | BIT_ULL(22);
45
46         reg = MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(0);
47         mcs_reg_write(mcs, reg, val);
48
49         reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(0);
50         mcs_reg_write(mcs, reg, val);
51
52         /* VLAN STag */
53         val = (0x88a8ull & 0xFFFF) | BIT_ULL(20) | BIT_ULL(23);
54
55         /* RX */
56         reg = MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(1);
57         mcs_reg_write(mcs, reg, val);
58
59         /* TX */
60         reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(1);
61         mcs_reg_write(mcs, reg, val);
62
63         /* Enable custom tage 0 and 1 and sectag */
64         val = BIT_ULL(0) | BIT_ULL(1) | BIT_ULL(12);
65
66         reg = MCSX_PEX_RX_SLAVE_ETYPE_ENABLE;
67         mcs_reg_write(mcs, reg, val);
68
69         reg = MCSX_PEX_TX_SLAVE_ETYPE_ENABLE;
70         mcs_reg_write(mcs, reg, val);
71 }
72
73 void cnf10kb_mcs_flowid_secy_map(struct mcs *mcs, struct secy_mem_map *map, int dir)
74 {
75         u64 reg, val;
76
77         val = (map->secy & 0x3F) | (map->ctrl_pkt & 0x1) << 6;
78         if (dir == MCS_RX) {
79                 reg = MCSX_CPM_RX_SLAVE_SECY_MAP_MEMX(map->flow_id);
80         } else {
81                 reg = MCSX_CPM_TX_SLAVE_SECY_MAP_MEM_0X(map->flow_id);
82                 mcs_reg_write(mcs, reg, map->sci);
83                 val |= (map->sc & 0x3F) << 7;
84                 reg = MCSX_CPM_TX_SLAVE_SECY_MAP_MEM_1X(map->flow_id);
85         }
86
87         mcs_reg_write(mcs, reg, val);
88 }
89
90 void cnf10kb_mcs_tx_sa_mem_map_write(struct mcs *mcs, struct mcs_tx_sc_sa_map *map)
91 {
92         u64 reg, val;
93
94         val = (map->sa_index0 & 0x7F) | (map->sa_index1 & 0x7F) << 7;
95
96         reg = MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(map->sc_id);
97         mcs_reg_write(mcs, reg, val);
98
99         reg = MCSX_CPM_TX_SLAVE_AUTO_REKEY_ENABLE_0;
100         val = mcs_reg_read(mcs, reg);
101
102         if (map->rekey_ena)
103                 val |= BIT_ULL(map->sc_id);
104         else
105                 val &= ~BIT_ULL(map->sc_id);
106
107         mcs_reg_write(mcs, reg, val);
108
109         mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_SA_INDEX0_VLDX(map->sc_id), map->sa_index0_vld);
110         mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_SA_INDEX1_VLDX(map->sc_id), map->sa_index1_vld);
111
112         mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_TX_SA_ACTIVEX(map->sc_id), map->tx_sa_active);
113 }
114
115 void cnf10kb_mcs_rx_sa_mem_map_write(struct mcs *mcs, struct mcs_rx_sc_sa_map *map)
116 {
117         u64 val, reg;
118
119         val = (map->sa_index & 0x7F) | (map->sa_in_use << 7);
120
121         reg = MCSX_CPM_RX_SLAVE_SA_MAP_MEMX((4 * map->sc_id) + map->an);
122         mcs_reg_write(mcs, reg, val);
123 }
124
125 int mcs_set_force_clk_en(struct mcs *mcs, bool set)
126 {
127         unsigned long timeout = jiffies + usecs_to_jiffies(2000);
128         u64 val;
129
130         val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL);
131
132         if (set) {
133                 val |= BIT_ULL(4);
134                 mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
135
136                 /* Poll till mcsx_mil_ip_gbl_status.mcs_ip_stats_ready value is 1 */
137                 while (!(mcs_reg_read(mcs, MCSX_MIL_IP_GBL_STATUS) & BIT_ULL(0))) {
138                         if (time_after(jiffies, timeout)) {
139                                 dev_err(mcs->dev, "MCS set force clk enable failed\n");
140                                 break;
141                         }
142                 }
143         } else {
144                 val &= ~BIT_ULL(4);
145                 mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
146         }
147
148         return 0;
149 }
150
151 /* TX SA interrupt is raised only if autorekey is enabled.
152  * MCS_CPM_TX_SLAVE_SA_MAP_MEM_0X[sc].tx_sa_active bit gets toggled if
153  * one of two SAs mapped to SC gets expired. If tx_sa_active=0 implies
154  * SA in SA_index1 got expired else SA in SA_index0 got expired.
155  */
156 void cnf10kb_mcs_tx_pn_thresh_reached_handler(struct mcs *mcs)
157 {
158         struct mcs_intr_event event;
159         struct rsrc_bmap *sc_bmap;
160         unsigned long rekey_ena;
161         u64 val, sa_status;
162         int sc;
163
164         sc_bmap = &mcs->tx.sc;
165
166         event.mcs_id = mcs->mcs_id;
167         event.intr_mask = MCS_CPM_TX_PN_THRESH_REACHED_INT;
168
169         rekey_ena = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_AUTO_REKEY_ENABLE_0);
170
171         for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) {
172                 /* Auto rekey is enable */
173                 if (!test_bit(sc, &rekey_ena))
174                         continue;
175                 sa_status = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_TX_SA_ACTIVEX(sc));
176                 /* Check if tx_sa_active status had changed */
177                 if (sa_status == mcs->tx_sa_active[sc])
178                         continue;
179
180                 /* SA_index0 is expired */
181                 val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc));
182                 if (sa_status)
183                         event.sa_id = val & 0x7F;
184                 else
185                         event.sa_id = (val >> 7) & 0x7F;
186
187                 event.pcifunc = mcs->tx.sa2pf_map[event.sa_id];
188                 mcs_add_intr_wq_entry(mcs, &event);
189         }
190 }
191
192 void cnf10kb_mcs_tx_pn_wrapped_handler(struct mcs *mcs)
193 {
194         struct mcs_intr_event event = { 0 };
195         struct rsrc_bmap *sc_bmap;
196         u64 val;
197         int sc;
198
199         sc_bmap = &mcs->tx.sc;
200
201         event.mcs_id = mcs->mcs_id;
202         event.intr_mask = MCS_CPM_TX_PACKET_XPN_EQ0_INT;
203
204         for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) {
205                 val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc));
206
207                 if (mcs->tx_sa_active[sc])
208                         /* SA_index1 was used and got expired */
209                         event.sa_id = (val >> 7) & 0x7F;
210                 else
211                         /* SA_index0 was used and got expired */
212                         event.sa_id = val & 0x7F;
213
214                 event.pcifunc = mcs->tx.sa2pf_map[event.sa_id];
215                 mcs_add_intr_wq_entry(mcs, &event);
216         }
217 }
218
219 void cnf10kb_mcs_bbe_intr_handler(struct mcs *mcs, u64 intr,
220                                   enum mcs_direction dir)
221 {
222         struct mcs_intr_event event = { 0 };
223         int i;
224
225         if (!(intr & MCS_BBE_INT_MASK))
226                 return;
227
228         event.mcs_id = mcs->mcs_id;
229         event.pcifunc = mcs->pf_map[0];
230
231         for (i = 0; i < MCS_MAX_BBE_INT; i++) {
232                 if (!(intr & BIT_ULL(i)))
233                         continue;
234
235                 /* Lower nibble denotes data fifo overflow interrupts and
236                  * upper nibble indicates policy fifo overflow interrupts.
237                  */
238                 if (intr & 0xFULL)
239                         event.intr_mask = (dir == MCS_RX) ?
240                                           MCS_BBE_RX_DFIFO_OVERFLOW_INT :
241                                           MCS_BBE_TX_DFIFO_OVERFLOW_INT;
242                 else
243                         event.intr_mask = (dir == MCS_RX) ?
244                                           MCS_BBE_RX_PLFIFO_OVERFLOW_INT :
245                                           MCS_BBE_TX_PLFIFO_OVERFLOW_INT;
246
247                 /* Notify the lmac_id info which ran into BBE fatal error */
248                 event.lmac_id = i & 0x3ULL;
249                 mcs_add_intr_wq_entry(mcs, &event);
250         }
251 }
252
253 void cnf10kb_mcs_pab_intr_handler(struct mcs *mcs, u64 intr,
254                                   enum mcs_direction dir)
255 {
256         struct mcs_intr_event event = { 0 };
257         int i;
258
259         if (!(intr & MCS_PAB_INT_MASK))
260                 return;
261
262         event.mcs_id = mcs->mcs_id;
263         event.pcifunc = mcs->pf_map[0];
264
265         for (i = 0; i < MCS_MAX_PAB_INT; i++) {
266                 if (!(intr & BIT_ULL(i)))
267                         continue;
268
269                 event.intr_mask = (dir == MCS_RX) ?
270                                   MCS_PAB_RX_CHAN_OVERFLOW_INT :
271                                   MCS_PAB_TX_CHAN_OVERFLOW_INT;
272
273                 /* Notify the lmac_id info which ran into PAB fatal error */
274                 event.lmac_id = i;
275                 mcs_add_intr_wq_entry(mcs, &event);
276         }
277 }
This page took 0.050162 seconds and 4 git commands to generate.