first public release
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe_fdir.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  *  version: DPDK.L.1.2.3-3
34  */
35
36 #include <stdio.h>
37 #include <stdint.h>
38 #include <stdarg.h>
39 #include <errno.h>
40 #include <sys/queue.h>
41
42 #include <rte_interrupts.h>
43 #include <rte_log.h>
44 #include <rte_debug.h>
45 #include <rte_pci.h>
46 #include <rte_ether.h>
47 #include <rte_ethdev.h>
48
49 #include "ixgbe_logs.h"
50 #include "ixgbe/ixgbe_api.h"
51 #include "ixgbe/ixgbe_common.h"
52 #include "ixgbe_ethdev.h"
53
54 /* To get PBALLOC (Packet Buffer Allocation) bits from FDIRCTRL value */
55 #define FDIRCTRL_PBALLOC_MASK           0x03
56
57 /* For calculating memory required for FDIR filters */
58 #define PBALLOC_SIZE_SHIFT              15
59
60 /* Number of bits used to mask bucket hash for different pballoc sizes */
61 #define PERFECT_BUCKET_64KB_HASH_MASK   0x07FF  /* 11 bits */
62 #define PERFECT_BUCKET_128KB_HASH_MASK  0x0FFF  /* 12 bits */
63 #define PERFECT_BUCKET_256KB_HASH_MASK  0x1FFF  /* 13 bits */
64 #define SIG_BUCKET_64KB_HASH_MASK       0x1FFF  /* 13 bits */
65 #define SIG_BUCKET_128KB_HASH_MASK      0x3FFF  /* 14 bits */
66 #define SIG_BUCKET_256KB_HASH_MASK      0x7FFF  /* 15 bits */
67
68 /**
69  * This function is based on ixgbe_fdir_enable_82599() in ixgbe/ixgbe_82599.c.
70  * It adds extra configuration of fdirctrl that is common for all filter types.
71  *
72  *  Initialize Flow Director control registers
73  *  @hw: pointer to hardware structure
74  *  @fdirctrl: value to write to flow director control register
75  **/
76 static void fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl)
77 {
78         int i;
79
80         PMD_INIT_FUNC_TRACE();
81
82         /* Prime the keys for hashing */
83         IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
84         IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY);
85
86         /*
87          * Continue setup of fdirctrl register bits:
88          *  Set the maximum length per hash bucket to 0xA filters
89          *  Send interrupt when 64 filters are left
90          */
91         fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
92                     (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
93
94         /*
95          * Poll init-done after we write the register.  Estimated times:
96          *      10G: PBALLOC = 11b, timing is 60us
97          *       1G: PBALLOC = 11b, timing is 600us
98          *     100M: PBALLOC = 11b, timing is 6ms
99          *
100          *     Multiple these timings by 4 if under full Rx load
101          *
102          * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
103          * 1 msec per poll time.  If we're at line rate and drop to 100M, then
104          * this might not finish in our poll time, but we can live with that
105          * for now.
106          */
107         IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
108         IXGBE_WRITE_FLUSH(hw);
109         for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
110                 if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
111                                    IXGBE_FDIRCTRL_INIT_DONE)
112                         break;
113                 msec_delay(1);
114         }
115
116         if (i >= IXGBE_FDIR_INIT_DONE_POLL)
117                 PMD_INIT_LOG(WARNING, "Flow Director poll time exceeded!\n");
118 }
119
120 /*
121  * Set appropriate bits in fdirctrl for: variable reporting levels, moving
122  * flexbytes matching field, and drop queue (only for perfect matching mode).
123  */
124 static int
125 configure_fdir_flags(struct rte_fdir_conf *conf, uint32_t *fdirctrl)
126 {
127         *fdirctrl = 0;
128
129         switch (conf->pballoc) {
130         case RTE_FDIR_PBALLOC_64K:
131                 /* 8k - 1 signature filters */
132                 *fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
133                 break;
134         case RTE_FDIR_PBALLOC_128K:
135                 /* 16k - 1 signature filters */
136                 *fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
137                 break;
138         case RTE_FDIR_PBALLOC_256K:
139                 /* 32k - 1 signature filters */
140                 *fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
141                 break;
142         default:
143                 /* bad value */
144                 PMD_INIT_LOG(ERR, "Invalid fdir_conf->pballoc value");
145                 return -EINVAL;
146         };
147
148         /* status flags: write hash & swindex in the rx descriptor */
149         switch (conf->status) {
150         case RTE_FDIR_NO_REPORT_STATUS:
151                 /* do nothing, default mode */
152                 break;
153         case RTE_FDIR_REPORT_STATUS:
154                 /* report status when the packet matches a fdir rule */
155                 *fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
156                 break;
157         case RTE_FDIR_REPORT_STATUS_ALWAYS:
158                 /* always report status */
159                 *fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS;
160                 break;
161         default:
162                 /* bad value */
163                 PMD_INIT_LOG(ERR, "Invalid fdir_conf->status value");
164                 return -EINVAL;
165         };
166
167         *fdirctrl |= (conf->flexbytes_offset << IXGBE_FDIRCTRL_FLEX_SHIFT);
168
169         if (conf->mode == RTE_FDIR_MODE_PERFECT) {
170                 *fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;
171                 *fdirctrl |= (conf->drop_queue << IXGBE_FDIRCTRL_DROP_Q_SHIFT);
172         }
173
174         return 0;
175 }
176
177 int
178 ixgbe_fdir_configure(struct rte_eth_dev *dev)
179 {
180         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
181         int err;
182         uint32_t fdirctrl, pbsize;
183         int i;
184
185         PMD_INIT_FUNC_TRACE();
186
187         if (hw->mac.type != ixgbe_mac_82599EB)
188                 return -ENOSYS;
189
190         err = configure_fdir_flags(&dev->data->dev_conf.fdir_conf, &fdirctrl);
191         if (err)
192                 return err;
193
194         /*
195          * Before enabling Flow Director, the Rx Packet Buffer size
196          * must be reduced.  The new value is the current size minus
197          * flow director memory usage size.
198          */
199         pbsize = (1 << (PBALLOC_SIZE_SHIFT + (fdirctrl & FDIRCTRL_PBALLOC_MASK)));
200         IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
201             (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
202
203         /*
204          * The defaults in the HW for RX PB 1-7 are not zero and so should be
205          * intialized to zero for non DCB mode otherwise actual total RX PB
206          * would be bigger than programmed and filter space would run into
207          * the PB 0 region.
208          */
209         for (i = 1; i < 8; i++)
210                 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
211
212         fdir_enable_82599(hw, fdirctrl);
213         return 0;
214 }
215
216 /*
217  * The below function is taken from the FreeBSD IXGBE drivers release
218  * 2.3.8. The only change is not to mask hash_result with IXGBE_ATR_HASH_MASK
219  * before returning, as the signature hash can use 16bits.
220  *
221  * The newer driver has optimised functions for calculating bucket and
222  * signature hashes. However they don't support IPv6 type packets for signature
223  * filters so are not used here.
224  *
225  * Note that the bkt_hash field in the ixgbe_atr_input structure is also never
226  * set.
227  *
228  * Compute the hashes for SW ATR
229  *  @stream: input bitstream to compute the hash on
230  *  @key: 32-bit hash key
231  **/
232 static u32
233 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input,
234                                  u32 key)
235 {
236         /*
237          * The algorithm is as follows:
238          *    Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350
239          *    where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n]
240          *    and A[n] x B[n] is bitwise AND between same length strings
241          *
242          *    K[n] is 16 bits, defined as:
243          *       for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15]
244          *       for n modulo 32 < 15, K[n] =
245          *             K[(n % 32:0) | (31:31 - (14 - (n % 32)))]
246          *
247          *    S[n] is 16 bits, defined as:
248          *       for n >= 15, S[n] = S[n:n - 15]
249          *       for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))]
250          *
251          *    To simplify for programming, the algorithm is implemented
252          *    in software this way:
253          *
254          *    key[31:0], hi_hash_dword[31:0], lo_hash_dword[31:0], hash[15:0]
255          *
256          *    for (i = 0; i < 352; i+=32)
257          *        hi_hash_dword[31:0] ^= Stream[(i+31):i];
258          *
259          *    lo_hash_dword[15:0]  ^= Stream[15:0];
260          *    lo_hash_dword[15:0]  ^= hi_hash_dword[31:16];
261          *    lo_hash_dword[31:16] ^= hi_hash_dword[15:0];
262          *
263          *    hi_hash_dword[31:0]  ^= Stream[351:320];
264          *
265          *    if(key[0])
266          *        hash[15:0] ^= Stream[15:0];
267          *
268          *    for (i = 0; i < 16; i++) {
269          *        if (key[i])
270          *            hash[15:0] ^= lo_hash_dword[(i+15):i];
271          *        if (key[i + 16])
272          *            hash[15:0] ^= hi_hash_dword[(i+15):i];
273          *    }
274          *
275          */
276         __be32 common_hash_dword = 0;
277         u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
278         u32 hash_result = 0;
279         u8 i;
280
281         /* record the flow_vm_vlan bits as they are a key part to the hash */
282         flow_vm_vlan = IXGBE_NTOHL(atr_input->dword_stream[0]);
283
284         /* generate common hash dword */
285         for (i = 10; i; i -= 2)
286                 common_hash_dword ^= atr_input->dword_stream[i] ^
287                                      atr_input->dword_stream[i - 1];
288
289         hi_hash_dword = IXGBE_NTOHL(common_hash_dword);
290
291         /* low dword is word swapped version of common */
292         lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
293
294         /* apply flow ID/VM pool/VLAN ID bits to hash words */
295         hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
296
297         /* Process bits 0 and 16 */
298         if (key & 0x0001) hash_result ^= lo_hash_dword;
299         if (key & 0x00010000) hash_result ^= hi_hash_dword;
300
301         /*
302          * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
303          * delay this because bit 0 of the stream should not be processed
304          * so we do not add the vlan until after bit 0 was processed
305          */
306         lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
307
308
309         /* process the remaining 30 bits in the key 2 bits at a time */
310         for (i = 15; i; i-- ) {
311                 if (key & (0x0001 << i)) hash_result ^= lo_hash_dword >> i;
312                 if (key & (0x00010000 << i)) hash_result ^= hi_hash_dword >> i;
313         }
314
315         return hash_result;
316 }
317
318 /*
319  * Calculate the hash value needed for signature-match filters. In the FreeBSD
320  * driver, this is done by the optimised function
321  * ixgbe_atr_compute_sig_hash_82599(). However that can't be used here as it
322  * doesn't support calculating a hash for an IPv6 filter.
323  */
324 static uint32_t
325 atr_compute_sig_hash_82599(union ixgbe_atr_input *input,
326                 enum rte_fdir_pballoc_type pballoc)
327 {
328         uint32_t bucket_hash, sig_hash;
329
330         if (pballoc == RTE_FDIR_PBALLOC_256K)
331                 bucket_hash = ixgbe_atr_compute_hash_82599(input,
332                                 IXGBE_ATR_BUCKET_HASH_KEY) &
333                                 SIG_BUCKET_256KB_HASH_MASK;
334         else if (pballoc == RTE_FDIR_PBALLOC_128K)
335                 bucket_hash = ixgbe_atr_compute_hash_82599(input,
336                                 IXGBE_ATR_BUCKET_HASH_KEY) &
337                                 SIG_BUCKET_128KB_HASH_MASK;
338         else
339                 bucket_hash = ixgbe_atr_compute_hash_82599(input,
340                                 IXGBE_ATR_BUCKET_HASH_KEY) &
341                                 SIG_BUCKET_64KB_HASH_MASK;
342
343         sig_hash = ixgbe_atr_compute_hash_82599(input,
344                         IXGBE_ATR_SIGNATURE_HASH_KEY);
345
346         return (sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT) | bucket_hash;
347 }
348
349 /**
350  * This function is based on ixgbe_atr_add_signature_filter_82599() in
351  * ixgbe/ixgbe_82599.c, but uses a pre-calculated hash value. It also supports
352  * setting extra fields in the FDIRCMD register, and removes the code that was
353  * verifying the flow_type field. According to the documentation, a flow type of
354  * 00 (i.e. not TCP, UDP, or SCTP) is not supported, however it appears to
355  * work ok...
356  *
357  *  Adds a signature hash filter
358  *  @hw: pointer to hardware structure
359  *  @input: unique input dword
360  *  @queue: queue index to direct traffic to
361  *  @fdircmd: any extra flags to set in fdircmd register
362  *  @fdirhash: pre-calculated hash value for the filter
363  **/
364 static void
365 fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
366                 union ixgbe_atr_input *input, u8 queue, u32 fdircmd,
367                 u32 fdirhash)
368 {
369         u64  fdirhashcmd;
370
371         PMD_INIT_FUNC_TRACE();
372
373         /* configure FDIRCMD register */
374         fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW |
375                   IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
376         fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
377         fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
378
379         /*
380          * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
381          * is for FDIRCMD.  Then do a 64-bit register write from FDIRHASH.
382          */
383         fdirhashcmd = (u64)fdircmd << 32;
384         fdirhashcmd |= fdirhash;
385         IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
386
387         PMD_INIT_LOG(DEBUG, "Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
388 }
389
390 /*
391  * Convert DPDK rte_fdir_filter struct to ixgbe_atr_input union that is used
392  * by the IXGBE driver code.
393  */
394 static int
395 fdir_filter_to_atr_input(struct rte_fdir_filter *fdir_filter,
396                 union ixgbe_atr_input *input)
397 {
398         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP ||
399                         fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE) &&
400                         (fdir_filter->port_src || fdir_filter->port_dst)) {
401                 PMD_INIT_LOG(ERR, "Invalid fdir_filter");
402                 return -EINVAL;
403         }
404
405         memset(input, 0, sizeof(*input));
406
407         input->formatted.vlan_id = fdir_filter->vlan_id;
408         input->formatted.src_port = fdir_filter->port_src;
409         input->formatted.dst_port = fdir_filter->port_dst;
410         input->formatted.flex_bytes = fdir_filter->flex_bytes;
411
412         switch (fdir_filter->l4type) {
413         case RTE_FDIR_L4TYPE_TCP:
414                 input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
415                 break;
416         case RTE_FDIR_L4TYPE_UDP:
417                 input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4;
418                 break;
419         case RTE_FDIR_L4TYPE_SCTP:
420                 input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4;
421                 break;
422         case RTE_FDIR_L4TYPE_NONE:
423                 input->formatted.flow_type = IXGBE_ATR_FLOW_TYPE_IPV4;
424                 break;
425         default:
426                 PMD_INIT_LOG(ERR, " Error on l4type input");
427                 return -EINVAL;
428         }
429
430         if (fdir_filter->iptype == RTE_FDIR_IPTYPE_IPV6) {
431                 input->formatted.flow_type |= IXGBE_ATR_L4TYPE_IPV6_MASK;
432
433                 input->formatted.src_ip[0] = fdir_filter->ip_src.ipv6_addr[0];
434                 input->formatted.src_ip[1] = fdir_filter->ip_src.ipv6_addr[1];
435                 input->formatted.src_ip[2] = fdir_filter->ip_src.ipv6_addr[2];
436                 input->formatted.src_ip[3] = fdir_filter->ip_src.ipv6_addr[3];
437
438                 input->formatted.dst_ip[0] = fdir_filter->ip_dst.ipv6_addr[0];
439                 input->formatted.dst_ip[1] = fdir_filter->ip_dst.ipv6_addr[1];
440                 input->formatted.dst_ip[2] = fdir_filter->ip_dst.ipv6_addr[2];
441                 input->formatted.dst_ip[3] = fdir_filter->ip_dst.ipv6_addr[3];
442
443         } else {
444                 input->formatted.src_ip[0] = fdir_filter->ip_src.ipv4_addr;
445                 input->formatted.dst_ip[0] = fdir_filter->ip_dst.ipv4_addr;
446         }
447
448         return 0;
449 }
450
451 /*
452  * Adds or updates a signature filter.
453  *
454  * dev: ethernet device to add filter to
455  * fdir_filter: filter details
456  * queue: queue index to direct traffic to
457  * update: 0 to add a new filter, otherwise update existing.
458  */
459 static int
460 fdir_add_update_signature_filter(struct rte_eth_dev *dev,
461                 struct rte_fdir_filter *fdir_filter, uint8_t queue, int update)
462 {
463         struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
464         uint32_t fdircmd_flags = (update) ? IXGBE_FDIRCMD_FILTER_UPDATE : 0;
465         uint32_t fdirhash;
466         union ixgbe_atr_input input;
467         int err;
468
469         if (hw->mac.type != ixgbe_mac_82599EB)
470                 return -ENOSYS;
471
472         err = fdir_filter_to_atr_input(fdir_filter, &input);
473         if (err)
474                 return err;
475
476         fdirhash = atr_compute_sig_hash_82599(&input,
477                         dev->data->dev_conf.fdir_conf.pballoc);
478         fdir_add_signature_filter_82599(hw, &input, queue, fdircmd_flags,
479                         fdirhash);
480         return 0;
481 }
482
483 int
484 ixgbe_fdir_add_signature_filter(struct rte_eth_dev *dev,
485                 struct rte_fdir_filter *fdir_filter, uint8_t queue)
486 {
487         PMD_INIT_FUNC_TRACE();
488         return fdir_add_update_signature_filter(dev, fdir_filter, queue, 0);
489 }
490
491 int
492 ixgbe_fdir_update_signature_filter(struct rte_eth_dev *dev,
493                 struct rte_fdir_filter *fdir_filter, uint8_t queue)
494 {
495         PMD_INIT_FUNC_TRACE();
496         return fdir_add_update_signature_filter(dev, fdir_filter, queue, 1);
497 }
498
499 /*
500  * This is based on ixgbe_fdir_erase_perfect_filter_82599() in
501  * ixgbe/ixgbe_82599.c. It is modified to take in the hash as a parameter so
502  * that it can be used for removing signature and perfect filters.
503  */
504 static s32
505 fdir_erase_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input,
506                 uint32_t fdirhash)
507 {
508         u32 fdircmd = 0;
509         u32 retry_count;
510         s32 err = 0;
511
512         IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
513
514         /* flush hash to HW */
515         IXGBE_WRITE_FLUSH(hw);
516
517         /* Query if filter is present */
518         IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
519
520         for (retry_count = 10; retry_count; retry_count--) {
521                 /* allow 10us for query to process */
522                 usec_delay(10);
523                 /* verify query completed successfully */
524                 fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
525                 if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
526                         break;
527         }
528
529         if (!retry_count) {
530                 PMD_INIT_LOG(ERR, "Timeout querying for flow director filter");
531                 err = -EIO;
532         }
533
534         /* if filter exists in hardware then remove it */
535         if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
536                 IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
537                 IXGBE_WRITE_FLUSH(hw);
538                 IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
539                                 IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
540         }
541
542         return err;
543 }
544
545 int
546 ixgbe_fdir_remove_signature_filter(struct rte_eth_dev *dev,
547                 struct rte_fdir_filter *fdir_filter)
548 {
549         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
550         union ixgbe_atr_input input;
551         int err;
552
553         PMD_INIT_FUNC_TRACE();
554
555         if (hw->mac.type != ixgbe_mac_82599EB)
556                 return -ENOSYS;
557
558         err = fdir_filter_to_atr_input(fdir_filter, &input);
559         if (err)
560                 return err;
561
562         return fdir_erase_filter_82599(hw, &input,
563                         atr_compute_sig_hash_82599(&input,
564                         dev->data->dev_conf.fdir_conf.pballoc));
565 }
566
567 /**
568  * This is based on ixgbe_get_fdirtcpm_82599(), in ixgbe/ixgbe_82599.c. It no
569  * longer does the byte reordering
570  *
571  *  generate a tcp port from atr_input_masks
572  *  @input_mask: mask to be bit swapped
573  *
574  *  The source and destination port masks for flow director are bit swapped
575  *  in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc.  In order to
576  *  generate a correctly swapped value we need to bit swap the mask and that
577  *  is what is accomplished by this function.
578  **/
579 static uint32_t
580 get_fdirtcpm_82599(struct rte_fdir_masks *input_mask)
581 {
582         u32 mask = input_mask->dst_port_mask;
583         mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT;
584         mask |= input_mask->src_port_mask;
585         mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
586         mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
587         mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
588         return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
589 }
590
591 /*
592  * This macro exists in ixgbe/ixgbe_82599.c, however in that file it reverses
593  * the bytes, and then reverses them again. So here it does nothing.
594  */
595 #define IXGBE_WRITE_REG_BE32 IXGBE_WRITE_REG
596
597 /*
598  * This is based on ixgbe_fdir_set_input_mask_82599() in ixgbe/ixgbe_82599.c,
599  * but makes use of the rte_fdir_masks structure to see which bits to set.
600  */
601 static int
602 fdir_set_input_mask_82599(struct ixgbe_hw *hw,
603                 struct rte_fdir_masks *input_mask)
604 {
605         /* mask VM pool and IPv6 since it is currently not supported */
606         u32 fdirm = IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6;
607         u32 fdirtcpm;
608
609         PMD_INIT_FUNC_TRACE();
610
611         /*
612          * Program the relevant mask registers.  If src/dst_port or src/dst_addr
613          * are zero, then assume a full mask for that field.  Also assume that
614          * a VLAN of 0 is unspecified, so mask that out as well.  L4type
615          * cannot be masked out in this implementation.
616          *
617          * This also assumes IPv4 only.  IPv6 masking isn't supported at this
618          * point in time.
619          */
620         if (input_mask->only_ip_flow) {
621                 /* use the L4 protocol mask for raw IPv4/IPv6 traffic */
622                 fdirm |= IXGBE_FDIRM_L4P;
623                 if (input_mask->dst_port_mask || input_mask->src_port_mask) {
624                         PMD_INIT_LOG(ERR, " Error on src/dst port mask\n");
625                         return -EINVAL;
626                 }
627         }
628
629         if (!input_mask->vlan_id)
630                 /* mask VLAN ID*/
631                 fdirm |= IXGBE_FDIRM_VLANID;
632
633         if (!input_mask->vlan_prio)
634                 /* mask VLAN priority */
635                 fdirm |= IXGBE_FDIRM_VLANP;
636
637         if (!input_mask->flexbytes)
638                 /* Mask Flex Bytes */
639                 fdirm |= IXGBE_FDIRM_FLEX;
640
641         IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
642
643         /* store the TCP/UDP port masks, bit reversed from port layout */
644         fdirtcpm = get_fdirtcpm_82599(input_mask);
645
646         /* write both the same so that UDP and TCP use the same mask */
647         IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
648         IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
649
650         /* store source and destination IP masks (big-enian) */
651         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
652                         IXGBE_NTOHL(~input_mask->src_ipv4_mask));
653         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
654                         IXGBE_NTOHL(~input_mask->dst_ipv4_mask));
655
656         return IXGBE_SUCCESS;
657 }
658
659 int
660 ixgbe_fdir_set_masks(struct rte_eth_dev *dev, struct rte_fdir_masks *fdir_masks)
661 {
662         struct ixgbe_hw *hw;
663         int err;
664
665         PMD_INIT_FUNC_TRACE();
666
667         hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
668
669         if (hw->mac.type != ixgbe_mac_82599EB)
670                 return -ENOSYS;
671
672         err = ixgbe_reinit_fdir_tables_82599(hw);
673         if (err) {
674                 PMD_INIT_LOG(ERR, "reinit of fdir tables failed");
675                 return -EIO;
676         }
677
678         return fdir_set_input_mask_82599(hw, fdir_masks);
679 }
680
681 static uint32_t
682 atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
683                 enum rte_fdir_pballoc_type pballoc)
684 {
685         if (pballoc == RTE_FDIR_PBALLOC_256K)
686                 return ixgbe_atr_compute_hash_82599(input,
687                                 IXGBE_ATR_BUCKET_HASH_KEY) &
688                                 PERFECT_BUCKET_256KB_HASH_MASK;
689         else if (pballoc == RTE_FDIR_PBALLOC_128K)
690                 return ixgbe_atr_compute_hash_82599(input,
691                                 IXGBE_ATR_BUCKET_HASH_KEY) &
692                                 PERFECT_BUCKET_128KB_HASH_MASK;
693         else
694                 return ixgbe_atr_compute_hash_82599(input,
695                                 IXGBE_ATR_BUCKET_HASH_KEY) &
696                                 PERFECT_BUCKET_64KB_HASH_MASK;
697 }
698
699 /*
700  * This is based on ixgbe_fdir_write_perfect_filter_82599() in
701  * ixgbe/ixgbe_82599.c, with the ability to set extra flags in FDIRCMD register
702  * added, and IPv6 support also added. The hash value is also pre-calculated
703  * as the pballoc value is needed to do it.
704  */
705 static void
706 fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input,
707                 uint16_t soft_id, uint8_t queue, uint32_t fdircmd,
708                 uint32_t fdirhash)
709 {
710         u32 fdirport, fdirvlan;
711
712         /* record the source address (big-endian) */
713         if (input->formatted.flow_type & IXGBE_ATR_L4TYPE_IPV6_MASK) {
714                 IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0), input->formatted.src_ip[0]);
715                 IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1), input->formatted.src_ip[1]);
716                 IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2), input->formatted.src_ip[2]);
717                 IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[3]);
718         }
719         else {
720                 IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]);
721         }
722
723         /* record the first 32 bits of the destination address (big-endian) */
724         IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]);
725
726         /* record source and destination port (little-endian)*/
727         fdirport = IXGBE_NTOHS(input->formatted.dst_port);
728         fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT;
729         fdirport |= IXGBE_NTOHS(input->formatted.src_port);
730         IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
731
732         /* record vlan (little-endian) and flex_bytes(big-endian) */
733         fdirvlan = input->formatted.flex_bytes;
734         fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
735         fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
736         IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan);
737
738         /* configure FDIRHASH register */
739         fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
740         IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
741
742         /*
743          * flush all previous writes to make certain registers are
744          * programmed prior to issuing the command
745          */
746         IXGBE_WRITE_FLUSH(hw);
747
748         /* configure FDIRCMD register */
749         fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW |
750                   IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
751         fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
752         fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
753         fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
754
755         IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
756 }
757
758 /*
759  * Adds or updates a perfect filter.
760  *
761  * dev: ethernet device to add filter to
762  * fdir_filter: filter details
763  * soft_id: software index for the filters
764  * queue: queue index to direct traffic to
765  * drop: non-zero if packets should be sent to the drop queue
766  * update: 0 to add a new filter, otherwise update existing.
767  */
768 static int
769 fdir_add_update_perfect_filter(struct rte_eth_dev *dev,
770                 struct rte_fdir_filter *fdir_filter, uint16_t soft_id,
771                 uint8_t queue, int drop, int update)
772 {
773         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
774         uint32_t fdircmd_flags = (update) ? IXGBE_FDIRCMD_FILTER_UPDATE : 0;
775         uint32_t fdirhash;
776         union ixgbe_atr_input input;
777         int err;
778
779         if (hw->mac.type != ixgbe_mac_82599EB)
780                 return -ENOSYS;
781
782         err = fdir_filter_to_atr_input(fdir_filter, &input);
783         if (err)
784                 return err;
785
786         if (drop) {
787                 queue = dev->data->dev_conf.fdir_conf.drop_queue;
788                 fdircmd_flags |= IXGBE_FDIRCMD_DROP;
789         }
790
791         fdirhash = atr_compute_perfect_hash_82599(&input,
792                         dev->data->dev_conf.fdir_conf.pballoc);
793
794         fdir_write_perfect_filter_82599(hw, &input, soft_id, queue,
795                         fdircmd_flags, fdirhash);
796         return 0;
797 }
798
799 int
800 ixgbe_fdir_add_perfect_filter(struct rte_eth_dev *dev,
801                 struct rte_fdir_filter *fdir_filter, uint16_t soft_id,
802                 uint8_t queue, uint8_t drop)
803 {
804         PMD_INIT_FUNC_TRACE();
805         return fdir_add_update_perfect_filter(dev, fdir_filter, soft_id, queue,
806                         drop, 0);
807 }
808
809 int
810 ixgbe_fdir_update_perfect_filter(struct rte_eth_dev *dev,
811                 struct rte_fdir_filter *fdir_filter, uint16_t soft_id,
812                 uint8_t queue, uint8_t drop)
813 {
814         PMD_INIT_FUNC_TRACE();
815         return fdir_add_update_perfect_filter(dev, fdir_filter, soft_id, queue,
816                         drop, 1);
817 }
818
819 int
820 ixgbe_fdir_remove_perfect_filter(struct rte_eth_dev *dev,
821                 struct rte_fdir_filter *fdir_filter,
822                 uint16_t soft_id)
823 {
824         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
825         union ixgbe_atr_input input;
826         uint32_t fdirhash;
827         int err;
828
829         PMD_INIT_FUNC_TRACE();
830
831         if (hw->mac.type != ixgbe_mac_82599EB)
832                 return -ENOSYS;
833
834         err = fdir_filter_to_atr_input(fdir_filter, &input);
835         if (err)
836                 return err;
837
838         /* configure FDIRHASH register */
839         fdirhash = atr_compute_perfect_hash_82599(&input,
840                         dev->data->dev_conf.fdir_conf.pballoc);
841         fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
842
843         return fdir_erase_filter_82599(hw, &input, fdirhash);
844 }
845
846 void
847 ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir *fdir)
848 {
849         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
850         struct ixgbe_hw_fdir_info *info =
851                         IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
852         uint32_t reg;
853
854         if (hw->mac.type != ixgbe_mac_82599EB)
855                 return;
856
857         /* Get the information from registers */
858         reg = IXGBE_READ_REG(hw, IXGBE_FDIRFREE);
859         info->collision = (uint16_t)((reg & IXGBE_FDIRFREE_COLL_MASK) >>
860                                         IXGBE_FDIRFREE_COLL_SHIFT);
861         info->free = (uint16_t)((reg & IXGBE_FDIRFREE_FREE_MASK) >>
862                                    IXGBE_FDIRFREE_FREE_SHIFT);
863
864         reg = IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
865         info->maxhash = (uint16_t)((reg & IXGBE_FDIRLEN_MAXHASH_MASK) >>
866                                       IXGBE_FDIRLEN_MAXHASH_SHIFT);
867         info->maxlen  = (uint8_t)((reg & IXGBE_FDIRLEN_MAXLEN_MASK) >>
868                                      IXGBE_FDIRLEN_MAXLEN_SHIFT);
869
870         reg = IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
871         info->remove += (reg & IXGBE_FDIRUSTAT_REMOVE_MASK) >>
872                 IXGBE_FDIRUSTAT_REMOVE_SHIFT;
873         info->add += (reg & IXGBE_FDIRUSTAT_ADD_MASK) >>
874                 IXGBE_FDIRUSTAT_ADD_SHIFT;
875
876         reg = IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT) & 0xFFFF;
877         info->f_remove += (reg & IXGBE_FDIRFSTAT_FREMOVE_MASK) >>
878                 IXGBE_FDIRFSTAT_FREMOVE_SHIFT;
879         info->f_add += (reg & IXGBE_FDIRFSTAT_FADD_MASK) >>
880                 IXGBE_FDIRFSTAT_FADD_SHIFT;
881
882         /*  Copy the new information in the fdir parameter */
883         fdir->collision = info->collision;
884         fdir->free = info->free;
885         fdir->maxhash = info->maxhash;
886         fdir->maxlen = info->maxlen;
887         fdir->remove = info->remove;
888         fdir->add = info->add;
889         fdir->f_remove = info->f_remove;
890         fdir->f_add = info->f_add;
891 }