New upstream version 18.02
[deb_dpdk.git] / lib / librte_eal / linuxapp / kni / ethtool / ixgbe / kcompat.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*******************************************************************************
3
4   Intel 10 Gigabit PCI Express Linux driver
5   Copyright(c) 1999 - 2012 Intel Corporation.
6
7   Contact Information:
8   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
9   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
10
11 *******************************************************************************/
12
13 #include "ixgbe.h"
14 #include "kcompat.h"
15
16 /*****************************************************************************/
17 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) )
18 /* From lib/vsprintf.c */
19 #include <asm/div64.h>
20
21 static int skip_atoi(const char **s)
22 {
23         int i=0;
24
25         while (isdigit(**s))
26                 i = i*10 + *((*s)++) - '0';
27         return i;
28 }
29
30 #define _kc_ZEROPAD     1               /* pad with zero */
31 #define _kc_SIGN        2               /* unsigned/signed long */
32 #define _kc_PLUS        4               /* show plus */
33 #define _kc_SPACE       8               /* space if plus */
34 #define _kc_LEFT        16              /* left justified */
35 #define _kc_SPECIAL     32              /* 0x */
36 #define _kc_LARGE       64              /* use 'ABCDEF' instead of 'abcdef' */
37
38 static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
39 {
40         char c,sign,tmp[66];
41         const char *digits;
42         const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
43         const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
44         int i;
45
46         digits = (type & _kc_LARGE) ? large_digits : small_digits;
47         if (type & _kc_LEFT)
48                 type &= ~_kc_ZEROPAD;
49         if (base < 2 || base > 36)
50                 return 0;
51         c = (type & _kc_ZEROPAD) ? '0' : ' ';
52         sign = 0;
53         if (type & _kc_SIGN) {
54                 if (num < 0) {
55                         sign = '-';
56                         num = -num;
57                         size--;
58                 } else if (type & _kc_PLUS) {
59                         sign = '+';
60                         size--;
61                 } else if (type & _kc_SPACE) {
62                         sign = ' ';
63                         size--;
64                 }
65         }
66         if (type & _kc_SPECIAL) {
67                 if (base == 16)
68                         size -= 2;
69                 else if (base == 8)
70                         size--;
71         }
72         i = 0;
73         if (num == 0)
74                 tmp[i++]='0';
75         else while (num != 0)
76                 tmp[i++] = digits[do_div(num,base)];
77         if (i > precision)
78                 precision = i;
79         size -= precision;
80         if (!(type&(_kc_ZEROPAD+_kc_LEFT))) {
81                 while(size-->0) {
82                         if (buf <= end)
83                                 *buf = ' ';
84                         ++buf;
85                 }
86         }
87         if (sign) {
88                 if (buf <= end)
89                         *buf = sign;
90                 ++buf;
91         }
92         if (type & _kc_SPECIAL) {
93                 if (base==8) {
94                         if (buf <= end)
95                                 *buf = '0';
96                         ++buf;
97                 } else if (base==16) {
98                         if (buf <= end)
99                                 *buf = '0';
100                         ++buf;
101                         if (buf <= end)
102                                 *buf = digits[33];
103                         ++buf;
104                 }
105         }
106         if (!(type & _kc_LEFT)) {
107                 while (size-- > 0) {
108                         if (buf <= end)
109                                 *buf = c;
110                         ++buf;
111                 }
112         }
113         while (i < precision--) {
114                 if (buf <= end)
115                         *buf = '0';
116                 ++buf;
117         }
118         while (i-- > 0) {
119                 if (buf <= end)
120                         *buf = tmp[i];
121                 ++buf;
122         }
123         while (size-- > 0) {
124                 if (buf <= end)
125                         *buf = ' ';
126                 ++buf;
127         }
128         return buf;
129 }
130
131 int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
132 {
133         int len;
134         unsigned long long num;
135         int i, base;
136         char *str, *end, c;
137         const char *s;
138
139         int flags;              /* flags to number() */
140
141         int field_width;        /* width of output field */
142         int precision;          /* min. # of digits for integers; max
143                                    number of chars for from string */
144         int qualifier;          /* 'h', 'l', or 'L' for integer fields */
145                                 /* 'z' support added 23/7/1999 S.H.    */
146                                 /* 'z' changed to 'Z' --davidm 1/25/99 */
147
148         str = buf;
149         end = buf + size - 1;
150
151         if (end < buf - 1) {
152                 end = ((void *) -1);
153                 size = end - buf + 1;
154         }
155
156         for (; *fmt ; ++fmt) {
157                 if (*fmt != '%') {
158                         if (str <= end)
159                                 *str = *fmt;
160                         ++str;
161                         continue;
162                 }
163
164                 /* process flags */
165                 flags = 0;
166                 repeat:
167                         ++fmt;          /* this also skips first '%' */
168                         switch (*fmt) {
169                                 case '-': flags |= _kc_LEFT; goto repeat;
170                                 case '+': flags |= _kc_PLUS; goto repeat;
171                                 case ' ': flags |= _kc_SPACE; goto repeat;
172                                 case '#': flags |= _kc_SPECIAL; goto repeat;
173                                 case '0': flags |= _kc_ZEROPAD; goto repeat;
174                         }
175
176                 /* get field width */
177                 field_width = -1;
178                 if (isdigit(*fmt))
179                         field_width = skip_atoi(&fmt);
180                 else if (*fmt == '*') {
181                         ++fmt;
182                         /* it's the next argument */
183                         field_width = va_arg(args, int);
184                         if (field_width < 0) {
185                                 field_width = -field_width;
186                                 flags |= _kc_LEFT;
187                         }
188                 }
189
190                 /* get the precision */
191                 precision = -1;
192                 if (*fmt == '.') {
193                         ++fmt;
194                         if (isdigit(*fmt))
195                                 precision = skip_atoi(&fmt);
196                         else if (*fmt == '*') {
197                                 ++fmt;
198                                 /* it's the next argument */
199                                 precision = va_arg(args, int);
200                         }
201                         if (precision < 0)
202                                 precision = 0;
203                 }
204
205                 /* get the conversion qualifier */
206                 qualifier = -1;
207                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
208                         qualifier = *fmt;
209                         ++fmt;
210                 }
211
212                 /* default base */
213                 base = 10;
214
215                 switch (*fmt) {
216                         case 'c':
217                                 if (!(flags & _kc_LEFT)) {
218                                         while (--field_width > 0) {
219                                                 if (str <= end)
220                                                         *str = ' ';
221                                                 ++str;
222                                         }
223                                 }
224                                 c = (unsigned char) va_arg(args, int);
225                                 if (str <= end)
226                                         *str = c;
227                                 ++str;
228                                 while (--field_width > 0) {
229                                         if (str <= end)
230                                                 *str = ' ';
231                                         ++str;
232                                 }
233                                 continue;
234
235                         case 's':
236                                 s = va_arg(args, char *);
237                                 if (!s)
238                                         s = "<NULL>";
239
240                                 len = strnlen(s, precision);
241
242                                 if (!(flags & _kc_LEFT)) {
243                                         while (len < field_width--) {
244                                                 if (str <= end)
245                                                         *str = ' ';
246                                                 ++str;
247                                         }
248                                 }
249                                 for (i = 0; i < len; ++i) {
250                                         if (str <= end)
251                                                 *str = *s;
252                                         ++str; ++s;
253                                 }
254                                 while (len < field_width--) {
255                                         if (str <= end)
256                                                 *str = ' ';
257                                         ++str;
258                                 }
259                                 continue;
260
261                         case 'p':
262                                 if (field_width == -1) {
263                                         field_width = 2*sizeof(void *);
264                                         flags |= _kc_ZEROPAD;
265                                 }
266                                 str = number(str, end,
267                                                 (unsigned long) va_arg(args, void *),
268                                                 16, field_width, precision, flags);
269                                 continue;
270
271
272                         case 'n':
273                                 /* FIXME:
274                                 * What does C99 say about the overflow case here? */
275                                 if (qualifier == 'l') {
276                                         long * ip = va_arg(args, long *);
277                                         *ip = (str - buf);
278                                 } else if (qualifier == 'Z') {
279                                         size_t * ip = va_arg(args, size_t *);
280                                         *ip = (str - buf);
281                                 } else {
282                                         int * ip = va_arg(args, int *);
283                                         *ip = (str - buf);
284                                 }
285                                 continue;
286
287                         case '%':
288                                 if (str <= end)
289                                         *str = '%';
290                                 ++str;
291                                 continue;
292
293                                 /* integer number formats - set up the flags and "break" */
294                         case 'o':
295                                 base = 8;
296                                 break;
297
298                         case 'X':
299                                 flags |= _kc_LARGE;
300                         case 'x':
301                                 base = 16;
302                                 break;
303
304                         case 'd':
305                         case 'i':
306                                 flags |= _kc_SIGN;
307                         case 'u':
308                                 break;
309
310                         default:
311                                 if (str <= end)
312                                         *str = '%';
313                                 ++str;
314                                 if (*fmt) {
315                                         if (str <= end)
316                                                 *str = *fmt;
317                                         ++str;
318                                 } else {
319                                         --fmt;
320                                 }
321                                 continue;
322                 }
323                 if (qualifier == 'L')
324                         num = va_arg(args, long long);
325                 else if (qualifier == 'l') {
326                         num = va_arg(args, unsigned long);
327                         if (flags & _kc_SIGN)
328                                 num = (signed long) num;
329                 } else if (qualifier == 'Z') {
330                         num = va_arg(args, size_t);
331                 } else if (qualifier == 'h') {
332                         num = (unsigned short) va_arg(args, int);
333                         if (flags & _kc_SIGN)
334                                 num = (signed short) num;
335                 } else {
336                         num = va_arg(args, unsigned int);
337                         if (flags & _kc_SIGN)
338                                 num = (signed int) num;
339                 }
340                 str = number(str, end, num, base,
341                                 field_width, precision, flags);
342         }
343         if (str <= end)
344                 *str = '\0';
345         else if (size > 0)
346                 /* don't write out a null byte if the buf size is zero */
347                 *end = '\0';
348         /* the trailing null byte doesn't count towards the total
349         * ++str;
350         */
351         return str-buf;
352 }
353
354 int _kc_snprintf(char * buf, size_t size, const char *fmt, ...)
355 {
356         va_list args;
357         int i;
358
359         va_start(args, fmt);
360         i = _kc_vsnprintf(buf,size,fmt,args);
361         va_end(args);
362         return i;
363 }
364 #endif /* < 2.4.8 */
365
366
367
368 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
369 #ifdef CONFIG_PCI_IOV
370 int __kc_pci_vfs_assigned(struct pci_dev *dev)
371 {
372         unsigned int vfs_assigned = 0;
373 #ifdef HAVE_PCI_DEV_FLAGS_ASSIGNED
374         int pos;
375         struct pci_dev *vfdev;
376         unsigned short dev_id;
377
378         /* only search if we are a PF */
379         if (!dev->is_physfn)
380                 return 0;
381
382         /* find SR-IOV capability */
383         pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
384         if (!pos)
385                 return 0;
386
387         /*
388  *          * determine the device ID for the VFs, the vendor ID will be the
389  *                   * same as the PF so there is no need to check for that one
390  *                            */
391         pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &dev_id);
392
393         /* loop through all the VFs to see if we own any that are assigned */
394        vfdev = pci_get_device(dev->vendor, dev_id, NULL);
395         while (vfdev) {
396                 /*
397  *                  * It is considered assigned if it is a virtual function with
398  *                                   * our dev as the physical function and the assigned bit is set
399  *                                                    */
400                if (vfdev->is_virtfn && (vfdev->physfn == dev) &&
401                    (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED))
402                        vfs_assigned++;
403
404                vfdev = pci_get_device(dev->vendor, dev_id, vfdev);
405        }
406
407 #endif /* HAVE_PCI_DEV_FLAGS_ASSIGNED */
408         return vfs_assigned;
409 }
410
411 #endif /* CONFIG_PCI_IOV */
412 #endif /* 3.10.0 */
413
414
415
416 /*****************************************************************************/
417 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
418
419 /**************************************/
420 /* PCI DMA MAPPING */
421
422 #if defined(CONFIG_HIGHMEM)
423
424 #ifndef PCI_DRAM_OFFSET
425 #define PCI_DRAM_OFFSET 0
426 #endif
427
428 u64
429 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset,
430                  size_t size, int direction)
431 {
432         return ((u64) (page - mem_map) << PAGE_SHIFT) + offset +
433                 PCI_DRAM_OFFSET;
434 }
435
436 #else /* CONFIG_HIGHMEM */
437
438 u64
439 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset,
440                  size_t size, int direction)
441 {
442         return pci_map_single(dev, (void *)page_address(page) + offset, size,
443                               direction);
444 }
445
446 #endif /* CONFIG_HIGHMEM */
447
448 void
449 _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size,
450                    int direction)
451 {
452         return pci_unmap_single(dev, dma_addr, size, direction);
453 }
454
455 #endif /* 2.4.13 => 2.4.3 */
456
457 /*****************************************************************************/
458 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
459
460 /**************************************/
461 /* PCI DRIVER API */
462
463 int
464 _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
465 {
466         if (!pci_dma_supported(dev, mask))
467                 return -EIO;
468         dev->dma_mask = mask;
469         return 0;
470 }
471
472 int
473 _kc_pci_request_regions(struct pci_dev *dev, char *res_name)
474 {
475         int i;
476
477         for (i = 0; i < 6; i++) {
478                 if (pci_resource_len(dev, i) == 0)
479                         continue;
480
481                 if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
482                         if (!request_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
483                                 pci_release_regions(dev);
484                                 return -EBUSY;
485                         }
486                 } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
487                         if (!request_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
488                                 pci_release_regions(dev);
489                                 return -EBUSY;
490                         }
491                 }
492         }
493         return 0;
494 }
495
496 void
497 _kc_pci_release_regions(struct pci_dev *dev)
498 {
499         int i;
500
501         for (i = 0; i < 6; i++) {
502                 if (pci_resource_len(dev, i) == 0)
503                         continue;
504
505                 if (pci_resource_flags(dev, i) & IORESOURCE_IO)
506                         release_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
507
508                 else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
509                         release_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
510         }
511 }
512
513 /**************************************/
514 /* NETWORK DRIVER API */
515
516 struct net_device *
517 _kc_alloc_etherdev(int sizeof_priv)
518 {
519         struct net_device *dev;
520         int alloc_size;
521
522         alloc_size = sizeof(*dev) + sizeof_priv + IFNAMSIZ + 31;
523         dev = kzalloc(alloc_size, GFP_KERNEL);
524         if (!dev)
525                 return NULL;
526
527         if (sizeof_priv)
528                 dev->priv = (void *) (((unsigned long)(dev + 1) + 31) & ~31);
529         dev->name[0] = '\0';
530         ether_setup(dev);
531
532         return dev;
533 }
534
535 int
536 _kc_is_valid_ether_addr(u8 *addr)
537 {
538         const char zaddr[6] = { 0, };
539
540         return !(addr[0] & 1) && memcmp(addr, zaddr, 6);
541 }
542
543 #endif /* 2.4.3 => 2.4.0 */
544
545 /*****************************************************************************/
546 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
547
548 int
549 _kc_pci_set_power_state(struct pci_dev *dev, int state)
550 {
551         return 0;
552 }
553
554 int
555 _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable)
556 {
557         return 0;
558 }
559
560 #endif /* 2.4.6 => 2.4.3 */
561
562 /*****************************************************************************/
563 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
564 void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page,
565                             int off, int size)
566 {
567         skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
568         frag->page = page;
569         frag->page_offset = off;
570         frag->size = size;
571         skb_shinfo(skb)->nr_frags = i + 1;
572 }
573
574 /*
575  * Original Copyright:
576  * find_next_bit.c: fallback find next bit implementation
577  *
578  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
579  * Written by David Howells (dhowells@redhat.com)
580  */
581
582 /**
583  * find_next_bit - find the next set bit in a memory region
584  * @addr: The address to base the search on
585  * @offset: The bitnumber to start searching at
586  * @size: The maximum size to search
587  */
588 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
589                             unsigned long offset)
590 {
591         const unsigned long *p = addr + BITOP_WORD(offset);
592         unsigned long result = offset & ~(BITS_PER_LONG-1);
593         unsigned long tmp;
594
595         if (offset >= size)
596                 return size;
597         size -= result;
598         offset %= BITS_PER_LONG;
599         if (offset) {
600                 tmp = *(p++);
601                 tmp &= (~0UL << offset);
602                 if (size < BITS_PER_LONG)
603                         goto found_first;
604                 if (tmp)
605                         goto found_middle;
606                 size -= BITS_PER_LONG;
607                 result += BITS_PER_LONG;
608         }
609         while (size & ~(BITS_PER_LONG-1)) {
610                 if ((tmp = *(p++)))
611                         goto found_middle;
612                 result += BITS_PER_LONG;
613                 size -= BITS_PER_LONG;
614         }
615         if (!size)
616                 return result;
617         tmp = *p;
618
619 found_first:
620         tmp &= (~0UL >> (BITS_PER_LONG - size));
621         if (tmp == 0UL)         /* Are any bits set? */
622                 return result + size;   /* Nope. */
623 found_middle:
624         return result + ffs(tmp);
625 }
626
627 size_t _kc_strlcpy(char *dest, const char *src, size_t size)
628 {
629         size_t ret = strlen(src);
630
631         if (size) {
632                 size_t len = (ret >= size) ? size - 1 : ret;
633                 memcpy(dest, src, len);
634                 dest[len] = '\0';
635         }
636         return ret;
637 }
638
639 #endif /* 2.6.0 => 2.4.6 */
640
641 /*****************************************************************************/
642 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
643 int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...)
644 {
645         va_list args;
646         int i;
647
648         va_start(args, fmt);
649         i = vsnprintf(buf, size, fmt, args);
650         va_end(args);
651         return (i >= size) ? (size - 1) : i;
652 }
653 #endif /* < 2.6.4 */
654
655 /*****************************************************************************/
656 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
657 DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES) = {1};
658 #endif /* < 2.6.10 */
659
660 /*****************************************************************************/
661 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
662 char *_kc_kstrdup(const char *s, unsigned int gfp)
663 {
664         size_t len;
665         char *buf;
666
667         if (!s)
668                 return NULL;
669
670         len = strlen(s) + 1;
671         buf = kmalloc(len, gfp);
672         if (buf)
673                 memcpy(buf, s, len);
674         return buf;
675 }
676 #endif /* < 2.6.13 */
677
678 /*****************************************************************************/
679 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) )
680 void *_kc_kzalloc(size_t size, int flags)
681 {
682         void *ret = kmalloc(size, flags);
683         if (ret)
684                 memset(ret, 0, size);
685         return ret;
686 }
687 #endif /* <= 2.6.13 */
688
689 /*****************************************************************************/
690 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) )
691 int _kc_skb_pad(struct sk_buff *skb, int pad)
692 {
693         int ntail;
694
695         /* If the skbuff is non linear tailroom is always zero.. */
696         if(!skb_cloned(skb) && skb_tailroom(skb) >= pad) {
697                 memset(skb->data+skb->len, 0, pad);
698                 return 0;
699         }
700
701         ntail = skb->data_len + pad - (skb->end - skb->tail);
702         if (likely(skb_cloned(skb) || ntail > 0)) {
703                 if (pskb_expand_head(skb, 0, ntail, GFP_ATOMIC));
704                         goto free_skb;
705         }
706
707 #ifdef MAX_SKB_FRAGS
708         if (skb_is_nonlinear(skb) &&
709             !__pskb_pull_tail(skb, skb->data_len))
710                 goto free_skb;
711
712 #endif
713         memset(skb->data + skb->len, 0, pad);
714         return 0;
715
716 free_skb:
717         kfree_skb(skb);
718         return -ENOMEM;
719 }
720
721 #if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))
722 int _kc_pci_save_state(struct pci_dev *pdev)
723 {
724         struct adapter_struct *adapter = pci_get_drvdata(pdev);
725         int size = PCI_CONFIG_SPACE_LEN, i;
726         u16 pcie_cap_offset, pcie_link_status;
727
728 #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
729         /* no ->dev for 2.4 kernels */
730         WARN_ON(pdev->dev.driver_data == NULL);
731 #endif
732         pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP);
733         if (pcie_cap_offset) {
734                 if (!pci_read_config_word(pdev,
735                                           pcie_cap_offset + PCIE_LINK_STATUS,
736                                           &pcie_link_status))
737                 size = PCIE_CONFIG_SPACE_LEN;
738         }
739         pci_config_space_ich8lan();
740 #ifdef HAVE_PCI_ERS
741         if (adapter->config_space == NULL)
742 #else
743         WARN_ON(adapter->config_space != NULL);
744 #endif
745                 adapter->config_space = kmalloc(size, GFP_KERNEL);
746         if (!adapter->config_space) {
747                 printk(KERN_ERR "Out of memory in pci_save_state\n");
748                 return -ENOMEM;
749         }
750         for (i = 0; i < (size / 4); i++)
751                 pci_read_config_dword(pdev, i * 4, &adapter->config_space[i]);
752         return 0;
753 }
754
755 void _kc_pci_restore_state(struct pci_dev *pdev)
756 {
757         struct adapter_struct *adapter = pci_get_drvdata(pdev);
758         int size = PCI_CONFIG_SPACE_LEN, i;
759         u16 pcie_cap_offset;
760         u16 pcie_link_status;
761
762         if (adapter->config_space != NULL) {
763                 pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP);
764                 if (pcie_cap_offset &&
765                     !pci_read_config_word(pdev,
766                                           pcie_cap_offset + PCIE_LINK_STATUS,
767                                           &pcie_link_status))
768                         size = PCIE_CONFIG_SPACE_LEN;
769
770                 pci_config_space_ich8lan();
771                 for (i = 0; i < (size / 4); i++)
772                 pci_write_config_dword(pdev, i * 4, adapter->config_space[i]);
773 #ifndef HAVE_PCI_ERS
774                 kfree(adapter->config_space);
775                 adapter->config_space = NULL;
776 #endif
777         }
778 }
779 #endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */
780
781 #ifdef HAVE_PCI_ERS
782 void _kc_free_netdev(struct net_device *netdev)
783 {
784         struct adapter_struct *adapter = netdev_priv(netdev);
785
786         if (adapter->config_space != NULL)
787                 kfree(adapter->config_space);
788 #ifdef CONFIG_SYSFS
789         if (netdev->reg_state == NETREG_UNINITIALIZED) {
790                 kfree((char *)netdev - netdev->padded);
791         } else {
792                 BUG_ON(netdev->reg_state != NETREG_UNREGISTERED);
793                 netdev->reg_state = NETREG_RELEASED;
794                 class_device_put(&netdev->class_dev);
795         }
796 #else
797         kfree((char *)netdev - netdev->padded);
798 #endif
799 }
800 #endif
801
802 void *_kc_kmemdup(const void *src, size_t len, unsigned gfp)
803 {
804         void *p;
805
806         p = kzalloc(len, gfp);
807         if (p)
808                 memcpy(p, src, len);
809         return p;
810 }
811 #endif /* <= 2.6.19 */
812
813 /*****************************************************************************/
814 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
815 /* hexdump code taken from lib/hexdump.c */
816 static void _kc_hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
817                         int groupsize, unsigned char *linebuf,
818                         size_t linebuflen, bool ascii)
819 {
820         const u8 *ptr = buf;
821         u8 ch;
822         int j, lx = 0;
823         int ascii_column;
824
825         if (rowsize != 16 && rowsize != 32)
826                 rowsize = 16;
827
828         if (!len)
829                 goto nil;
830         if (len > rowsize)              /* limit to one line at a time */
831                 len = rowsize;
832         if ((len % groupsize) != 0)     /* no mixed size output */
833                 groupsize = 1;
834
835         switch (groupsize) {
836         case 8: {
837                 const u64 *ptr8 = buf;
838                 int ngroups = len / groupsize;
839
840                 for (j = 0; j < ngroups; j++)
841                         lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
842                                 "%s%16.16llx", j ? " " : "",
843                                 (unsigned long long)*(ptr8 + j));
844                 ascii_column = 17 * ngroups + 2;
845                 break;
846         }
847
848         case 4: {
849                 const u32 *ptr4 = buf;
850                 int ngroups = len / groupsize;
851
852                 for (j = 0; j < ngroups; j++)
853                         lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
854                                 "%s%8.8x", j ? " " : "", *(ptr4 + j));
855                 ascii_column = 9 * ngroups + 2;
856                 break;
857         }
858
859         case 2: {
860                 const u16 *ptr2 = buf;
861                 int ngroups = len / groupsize;
862
863                 for (j = 0; j < ngroups; j++)
864                         lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
865                                 "%s%4.4x", j ? " " : "", *(ptr2 + j));
866                 ascii_column = 5 * ngroups + 2;
867                 break;
868         }
869
870         default:
871                 for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
872                         ch = ptr[j];
873                         linebuf[lx++] = hex_asc(ch >> 4);
874                         linebuf[lx++] = hex_asc(ch & 0x0f);
875                         linebuf[lx++] = ' ';
876                 }
877                 if (j)
878                         lx--;
879
880                 ascii_column = 3 * rowsize + 2;
881                 break;
882         }
883         if (!ascii)
884                 goto nil;
885
886         while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
887                 linebuf[lx++] = ' ';
888         for (j = 0; (j < len) && (lx + 2) < linebuflen; j++)
889                 linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j]
890                                 : '.';
891 nil:
892         linebuf[lx++] = '\0';
893 }
894
895 void _kc_print_hex_dump(const char *level,
896                         const char *prefix_str, int prefix_type,
897                         int rowsize, int groupsize,
898                         const void *buf, size_t len, bool ascii)
899 {
900         const u8 *ptr = buf;
901         int i, linelen, remaining = len;
902         unsigned char linebuf[200];
903
904         if (rowsize != 16 && rowsize != 32)
905                 rowsize = 16;
906
907         for (i = 0; i < len; i += rowsize) {
908                 linelen = min(remaining, rowsize);
909                 remaining -= rowsize;
910                 _kc_hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
911                                 linebuf, sizeof(linebuf), ascii);
912
913                 switch (prefix_type) {
914                 case DUMP_PREFIX_ADDRESS:
915                         printk("%s%s%*p: %s\n", level, prefix_str,
916                                 (int)(2 * sizeof(void *)), ptr + i, linebuf);
917                         break;
918                 case DUMP_PREFIX_OFFSET:
919                         printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
920                         break;
921                 default:
922                         printk("%s%s%s\n", level, prefix_str, linebuf);
923                         break;
924                 }
925         }
926 }
927 #endif /* < 2.6.22 */
928
929 /*****************************************************************************/
930 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) )
931 int ixgbe_dcb_netlink_register(void)
932 {
933         return 0;
934 }
935
936 int ixgbe_dcb_netlink_unregister(void)
937 {
938         return 0;
939 }
940
941 int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max)
942 {
943         return 0;
944 }
945 #endif /* < 2.6.23 */
946
947 /*****************************************************************************/
948 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
949 #ifdef NAPI
950 struct net_device *napi_to_poll_dev(struct napi_struct *napi)
951 {
952         struct adapter_q_vector *q_vector = container_of(napi,
953                                                         struct adapter_q_vector,
954                                                         napi);
955         return &q_vector->poll_dev;
956 }
957
958 int __kc_adapter_clean(struct net_device *netdev, int *budget)
959 {
960         int work_done;
961         int work_to_do = min(*budget, netdev->quota);
962         /* kcompat.h netif_napi_add puts napi struct in "fake netdev->priv" */
963         struct napi_struct *napi = netdev->priv;
964         work_done = napi->poll(napi, work_to_do);
965         *budget -= work_done;
966         netdev->quota -= work_done;
967         return (work_done >= work_to_do) ? 1 : 0;
968 }
969 #endif /* NAPI */
970 #endif /* <= 2.6.24 */
971
972 /*****************************************************************************/
973 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) )
974 void _kc_pci_disable_link_state(struct pci_dev *pdev, int state)
975 {
976         struct pci_dev *parent = pdev->bus->self;
977         u16 link_state;
978         int pos;
979
980         if (!parent)
981                 return;
982
983         pos = pci_find_capability(parent, PCI_CAP_ID_EXP);
984         if (pos) {
985                 pci_read_config_word(parent, pos + PCI_EXP_LNKCTL, &link_state);
986                 link_state &= ~state;
987                 pci_write_config_word(parent, pos + PCI_EXP_LNKCTL, link_state);
988         }
989 }
990 #endif /* < 2.6.26 */
991
992 /*****************************************************************************/
993 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) )
994 #ifdef HAVE_TX_MQ
995 void _kc_netif_tx_stop_all_queues(struct net_device *netdev)
996 {
997         struct adapter_struct *adapter = netdev_priv(netdev);
998         int i;
999
1000         netif_stop_queue(netdev);
1001         if (netif_is_multiqueue(netdev))
1002                 for (i = 0; i < adapter->num_tx_queues; i++)
1003                         netif_stop_subqueue(netdev, i);
1004 }
1005 void _kc_netif_tx_wake_all_queues(struct net_device *netdev)
1006 {
1007         struct adapter_struct *adapter = netdev_priv(netdev);
1008         int i;
1009
1010         netif_wake_queue(netdev);
1011         if (netif_is_multiqueue(netdev))
1012                 for (i = 0; i < adapter->num_tx_queues; i++)
1013                         netif_wake_subqueue(netdev, i);
1014 }
1015 void _kc_netif_tx_start_all_queues(struct net_device *netdev)
1016 {
1017         struct adapter_struct *adapter = netdev_priv(netdev);
1018         int i;
1019
1020         netif_start_queue(netdev);
1021         if (netif_is_multiqueue(netdev))
1022                 for (i = 0; i < adapter->num_tx_queues; i++)
1023                         netif_start_subqueue(netdev, i);
1024 }
1025 #endif /* HAVE_TX_MQ */
1026
1027 #ifndef __WARN_printf
1028 void __kc_warn_slowpath(const char *file, int line, const char *fmt, ...)
1029 {
1030         va_list args;
1031
1032         printk(KERN_WARNING "------------[ cut here ]------------\n");
1033         printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, line);
1034         va_start(args, fmt);
1035         vprintk(fmt, args);
1036         va_end(args);
1037
1038         dump_stack();
1039 }
1040 #endif /* __WARN_printf */
1041 #endif /* < 2.6.27 */
1042
1043 /*****************************************************************************/
1044 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) )
1045
1046 int
1047 _kc_pci_prepare_to_sleep(struct pci_dev *dev)
1048 {
1049         pci_power_t target_state;
1050         int error;
1051
1052         target_state = pci_choose_state(dev, PMSG_SUSPEND);
1053
1054         pci_enable_wake(dev, target_state, true);
1055
1056         error = pci_set_power_state(dev, target_state);
1057
1058         if (error)
1059                 pci_enable_wake(dev, target_state, false);
1060
1061         return error;
1062 }
1063
1064 int
1065 _kc_pci_wake_from_d3(struct pci_dev *dev, bool enable)
1066 {
1067         int err;
1068
1069         err = pci_enable_wake(dev, PCI_D3cold, enable);
1070         if (err)
1071                 goto out;
1072
1073         err = pci_enable_wake(dev, PCI_D3hot, enable);
1074
1075 out:
1076         return err;
1077 }
1078 #endif /* < 2.6.28 */
1079
1080 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) )
1081 void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
1082                          int off, int size)
1083 {
1084         skb_fill_page_desc(skb, i, page, off, size);
1085         skb->len += size;
1086         skb->data_len += size;
1087         skb->truesize += size;
1088 }
1089 #endif /* < 3.4.0 */
1090
1091 /*****************************************************************************/
1092 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) )
1093 #ifdef HAVE_NETDEV_SELECT_QUEUE
1094 #include <net/ip.h>
1095 static u32 _kc_simple_tx_hashrnd;
1096 static u32 _kc_simple_tx_hashrnd_initialized;
1097
1098 u16 _kc_skb_tx_hash(struct net_device *dev, struct sk_buff *skb)
1099 {
1100         u32 addr1, addr2, ports;
1101         u32 hash, ihl;
1102         u8 ip_proto = 0;
1103
1104         if (unlikely(!_kc_simple_tx_hashrnd_initialized)) {
1105                 get_random_bytes(&_kc_simple_tx_hashrnd, 4);
1106                 _kc_simple_tx_hashrnd_initialized = 1;
1107         }
1108
1109         switch (skb->protocol) {
1110         case htons(ETH_P_IP):
1111                 if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
1112                         ip_proto = ip_hdr(skb)->protocol;
1113                 addr1 = ip_hdr(skb)->saddr;
1114                 addr2 = ip_hdr(skb)->daddr;
1115                 ihl = ip_hdr(skb)->ihl;
1116                 break;
1117 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1118         case htons(ETH_P_IPV6):
1119                 ip_proto = ipv6_hdr(skb)->nexthdr;
1120                 addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
1121                 addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
1122                 ihl = (40 >> 2);
1123                 break;
1124 #endif
1125         default:
1126                 return 0;
1127         }
1128
1129
1130         switch (ip_proto) {
1131         case IPPROTO_TCP:
1132         case IPPROTO_UDP:
1133         case IPPROTO_DCCP:
1134         case IPPROTO_ESP:
1135         case IPPROTO_AH:
1136         case IPPROTO_SCTP:
1137         case IPPROTO_UDPLITE:
1138                 ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
1139                 break;
1140
1141         default:
1142                 ports = 0;
1143                 break;
1144         }
1145
1146         hash = jhash_3words(addr1, addr2, ports, _kc_simple_tx_hashrnd);
1147
1148         return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
1149 }
1150 #endif /* HAVE_NETDEV_SELECT_QUEUE */
1151 #endif /* < 2.6.30 */
1152
1153 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
1154 #ifdef HAVE_TX_MQ
1155 #ifndef CONFIG_NETDEVICES_MULTIQUEUE
1156 void _kc_netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
1157 {
1158         unsigned int real_num = dev->real_num_tx_queues;
1159         struct Qdisc *qdisc;
1160         int i;
1161
1162         if (unlikely(txq > dev->num_tx_queues))
1163                 ;
1164         else if (txq > real_num)
1165                 dev->real_num_tx_queues = txq;
1166         else if ( txq < real_num) {
1167                 dev->real_num_tx_queues = txq;
1168                 for (i = txq; i < dev->num_tx_queues; i++) {
1169                         qdisc = netdev_get_tx_queue(dev, i)->qdisc;
1170                         if (qdisc) {
1171                                 spin_lock_bh(qdisc_lock(qdisc));
1172                                 qdisc_reset(qdisc);
1173                                 spin_unlock_bh(qdisc_lock(qdisc));
1174                         }
1175                 }
1176         }
1177 }
1178 #endif /* CONFIG_NETDEVICES_MULTIQUEUE */
1179 #endif /* HAVE_TX_MQ */
1180 #endif /* < 2.6.35 */
1181
1182 /*****************************************************************************/
1183 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
1184 static const u32 _kc_flags_dup_features =
1185         (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH);
1186
1187 u32 _kc_ethtool_op_get_flags(struct net_device *dev)
1188 {
1189         return dev->features & _kc_flags_dup_features;
1190 }
1191
1192 int _kc_ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
1193 {
1194         if (data & ~supported)
1195                 return -EINVAL;
1196
1197         dev->features = ((dev->features & ~_kc_flags_dup_features) |
1198                          (data & _kc_flags_dup_features));
1199         return 0;
1200 }
1201 #endif /* < 2.6.36 */
1202
1203 /******************************************************************************/
1204 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) )
1205 #if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)))
1206 u8 _kc_netdev_get_num_tc(struct net_device *dev)
1207 {
1208         struct adapter_struct *kc_adapter = netdev_priv(dev);
1209         if (kc_adapter->flags & IXGBE_FLAG_DCB_ENABLED)
1210                 return kc_adapter->tc;
1211         else
1212                 return 0;
1213 }
1214
1215 u8 _kc_netdev_get_prio_tc_map(struct net_device *dev, u8 up)
1216 {
1217         struct adapter_struct *kc_adapter = netdev_priv(dev);
1218         int tc;
1219         u8 map;
1220
1221         for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
1222                 map = kc_adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap;
1223
1224                 if (map & (1 << up))
1225                         return tc;
1226         }
1227
1228         return 0;
1229 }
1230 #endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */
1231 #endif /* < 2.6.39 */