]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/netronome/nfp/flower/offload.c
Fix warning messages when mounting to older servers
[karo-tx-linux.git] / drivers / net / ethernet / netronome / nfp / flower / offload.c
1 /*
2  * Copyright (C) 2017 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. Redistributions in binary form must reproduce the above
20  *         copyright notice, this list of conditions and the following
21  *         disclaimer in the documentation and/or other materials
22  *         provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include <linux/skbuff.h>
35 #include <net/devlink.h>
36 #include <net/pkt_cls.h>
37
38 #include "cmsg.h"
39 #include "main.h"
40 #include "../nfpcore/nfp_cpp.h"
41 #include "../nfpcore/nfp_nsp.h"
42 #include "../nfp_app.h"
43 #include "../nfp_main.h"
44 #include "../nfp_net.h"
45 #include "../nfp_port.h"
46
47 static int
48 nfp_flower_xmit_flow(struct net_device *netdev,
49                      struct nfp_fl_payload *nfp_flow, u8 mtype)
50 {
51         u32 meta_len, key_len, mask_len, act_len, tot_len;
52         struct nfp_repr *priv = netdev_priv(netdev);
53         struct sk_buff *skb;
54         unsigned char *msg;
55
56         meta_len =  sizeof(struct nfp_fl_rule_metadata);
57         key_len = nfp_flow->meta.key_len;
58         mask_len = nfp_flow->meta.mask_len;
59         act_len = nfp_flow->meta.act_len;
60
61         tot_len = meta_len + key_len + mask_len + act_len;
62
63         /* Convert to long words as firmware expects
64          * lengths in units of NFP_FL_LW_SIZ.
65          */
66         nfp_flow->meta.key_len >>= NFP_FL_LW_SIZ;
67         nfp_flow->meta.mask_len >>= NFP_FL_LW_SIZ;
68         nfp_flow->meta.act_len >>= NFP_FL_LW_SIZ;
69
70         skb = nfp_flower_cmsg_alloc(priv->app, tot_len, mtype);
71         if (!skb)
72                 return -ENOMEM;
73
74         msg = nfp_flower_cmsg_get_data(skb);
75         memcpy(msg, &nfp_flow->meta, meta_len);
76         memcpy(&msg[meta_len], nfp_flow->unmasked_data, key_len);
77         memcpy(&msg[meta_len + key_len], nfp_flow->mask_data, mask_len);
78         memcpy(&msg[meta_len + key_len + mask_len],
79                nfp_flow->action_data, act_len);
80
81         /* Convert back to bytes as software expects
82          * lengths in units of bytes.
83          */
84         nfp_flow->meta.key_len <<= NFP_FL_LW_SIZ;
85         nfp_flow->meta.mask_len <<= NFP_FL_LW_SIZ;
86         nfp_flow->meta.act_len <<= NFP_FL_LW_SIZ;
87
88         nfp_ctrl_tx(priv->app->ctrl, skb);
89
90         return 0;
91 }
92
93 static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
94 {
95         return dissector_uses_key(f->dissector,
96                                   FLOW_DISSECTOR_KEY_IPV4_ADDRS) ||
97                 dissector_uses_key(f->dissector,
98                                    FLOW_DISSECTOR_KEY_IPV6_ADDRS) ||
99                 dissector_uses_key(f->dissector,
100                                    FLOW_DISSECTOR_KEY_PORTS) ||
101                 dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ICMP);
102 }
103
104 static int
105 nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
106                                 struct tc_cls_flower_offload *flow)
107 {
108         struct flow_dissector_key_control *mask_enc_ctl;
109         struct flow_dissector_key_basic *mask_basic;
110         struct flow_dissector_key_basic *key_basic;
111         u32 key_layer_two;
112         u8 key_layer;
113         int key_size;
114
115         mask_enc_ctl = skb_flow_dissector_target(flow->dissector,
116                                                  FLOW_DISSECTOR_KEY_ENC_CONTROL,
117                                                  flow->mask);
118
119         mask_basic = skb_flow_dissector_target(flow->dissector,
120                                                FLOW_DISSECTOR_KEY_BASIC,
121                                                flow->mask);
122
123         key_basic = skb_flow_dissector_target(flow->dissector,
124                                               FLOW_DISSECTOR_KEY_BASIC,
125                                               flow->key);
126         key_layer_two = 0;
127         key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
128         key_size = sizeof(struct nfp_flower_meta_one) +
129                    sizeof(struct nfp_flower_in_port) +
130                    sizeof(struct nfp_flower_mac_mpls);
131
132         /* We are expecting a tunnel. For now we ignore offloading. */
133         if (mask_enc_ctl->addr_type)
134                 return -EOPNOTSUPP;
135
136         if (mask_basic->n_proto) {
137                 /* Ethernet type is present in the key. */
138                 switch (key_basic->n_proto) {
139                 case cpu_to_be16(ETH_P_IP):
140                         key_layer |= NFP_FLOWER_LAYER_IPV4;
141                         key_size += sizeof(struct nfp_flower_ipv4);
142                         break;
143
144                 case cpu_to_be16(ETH_P_IPV6):
145                         key_layer |= NFP_FLOWER_LAYER_IPV6;
146                         key_size += sizeof(struct nfp_flower_ipv6);
147                         break;
148
149                 /* Currently we do not offload ARP
150                  * because we rely on it to get to the host.
151                  */
152                 case cpu_to_be16(ETH_P_ARP):
153                         return -EOPNOTSUPP;
154
155                 /* Will be included in layer 2. */
156                 case cpu_to_be16(ETH_P_8021Q):
157                         break;
158
159                 default:
160                         /* Other ethtype - we need check the masks for the
161                          * remainder of the key to ensure we can offload.
162                          */
163                         if (nfp_flower_check_higher_than_mac(flow))
164                                 return -EOPNOTSUPP;
165                         break;
166                 }
167         }
168
169         if (mask_basic->ip_proto) {
170                 /* Ethernet type is present in the key. */
171                 switch (key_basic->ip_proto) {
172                 case IPPROTO_TCP:
173                 case IPPROTO_UDP:
174                 case IPPROTO_SCTP:
175                 case IPPROTO_ICMP:
176                 case IPPROTO_ICMPV6:
177                         key_layer |= NFP_FLOWER_LAYER_TP;
178                         key_size += sizeof(struct nfp_flower_tp_ports);
179                         break;
180                 default:
181                         /* Other ip proto - we need check the masks for the
182                          * remainder of the key to ensure we can offload.
183                          */
184                         return -EOPNOTSUPP;
185                 }
186         }
187
188         ret_key_ls->key_layer = key_layer;
189         ret_key_ls->key_layer_two = key_layer_two;
190         ret_key_ls->key_size = key_size;
191
192         return 0;
193 }
194
195 static struct nfp_fl_payload *
196 nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer)
197 {
198         struct nfp_fl_payload *flow_pay;
199
200         flow_pay = kmalloc(sizeof(*flow_pay), GFP_KERNEL);
201         if (!flow_pay)
202                 return NULL;
203
204         flow_pay->meta.key_len = key_layer->key_size;
205         flow_pay->unmasked_data = kmalloc(key_layer->key_size, GFP_KERNEL);
206         if (!flow_pay->unmasked_data)
207                 goto err_free_flow;
208
209         flow_pay->meta.mask_len = key_layer->key_size;
210         flow_pay->mask_data = kmalloc(key_layer->key_size, GFP_KERNEL);
211         if (!flow_pay->mask_data)
212                 goto err_free_unmasked;
213
214         flow_pay->action_data = kmalloc(NFP_FL_MAX_A_SIZ, GFP_KERNEL);
215         if (!flow_pay->action_data)
216                 goto err_free_mask;
217
218         flow_pay->meta.flags = 0;
219         spin_lock_init(&flow_pay->lock);
220
221         return flow_pay;
222
223 err_free_mask:
224         kfree(flow_pay->mask_data);
225 err_free_unmasked:
226         kfree(flow_pay->unmasked_data);
227 err_free_flow:
228         kfree(flow_pay);
229         return NULL;
230 }
231
232 /**
233  * nfp_flower_add_offload() - Adds a new flow to hardware.
234  * @app:        Pointer to the APP handle
235  * @netdev:     netdev structure.
236  * @flow:       TC flower classifier offload structure.
237  *
238  * Adds a new flow to the repeated hash structure and action payload.
239  *
240  * Return: negative value on error, 0 if configured successfully.
241  */
242 static int
243 nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
244                        struct tc_cls_flower_offload *flow)
245 {
246         struct nfp_flower_priv *priv = app->priv;
247         struct nfp_fl_payload *flow_pay;
248         struct nfp_fl_key_ls *key_layer;
249         int err;
250
251         key_layer = kmalloc(sizeof(*key_layer), GFP_KERNEL);
252         if (!key_layer)
253                 return -ENOMEM;
254
255         err = nfp_flower_calculate_key_layers(key_layer, flow);
256         if (err)
257                 goto err_free_key_ls;
258
259         flow_pay = nfp_flower_allocate_new(key_layer);
260         if (!flow_pay) {
261                 err = -ENOMEM;
262                 goto err_free_key_ls;
263         }
264
265         err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay);
266         if (err)
267                 goto err_destroy_flow;
268
269         err = nfp_flower_compile_action(flow, netdev, flow_pay);
270         if (err)
271                 goto err_destroy_flow;
272
273         err = nfp_compile_flow_metadata(app, flow, flow_pay);
274         if (err)
275                 goto err_destroy_flow;
276
277         err = nfp_flower_xmit_flow(netdev, flow_pay,
278                                    NFP_FLOWER_CMSG_TYPE_FLOW_ADD);
279         if (err)
280                 goto err_destroy_flow;
281
282         INIT_HLIST_NODE(&flow_pay->link);
283         flow_pay->tc_flower_cookie = flow->cookie;
284         hash_add_rcu(priv->flow_table, &flow_pay->link, flow->cookie);
285
286         /* Deallocate flow payload when flower rule has been destroyed. */
287         kfree(key_layer);
288
289         return 0;
290
291 err_destroy_flow:
292         kfree(flow_pay->action_data);
293         kfree(flow_pay->mask_data);
294         kfree(flow_pay->unmasked_data);
295         kfree(flow_pay);
296 err_free_key_ls:
297         kfree(key_layer);
298         return err;
299 }
300
301 /**
302  * nfp_flower_del_offload() - Removes a flow from hardware.
303  * @app:        Pointer to the APP handle
304  * @netdev:     netdev structure.
305  * @flow:       TC flower classifier offload structure
306  *
307  * Removes a flow from the repeated hash structure and clears the
308  * action payload.
309  *
310  * Return: negative value on error, 0 if removed successfully.
311  */
312 static int
313 nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
314                        struct tc_cls_flower_offload *flow)
315 {
316         struct nfp_fl_payload *nfp_flow;
317         int err;
318
319         nfp_flow = nfp_flower_search_fl_table(app, flow->cookie);
320         if (!nfp_flow)
321                 return -ENOENT;
322
323         err = nfp_modify_flow_metadata(app, nfp_flow);
324         if (err)
325                 goto err_free_flow;
326
327         err = nfp_flower_xmit_flow(netdev, nfp_flow,
328                                    NFP_FLOWER_CMSG_TYPE_FLOW_DEL);
329         if (err)
330                 goto err_free_flow;
331
332 err_free_flow:
333         hash_del_rcu(&nfp_flow->link);
334         kfree(nfp_flow->action_data);
335         kfree(nfp_flow->mask_data);
336         kfree(nfp_flow->unmasked_data);
337         kfree_rcu(nfp_flow, rcu);
338         return err;
339 }
340
341 /**
342  * nfp_flower_get_stats() - Populates flow stats obtained from hardware.
343  * @app:        Pointer to the APP handle
344  * @flow:       TC flower classifier offload structure
345  *
346  * Populates a flow statistics structure which which corresponds to a
347  * specific flow.
348  *
349  * Return: negative value on error, 0 if stats populated successfully.
350  */
351 static int
352 nfp_flower_get_stats(struct nfp_app *app, struct tc_cls_flower_offload *flow)
353 {
354         struct nfp_fl_payload *nfp_flow;
355
356         nfp_flow = nfp_flower_search_fl_table(app, flow->cookie);
357         if (!nfp_flow)
358                 return -EINVAL;
359
360         spin_lock_bh(&nfp_flow->lock);
361         tcf_exts_stats_update(flow->exts, nfp_flow->stats.bytes,
362                               nfp_flow->stats.pkts, nfp_flow->stats.used);
363
364         nfp_flow->stats.pkts = 0;
365         nfp_flow->stats.bytes = 0;
366         spin_unlock_bh(&nfp_flow->lock);
367
368         return 0;
369 }
370
371 static int
372 nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
373                         struct tc_cls_flower_offload *flower)
374 {
375         switch (flower->command) {
376         case TC_CLSFLOWER_REPLACE:
377                 return nfp_flower_add_offload(app, netdev, flower);
378         case TC_CLSFLOWER_DESTROY:
379                 return nfp_flower_del_offload(app, netdev, flower);
380         case TC_CLSFLOWER_STATS:
381                 return nfp_flower_get_stats(app, flower);
382         }
383
384         return -EOPNOTSUPP;
385 }
386
387 int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
388                         u32 handle, __be16 proto, struct tc_to_netdev *tc)
389 {
390         if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
391                 return -EOPNOTSUPP;
392
393         if (!eth_proto_is_802_3(proto))
394                 return -EOPNOTSUPP;
395
396         if (tc->type != TC_SETUP_CLSFLOWER)
397                 return -EINVAL;
398
399         return nfp_flower_repr_offload(app, netdev, tc->cls_flower);
400 }