3
3
/* Copyright 2020 NXP
4
4
*/
5
5
6
+ #define DPAA2_ETH_TRAP_DROP (_id , _group_id ) \
7
+ DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
8
+ DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, 0)
9
+
10
+ static const struct devlink_trap_group dpaa2_eth_trap_groups_arr [] = {
11
+ DEVLINK_TRAP_GROUP_GENERIC (PARSER_ERROR_DROPS , 0 ),
12
+ };
13
+
14
+ static const struct devlink_trap dpaa2_eth_traps_arr [] = {
15
+ DPAA2_ETH_TRAP_DROP (VXLAN_PARSING , PARSER_ERROR_DROPS ),
16
+ DPAA2_ETH_TRAP_DROP (LLC_SNAP_PARSING , PARSER_ERROR_DROPS ),
17
+ DPAA2_ETH_TRAP_DROP (VLAN_PARSING , PARSER_ERROR_DROPS ),
18
+ DPAA2_ETH_TRAP_DROP (PPPOE_PPP_PARSING , PARSER_ERROR_DROPS ),
19
+ DPAA2_ETH_TRAP_DROP (MPLS_PARSING , PARSER_ERROR_DROPS ),
20
+ DPAA2_ETH_TRAP_DROP (ARP_PARSING , PARSER_ERROR_DROPS ),
21
+ DPAA2_ETH_TRAP_DROP (IP_1_PARSING , PARSER_ERROR_DROPS ),
22
+ DPAA2_ETH_TRAP_DROP (IP_N_PARSING , PARSER_ERROR_DROPS ),
23
+ DPAA2_ETH_TRAP_DROP (GRE_PARSING , PARSER_ERROR_DROPS ),
24
+ DPAA2_ETH_TRAP_DROP (UDP_PARSING , PARSER_ERROR_DROPS ),
25
+ DPAA2_ETH_TRAP_DROP (TCP_PARSING , PARSER_ERROR_DROPS ),
26
+ DPAA2_ETH_TRAP_DROP (IPSEC_PARSING , PARSER_ERROR_DROPS ),
27
+ DPAA2_ETH_TRAP_DROP (SCTP_PARSING , PARSER_ERROR_DROPS ),
28
+ DPAA2_ETH_TRAP_DROP (DCCP_PARSING , PARSER_ERROR_DROPS ),
29
+ DPAA2_ETH_TRAP_DROP (GTP_PARSING , PARSER_ERROR_DROPS ),
30
+ DPAA2_ETH_TRAP_DROP (ESP_PARSING , PARSER_ERROR_DROPS ),
31
+ };
32
+
6
33
static int dpaa2_eth_dl_info_get (struct devlink * devlink ,
7
34
struct devlink_info_req * req ,
8
35
struct netlink_ext_ack * extack )
@@ -24,8 +51,142 @@ static int dpaa2_eth_dl_info_get(struct devlink *devlink,
24
51
return 0 ;
25
52
}
26
53
54
+ static struct dpaa2_eth_trap_item *
55
+ dpaa2_eth_dl_trap_item_lookup (struct dpaa2_eth_priv * priv , u16 trap_id )
56
+ {
57
+ struct dpaa2_eth_trap_data * dpaa2_eth_trap_data = priv -> trap_data ;
58
+ int i ;
59
+
60
+ for (i = 0 ; i < ARRAY_SIZE (dpaa2_eth_traps_arr ); i ++ ) {
61
+ if (dpaa2_eth_traps_arr [i ].id == trap_id )
62
+ return & dpaa2_eth_trap_data -> trap_items_arr [i ];
63
+ }
64
+
65
+ return NULL ;
66
+ }
67
+
68
+ struct dpaa2_eth_trap_item * dpaa2_eth_dl_get_trap (struct dpaa2_eth_priv * priv ,
69
+ struct dpaa2_fapr * fapr )
70
+ {
71
+ struct dpaa2_faf_error_bit {
72
+ int position ;
73
+ enum devlink_trap_generic_id trap_id ;
74
+ } faf_bits [] = {
75
+ { .position = 5 , .trap_id = DEVLINK_TRAP_GENERIC_ID_VXLAN_PARSING },
76
+ { .position = 20 , .trap_id = DEVLINK_TRAP_GENERIC_ID_LLC_SNAP_PARSING },
77
+ { .position = 24 , .trap_id = DEVLINK_TRAP_GENERIC_ID_VLAN_PARSING },
78
+ { .position = 26 , .trap_id = DEVLINK_TRAP_GENERIC_ID_PPPOE_PPP_PARSING },
79
+ { .position = 29 , .trap_id = DEVLINK_TRAP_GENERIC_ID_MPLS_PARSING },
80
+ { .position = 31 , .trap_id = DEVLINK_TRAP_GENERIC_ID_ARP_PARSING },
81
+ { .position = 52 , .trap_id = DEVLINK_TRAP_GENERIC_ID_IP_1_PARSING },
82
+ { .position = 61 , .trap_id = DEVLINK_TRAP_GENERIC_ID_IP_N_PARSING },
83
+ { .position = 67 , .trap_id = DEVLINK_TRAP_GENERIC_ID_GRE_PARSING },
84
+ { .position = 71 , .trap_id = DEVLINK_TRAP_GENERIC_ID_UDP_PARSING },
85
+ { .position = 76 , .trap_id = DEVLINK_TRAP_GENERIC_ID_TCP_PARSING },
86
+ { .position = 80 , .trap_id = DEVLINK_TRAP_GENERIC_ID_IPSEC_PARSING },
87
+ { .position = 82 , .trap_id = DEVLINK_TRAP_GENERIC_ID_SCTP_PARSING },
88
+ { .position = 84 , .trap_id = DEVLINK_TRAP_GENERIC_ID_DCCP_PARSING },
89
+ { .position = 88 , .trap_id = DEVLINK_TRAP_GENERIC_ID_GTP_PARSING },
90
+ { .position = 90 , .trap_id = DEVLINK_TRAP_GENERIC_ID_ESP_PARSING },
91
+ };
92
+ u64 faf_word ;
93
+ u64 mask ;
94
+ int i ;
95
+
96
+ for (i = 0 ; i < ARRAY_SIZE (faf_bits ); i ++ ) {
97
+ if (faf_bits [i ].position < 32 ) {
98
+ /* Low part of FAF.
99
+ * position ranges from 31 to 0, mask from 0 to 31.
100
+ */
101
+ mask = 1ull << (31 - faf_bits [i ].position );
102
+ faf_word = __le32_to_cpu (fapr -> faf_lo );
103
+ } else {
104
+ /* High part of FAF.
105
+ * position ranges from 95 to 32, mask from 0 to 63.
106
+ */
107
+ mask = 1ull << (63 - (faf_bits [i ].position - 32 ));
108
+ faf_word = __le64_to_cpu (fapr -> faf_hi );
109
+ }
110
+ if (faf_word & mask )
111
+ return dpaa2_eth_dl_trap_item_lookup (priv , faf_bits [i ].trap_id );
112
+ }
113
+ return NULL ;
114
+ }
115
+
116
+ static int dpaa2_eth_dl_trap_init (struct devlink * devlink ,
117
+ const struct devlink_trap * trap ,
118
+ void * trap_ctx )
119
+ {
120
+ struct dpaa2_eth_devlink_priv * dl_priv = devlink_priv (devlink );
121
+ struct dpaa2_eth_priv * priv = dl_priv -> dpaa2_priv ;
122
+ struct dpaa2_eth_trap_item * dpaa2_eth_trap_item ;
123
+
124
+ dpaa2_eth_trap_item = dpaa2_eth_dl_trap_item_lookup (priv , trap -> id );
125
+ if (WARN_ON (!dpaa2_eth_trap_item ))
126
+ return - ENOENT ;
127
+
128
+ dpaa2_eth_trap_item -> trap_ctx = trap_ctx ;
129
+
130
+ return 0 ;
131
+ }
132
+
133
+ static int dpaa2_eth_dl_trap_action_set (struct devlink * devlink ,
134
+ const struct devlink_trap * trap ,
135
+ enum devlink_trap_action action ,
136
+ struct netlink_ext_ack * extack )
137
+ {
138
+ /* No support for changing the action of an independent packet trap,
139
+ * only per trap group - parser error drops
140
+ */
141
+ NL_SET_ERR_MSG_MOD (extack ,
142
+ "Cannot change trap action independently of group" );
143
+ return - EOPNOTSUPP ;
144
+ }
145
+
146
+ static int dpaa2_eth_dl_trap_group_action_set (struct devlink * devlink ,
147
+ const struct devlink_trap_group * group ,
148
+ enum devlink_trap_action action ,
149
+ struct netlink_ext_ack * extack )
150
+ {
151
+ struct dpaa2_eth_devlink_priv * dl_priv = devlink_priv (devlink );
152
+ struct dpaa2_eth_priv * priv = dl_priv -> dpaa2_priv ;
153
+ struct net_device * net_dev = priv -> net_dev ;
154
+ struct device * dev = net_dev -> dev .parent ;
155
+ struct dpni_error_cfg err_cfg = {0 };
156
+ int err ;
157
+
158
+ if (group -> id != DEVLINK_TRAP_GROUP_GENERIC_ID_PARSER_ERROR_DROPS )
159
+ return - EOPNOTSUPP ;
160
+
161
+ /* Configure handling of frames marked as errors from the parser */
162
+ err_cfg .errors = DPAA2_FAS_RX_ERR_MASK ;
163
+ err_cfg .set_frame_annotation = 1 ;
164
+
165
+ switch (action ) {
166
+ case DEVLINK_TRAP_ACTION_DROP :
167
+ err_cfg .error_action = DPNI_ERROR_ACTION_DISCARD ;
168
+ break ;
169
+ case DEVLINK_TRAP_ACTION_TRAP :
170
+ err_cfg .error_action = DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE ;
171
+ break ;
172
+ default :
173
+ return - EOPNOTSUPP ;
174
+ }
175
+
176
+ err = dpni_set_errors_behavior (priv -> mc_io , 0 , priv -> mc_token , & err_cfg );
177
+ if (err ) {
178
+ dev_err (dev , "dpni_set_errors_behavior failed\n" );
179
+ return err ;
180
+ }
181
+
182
+ return 0 ;
183
+ }
184
+
27
185
static const struct devlink_ops dpaa2_eth_devlink_ops = {
28
186
.info_get = dpaa2_eth_dl_info_get ,
187
+ .trap_init = dpaa2_eth_dl_trap_init ,
188
+ .trap_action_set = dpaa2_eth_dl_trap_action_set ,
189
+ .trap_group_action_set = dpaa2_eth_dl_trap_group_action_set ,
29
190
};
30
191
31
192
int dpaa2_eth_dl_register (struct dpaa2_eth_priv * priv )
@@ -88,3 +249,61 @@ void dpaa2_eth_dl_port_del(struct dpaa2_eth_priv *priv)
88
249
devlink_port_type_clear (devlink_port );
89
250
devlink_port_unregister (devlink_port );
90
251
}
252
+
253
+ int dpaa2_eth_dl_traps_register (struct dpaa2_eth_priv * priv )
254
+ {
255
+ struct dpaa2_eth_trap_data * dpaa2_eth_trap_data ;
256
+ struct net_device * net_dev = priv -> net_dev ;
257
+ struct device * dev = net_dev -> dev .parent ;
258
+ int err ;
259
+
260
+ dpaa2_eth_trap_data = kzalloc (sizeof (* dpaa2_eth_trap_data ), GFP_KERNEL );
261
+ if (!dpaa2_eth_trap_data )
262
+ return - ENOMEM ;
263
+ priv -> trap_data = dpaa2_eth_trap_data ;
264
+
265
+ dpaa2_eth_trap_data -> trap_items_arr = kcalloc (ARRAY_SIZE (dpaa2_eth_traps_arr ),
266
+ sizeof (struct dpaa2_eth_trap_item ),
267
+ GFP_KERNEL );
268
+ if (!dpaa2_eth_trap_data -> trap_items_arr ) {
269
+ err = - ENOMEM ;
270
+ goto trap_data_free ;
271
+ }
272
+
273
+ err = devlink_trap_groups_register (priv -> devlink , dpaa2_eth_trap_groups_arr ,
274
+ ARRAY_SIZE (dpaa2_eth_trap_groups_arr ));
275
+ if (err ) {
276
+ dev_err (dev , "devlink_trap_groups_register() = %d\n" , err );
277
+ goto trap_items_arr_free ;
278
+ }
279
+
280
+ err = devlink_traps_register (priv -> devlink , dpaa2_eth_traps_arr ,
281
+ ARRAY_SIZE (dpaa2_eth_traps_arr ), priv );
282
+ if (err ) {
283
+ dev_err (dev , "devlink_traps_register() = %d\n" , err );
284
+ goto trap_groups_unregiser ;
285
+ }
286
+
287
+ return 0 ;
288
+
289
+ trap_groups_unregiser :
290
+ devlink_trap_groups_unregister (priv -> devlink , dpaa2_eth_trap_groups_arr ,
291
+ ARRAY_SIZE (dpaa2_eth_trap_groups_arr ));
292
+ trap_items_arr_free :
293
+ kfree (dpaa2_eth_trap_data -> trap_items_arr );
294
+ trap_data_free :
295
+ kfree (dpaa2_eth_trap_data );
296
+ priv -> trap_data = NULL ;
297
+
298
+ return err ;
299
+ }
300
+
301
+ void dpaa2_eth_dl_traps_unregister (struct dpaa2_eth_priv * priv )
302
+ {
303
+ devlink_traps_unregister (priv -> devlink , dpaa2_eth_traps_arr ,
304
+ ARRAY_SIZE (dpaa2_eth_traps_arr ));
305
+ devlink_trap_groups_unregister (priv -> devlink , dpaa2_eth_trap_groups_arr ,
306
+ ARRAY_SIZE (dpaa2_eth_trap_groups_arr ));
307
+ kfree (priv -> trap_data -> trap_items_arr );
308
+ kfree (priv -> trap_data );
309
+ }
0 commit comments