Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
netio_intf.h
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation, version 2.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  * NON INFRINGEMENT. See the GNU General Public License for
12  * more details.
13  */
14 
19 #ifndef __NETIO_INTF_H__
20 #define __NETIO_INTF_H__
21 
22 #include <hv/netio_errors.h>
23 
24 #ifdef __KERNEL__
25 #include <linux/types.h>
26 #else
27 #include <stdint.h>
28 #endif
29 
30 #if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__)
31 #include <assert.h>
32 #define netio_assert assert
33 #else
34 #define netio_assert(...) ((void)(0))
35 #endif
36 
37 /*
38  * If none of these symbols are defined, we're building libnetio in an
39  * environment where we have pthreads, so we'll enable locking.
40  */
41 #if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__) && \
42  !defined(__NEWLIB__)
43 #define _NETIO_PTHREAD
45 /*
46  * If NETIO_UNLOCKED is defined, we don't do use per-cpu locks on
47  * per-packet NetIO operations. We still do pthread locking on things
48  * like netio_input_register, though. This is used for building
49  * libnetio_unlocked.
50  */
51 #ifndef NETIO_UNLOCKED
52 
53 /* Avoid PLT overhead by using our own inlined per-cpu lock. */
54 #include <sched.h>
56 
57 static __inline int
58 _netio_percpu_mutex_init(_netio_percpu_mutex_t* lock)
59 {
60  *lock = 0;
61  return 0;
62 }
63 
64 static __inline int
65 _netio_percpu_mutex_lock(_netio_percpu_mutex_t* lock)
66 {
67  while (__builtin_expect(__insn_tns(lock), 0))
68  sched_yield();
69  return 0;
70 }
71 
72 static __inline int
73 _netio_percpu_mutex_unlock(_netio_percpu_mutex_t* lock)
74 {
75  *lock = 0;
76  return 0;
77 }
78 
79 #else /* NETIO_UNLOCKED */
80 
81 /* Don't do any locking for per-packet NetIO operations. */
82 typedef int _netio_percpu_mutex_t;
83 #define _netio_percpu_mutex_init(L)
84 #define _netio_percpu_mutex_lock(L)
85 #define _netio_percpu_mutex_unlock(L)
86 
87 #endif /* NETIO_UNLOCKED */
88 #endif /* !__HV__, !__BOGUX, !__KERNEL__, !__NEWLIB__ */
89 
92 #define NETIO_MAX_TILES_PER_QUEUE 64
93 
94 
97 #define NETIO_MAX_QUEUE_ID 255
98 
99 
100 #ifndef __DOXYGEN__
101 
102 /* Metadata packet checksum/ethertype flags. */
103 
105 #define _NETIO_PKT_NO_L4_CSUM_SHIFT 0
106 #define _NETIO_PKT_NO_L4_CSUM_RMASK 1
107 #define _NETIO_PKT_NO_L4_CSUM_MASK \
108  (_NETIO_PKT_NO_L4_CSUM_RMASK << _NETIO_PKT_NO_L4_CSUM_SHIFT)
109 
111 #define _NETIO_PKT_NO_L3_CSUM_SHIFT 1
112 #define _NETIO_PKT_NO_L3_CSUM_RMASK 1
113 #define _NETIO_PKT_NO_L3_CSUM_MASK \
114  (_NETIO_PKT_NO_L3_CSUM_RMASK << _NETIO_PKT_NO_L3_CSUM_SHIFT)
115 
117 #define _NETIO_PKT_BAD_L3_CSUM_SHIFT 2
118 #define _NETIO_PKT_BAD_L3_CSUM_RMASK 1
119 #define _NETIO_PKT_BAD_L3_CSUM_MASK \
120  (_NETIO_PKT_BAD_L3_CSUM_RMASK << _NETIO_PKT_BAD_L3_CSUM_SHIFT)
121 
123 #define _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT 3
124 #define _NETIO_PKT_TYPE_UNRECOGNIZED_RMASK 1
125 #define _NETIO_PKT_TYPE_UNRECOGNIZED_MASK \
126  (_NETIO_PKT_TYPE_UNRECOGNIZED_RMASK << \
127  _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT)
128 
129 /* Metadata packet type flags. */
130 
133 #define _NETIO_PKT_TYPE_SHIFT 4
134 #define _NETIO_PKT_TYPE_RMASK 0x3F
135 
139 #define _NETIO_PKT_VLAN_SHIFT 4
140 #define _NETIO_PKT_VLAN_RMASK 0x3
141 #define _NETIO_PKT_VLAN_MASK \
142  (_NETIO_PKT_VLAN_RMASK << _NETIO_PKT_VLAN_SHIFT)
143 #define _NETIO_PKT_VLAN_NONE 0 /* No VLAN tag. */
144 #define _NETIO_PKT_VLAN_ONE 1 /* One VLAN tag. */
145 #define _NETIO_PKT_VLAN_TWO_OUTER 2 /* Two VLAN tags, outer one used. */
146 #define _NETIO_PKT_VLAN_TWO_INNER 3 /* Two VLAN tags, inner one used. */
147 
149 #define _NETIO_PKT_TAG_SHIFT 6
150 #define _NETIO_PKT_TAG_RMASK 0x3
151 #define _NETIO_PKT_TAG_MASK \
152  (_NETIO_PKT_TAG_RMASK << _NETIO_PKT_TAG_SHIFT)
153 #define _NETIO_PKT_TAG_NONE 0 /* No proprietary tags. */
154 #define _NETIO_PKT_TAG_MRVL 1 /* Marvell HyperG.Stack tags. */
155 #define _NETIO_PKT_TAG_MRVL_EXT 2 /* HyperG.Stack extended tags. */
156 #define _NETIO_PKT_TAG_BRCM 3 /* Broadcom HiGig tags. */
157 
159 #define _NETIO_PKT_SNAP_SHIFT 8
160 #define _NETIO_PKT_SNAP_RMASK 0x1
161 #define _NETIO_PKT_SNAP_MASK \
162  (_NETIO_PKT_SNAP_RMASK << _NETIO_PKT_SNAP_SHIFT)
163 
164 /* NOTE: Bits 9 and 10 are unused. */
165 
167 #define _NETIO_PKT_CUSTOM_LEN_SHIFT 11
168 #define _NETIO_PKT_CUSTOM_LEN_RMASK 0x1F
169 #define _NETIO_PKT_CUSTOM_LEN_MASK \
170  (_NETIO_PKT_CUSTOM_LEN_RMASK << _NETIO_PKT_CUSTOM_LEN_SHIFT)
171 
173 #define _NETIO_PKT_BAD_L4_CSUM_SHIFT 16
174 #define _NETIO_PKT_BAD_L4_CSUM_RMASK 0x1
175 #define _NETIO_PKT_BAD_L4_CSUM_MASK \
176  (_NETIO_PKT_BAD_L4_CSUM_RMASK << _NETIO_PKT_BAD_L4_CSUM_SHIFT)
177 
179 #define _NETIO_PKT_L2_LEN_SHIFT 17
180 #define _NETIO_PKT_L2_LEN_RMASK 0x1F
181 #define _NETIO_PKT_L2_LEN_MASK \
182  (_NETIO_PKT_L2_LEN_RMASK << _NETIO_PKT_L2_LEN_SHIFT)
183 
184 
185 /* Flags in minimal packet metadata. */
186 
188 #define _NETIO_PKT_NEED_EDMA_CSUM_SHIFT 0
189 #define _NETIO_PKT_NEED_EDMA_CSUM_RMASK 1
190 #define _NETIO_PKT_NEED_EDMA_CSUM_MASK \
191  (_NETIO_PKT_NEED_EDMA_CSUM_RMASK << _NETIO_PKT_NEED_EDMA_CSUM_SHIFT)
192 
193 /* Data within the packet information table. */
194 
195 /* Note that, for efficiency, code which uses these fields assumes that none
196  * of the shift values below are zero. See uses below for an explanation. */
197 
199 #define _NETIO_PKT_INFO_ETYPE_SHIFT 6
200 #define _NETIO_PKT_INFO_ETYPE_RMASK 0x1F
201 
203 #define _NETIO_PKT_INFO_VLAN_SHIFT 11
204 #define _NETIO_PKT_INFO_VLAN_RMASK 0x1F
205 
206 #endif
207 
208 
211 #define SMALL_PACKET_SIZE 256
212 
215 #define LARGE_PACKET_SIZE 2048
216 
219 #define JUMBO_PACKET_SIZE (12 * 1024)
220 
221 
222 /* Common ethertypes.
223  * @ingroup ingress */
226 #define ETHERTYPE_IPv4 (0x0800)
227 
228 #define ETHERTYPE_ARP (0x0806)
229 
230 #define ETHERTYPE_VLAN (0x8100)
231 
232 #define ETHERTYPE_Q_IN_Q (0x9100)
233 
234 #define ETHERTYPE_IPv6 (0x86DD)
235 
236 #define ETHERTYPE_MPLS (0x8847)
237 
243 typedef enum
244 {
260 
261 
263 #define NETIO_LOG2_NUM_BUCKETS (10)
264 
267 #define NETIO_NUM_BUCKETS (1 << NETIO_LOG2_NUM_BUCKETS)
268 
269 
277 typedef union {
279  struct {
281  unsigned int __balance_on_l4:1;
283  unsigned int __balance_on_l3:1;
285  unsigned int __balance_on_l2:1;
287  unsigned int __reserved:1;
289  unsigned int __bucket_base:NETIO_LOG2_NUM_BUCKETS;
293  unsigned int __bucket_mask:NETIO_LOG2_NUM_BUCKETS;
295  unsigned int __padding:(32 - 4 - 2 * NETIO_LOG2_NUM_BUCKETS);
296  } bits;
298  unsigned int word;
299 }
301 
302 
311 
312 
317 typedef unsigned char netio_bucket_t;
318 
319 
324 typedef unsigned int netio_size_t;
325 
326 
339 typedef struct
340 {
341 #ifdef __DOXYGEN__
342 
343  unsigned char opaque[24];
344 #else
345 
346  unsigned int __packet_ordinal;
348  unsigned int __group_ordinal;
350  unsigned int __flow_hash;
352  unsigned int __flags;
354  unsigned int __user_data_0;
356  unsigned int __user_data_1;
357 #endif
358 }
360 
361 
367 #define NETIO_PACKET_PADDING 2
368 
369 
370 
384 typedef struct
385 {
386 #ifdef __DOXYGEN__
387 
388  unsigned char opaque[14];
389 #else
390 
391  unsigned short l2_offset;
393  unsigned short l3_offset;
395  unsigned char csum_location;
397  unsigned char csum_start;
399  unsigned short flags;
401  unsigned short l2_length;
403  unsigned short csum_seed;
405  unsigned short csum_length;
406 #endif
407 }
409 
410 
411 #ifndef __DOXYGEN__
412 
419 typedef union
420 {
421  unsigned int word;
423  struct
424  {
425  unsigned int __channel:7;
426  unsigned int __type:4;
427  unsigned int __ack:1;
428  unsigned int __reserved:1;
429  unsigned int __protocol:1;
430  unsigned int __status:2;
431  unsigned int __framing:2;
432  unsigned int __transfer_size:14;
433  } bits;
434 }
436 
437 
441 #define _NETIO_PKT_HANDLE_BASE(p) \
442  ((unsigned char*)((p).word & 0xFFFFFFC0))
443 
447 #define _NETIO_PKT_BASE(p) \
448  _NETIO_PKT_HANDLE_BASE(p->__packet)
449 
465 typedef union
466 {
467  unsigned int word;
469  struct
470  {
473  unsigned int __queue:2;
474 
476  unsigned int __ipp_handle:2;
477 
479  unsigned int __reserved:1;
480 
483  unsigned int __minimal:1;
484 
489  unsigned int __offset:2;
490 
492  unsigned int __addr:24;
493  } bits;
494 }
496 
497 #endif /* !__DOXYGEN__ */
498 
499 
522 typedef struct
523 {
524  unsigned int word;
526 
553 typedef struct
554 {
555 #ifdef __DOXYGEN__
556 
557  unsigned char opaque[32];
558 #else
559 
564 
567 
570 #endif
571 }
573 
574 
575 #ifndef __DOXYGEN__
576 
577 #define __NETIO_PKT_NOTIF_HEADER(pkt) ((pkt)->__notif_header)
578 #define __NETIO_PKT_IPP_HANDLE(pkt) ((pkt)->__packet.bits.__ipp_handle)
579 #define __NETIO_PKT_QUEUE(pkt) ((pkt)->__packet.bits.__queue)
580 #define __NETIO_PKT_NOTIF_HEADER_M(mda, pkt) ((pkt)->__notif_header)
581 #define __NETIO_PKT_IPP_HANDLE_M(mda, pkt) ((pkt)->__packet.bits.__ipp_handle)
582 #define __NETIO_PKT_MINIMAL(pkt) ((pkt)->__packet.bits.__minimal)
583 #define __NETIO_PKT_QUEUE_M(mda, pkt) ((pkt)->__packet.bits.__queue)
584 #define __NETIO_PKT_FLAGS_M(mda, pkt) ((mda)->__flags)
585 
586 /* Packet information table, used by the attribute access functions below. */
587 extern const uint16_t _netio_pkt_info[];
588 
589 #endif /* __DOXYGEN__ */
590 
591 
592 #ifndef __DOXYGEN__
593 /* These macros are deprecated and will disappear in a future MDE release. */
594 #define NETIO_PKT_GOOD_CHECKSUM(pkt) \
595  NETIO_PKT_L4_CSUM_CORRECT(pkt)
596 #define NETIO_PKT_GOOD_CHECKSUM_M(mda, pkt) \
597  NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt)
598 #endif /* __DOXYGEN__ */
599 
600 
601 /* Packet attribute access functions. */
602 
617 NETIO_PKT_METADATA(netio_pkt_t* pkt)
618 {
619  netio_assert(!pkt->__packet.bits.__minimal);
620  return &pkt->__metadata;
621 }
622 
623 
638 NETIO_PKT_MINIMAL_METADATA(netio_pkt_t* pkt)
639 {
640  netio_assert(pkt->__packet.bits.__minimal);
642 }
643 
644 
658 static __inline unsigned int
659 NETIO_PKT_IS_MINIMAL(netio_pkt_t* pkt)
660 {
661  return pkt->__packet.bits.__minimal;
662 }
663 
664 
672 NETIO_PKT_HANDLE(netio_pkt_t* pkt)
673 {
675  h.word = pkt->__packet.word;
676  return h;
677 }
678 
679 
684 #define NETIO_PKT_HANDLE_NONE ((netio_pkt_handle_t) { 0 })
685 
686 
698 static __inline unsigned int
699 NETIO_PKT_HANDLE_IS_VALID(netio_pkt_handle_t handle)
700 {
701  return handle.word != 0;
702 }
703 
704 
705 
716 static __inline unsigned char*
717 NETIO_PKT_CUSTOM_DATA_H(netio_pkt_handle_t handle)
718 {
720 }
721 
722 
735 static __inline netio_size_t
736 NETIO_PKT_CUSTOM_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
737 {
738  /*
739  * Note that we effectively need to extract a quantity from the flags word
740  * which is measured in words, and then turn it into bytes by shifting
741  * it left by 2. We do this all at once by just shifting right two less
742  * bits, and shifting the mask up two bits.
743  */
744  return ((mda->__flags >> (_NETIO_PKT_CUSTOM_LEN_SHIFT - 2)) &
746 }
747 
748 
760 static __inline netio_size_t
761 NETIO_PKT_CUSTOM_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
762 {
763  return (__NETIO_PKT_NOTIF_HEADER(pkt).bits.__transfer_size -
765 }
766 
767 
779 static __inline unsigned char*
780 NETIO_PKT_CUSTOM_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
781 {
782  return NETIO_PKT_CUSTOM_DATA_H(NETIO_PKT_HANDLE(pkt));
783 }
784 
785 
793 static __inline netio_size_t
794 NETIO_PKT_L2_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
795 {
796  /*
797  * Note that we effectively need to extract a quantity from the flags word
798  * which is measured in words, and then turn it into bytes by shifting
799  * it left by 2. We do this all at once by just shifting right two less
800  * bits, and shifting the mask up two bits. We then add two bytes.
801  */
802  return ((mda->__flags >> (_NETIO_PKT_L2_LEN_SHIFT - 2)) &
803  (_NETIO_PKT_L2_LEN_RMASK << 2)) + 2;
804 }
805 
806 
814 static __inline netio_size_t
815 NETIO_PKT_L2_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
816 {
817  return (NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt) -
818  NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda,pkt));
819 }
820 
821 
829 static __inline unsigned char*
830 NETIO_PKT_L2_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
831 {
832  return (NETIO_PKT_CUSTOM_DATA_M(mda, pkt) +
833  NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt));
834 }
835 
836 
845 static __inline netio_size_t
846 NETIO_PKT_L3_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
847 {
848  return (NETIO_PKT_L2_LENGTH_M(mda, pkt) -
849  NETIO_PKT_L2_HEADER_LENGTH_M(mda,pkt));
850 }
851 
852 
862 static __inline unsigned char*
863 NETIO_PKT_L3_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
864 {
865  return (NETIO_PKT_L2_DATA_M(mda, pkt) +
866  NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt));
867 }
868 
869 
887 static __inline unsigned int
888 NETIO_PKT_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
889 {
890  return mda->__packet_ordinal;
891 }
892 
893 
915 static __inline unsigned int
916 NETIO_PKT_GROUP_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
917 {
918  return mda->__group_ordinal;
919 }
920 
921 
934 static __inline unsigned short
935 NETIO_PKT_VLAN_ID_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
936 {
938  unsigned short* pkt_p;
939  int index;
940  unsigned short val;
941 
942  if (vl == _NETIO_PKT_VLAN_NONE)
943  return 0;
944 
945  pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt);
947 
948  val = pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_VLAN_SHIFT) &
950 
951 #ifdef __TILECC__
952  return (__insn_bytex(val) >> 16) & 0xFFF;
953 #else
954  return (__builtin_bswap32(val) >> 16) & 0xFFF;
955 #endif
956 }
957 
958 
971 static __inline unsigned short
972 NETIO_PKT_ETHERTYPE_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
973 {
974  unsigned short* pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt);
975  int index = (mda->__flags >> _NETIO_PKT_TYPE_SHIFT) & _NETIO_PKT_TYPE_RMASK;
976 
977  unsigned short val =
978  pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_ETYPE_SHIFT) &
980 
981  return __builtin_bswap32(val) >> 16;
982 }
983 
984 
1014 static __inline unsigned int
1015 NETIO_PKT_FLOW_HASH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1016 {
1017  return mda->__flow_hash;
1018 }
1019 
1020 
1037 static __inline unsigned int
1038 NETIO_PKT_USER_DATA_0_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1039 {
1040  return mda->__user_data_0;
1041 }
1042 
1043 
1060 static __inline unsigned int
1061 NETIO_PKT_USER_DATA_1_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1062 {
1063  return mda->__user_data_1;
1064 }
1065 
1066 
1074 static __inline unsigned int
1075 NETIO_PKT_L4_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1076 {
1077  return !(mda->__flags & _NETIO_PKT_NO_L4_CSUM_MASK);
1078 }
1079 
1080 
1089 static __inline unsigned int
1090 NETIO_PKT_L4_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1091 {
1092  return !(mda->__flags &
1094 }
1095 
1096 
1104 static __inline unsigned int
1105 NETIO_PKT_L3_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1106 {
1107  return !(mda->__flags & _NETIO_PKT_NO_L3_CSUM_MASK);
1108 }
1109 
1110 
1119 static __inline unsigned int
1120 NETIO_PKT_L3_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1121 {
1122  return !(mda->__flags &
1124 }
1125 
1126 
1136 static __inline unsigned int
1137 NETIO_PKT_ETHERTYPE_RECOGNIZED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1138 {
1139  return !(mda->__flags & _NETIO_PKT_TYPE_UNRECOGNIZED_MASK);
1140 }
1141 
1142 
1158 NETIO_PKT_STATUS_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1159 {
1160  return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status;
1161 }
1162 
1163 
1174 static __inline unsigned int
1175 NETIO_PKT_BAD_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1176 {
1177  return ((NETIO_PKT_STATUS_M(mda, pkt) & 1) &&
1178  (NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt) ||
1179  NETIO_PKT_STATUS_M(mda, pkt) == NETIO_PKT_STATUS_BAD));
1180 }
1181 
1182 
1190 static __inline netio_size_t
1191 NETIO_PKT_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
1192 {
1193  return mmd->l2_length;
1194 }
1195 
1196 
1204 static __inline netio_size_t
1205 NETIO_PKT_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd,
1206  netio_pkt_t* pkt)
1207 {
1208  return mmd->l3_offset - mmd->l2_offset;
1209 }
1210 
1211 
1219 static __inline netio_size_t
1220 NETIO_PKT_L3_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
1221 {
1222  return (NETIO_PKT_L2_LENGTH_MM(mmd, pkt) -
1223  NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt));
1224 }
1225 
1226 
1236 static __inline unsigned char*
1237 NETIO_PKT_L3_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
1238 {
1239  return _NETIO_PKT_BASE(pkt) + mmd->l3_offset;
1240 }
1241 
1242 
1250 static __inline unsigned char*
1251 NETIO_PKT_L2_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
1252 {
1253  return _NETIO_PKT_BASE(pkt) + mmd->l2_offset;
1254 }
1255 
1256 
1271 NETIO_PKT_STATUS(netio_pkt_t* pkt)
1272 {
1273  netio_assert(!pkt->__packet.bits.__minimal);
1274 
1275  return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status;
1276 }
1277 
1278 
1288 static __inline unsigned int
1289 NETIO_PKT_BAD(netio_pkt_t* pkt)
1290 {
1291  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1292 
1293  return NETIO_PKT_BAD_M(mda, pkt);
1294 }
1295 
1296 
1307 static __inline netio_size_t
1308 NETIO_PKT_CUSTOM_HEADER_LENGTH(netio_pkt_t* pkt)
1309 {
1310  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1311 
1312  return NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt);
1313 }
1314 
1315 
1326 static __inline netio_size_t
1327 NETIO_PKT_CUSTOM_LENGTH(netio_pkt_t* pkt)
1328 {
1329  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1330 
1331  return NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt);
1332 }
1333 
1334 
1345 static __inline unsigned char*
1346 NETIO_PKT_CUSTOM_DATA(netio_pkt_t* pkt)
1347 {
1348  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1349 
1350  return NETIO_PKT_CUSTOM_DATA_M(mda, pkt);
1351 }
1352 
1353 
1360 static __inline netio_size_t
1361 NETIO_PKT_L2_HEADER_LENGTH(netio_pkt_t* pkt)
1362 {
1363  if (NETIO_PKT_IS_MINIMAL(pkt))
1364  {
1365  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1366 
1367  return NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt);
1368  }
1369  else
1370  {
1371  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1372 
1373  return NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt);
1374  }
1375 }
1376 
1377 
1384 static __inline netio_size_t
1385 NETIO_PKT_L2_LENGTH(netio_pkt_t* pkt)
1386 {
1387  if (NETIO_PKT_IS_MINIMAL(pkt))
1388  {
1389  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1390 
1391  return NETIO_PKT_L2_LENGTH_MM(mmd, pkt);
1392  }
1393  else
1394  {
1395  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1396 
1397  return NETIO_PKT_L2_LENGTH_M(mda, pkt);
1398  }
1399 }
1400 
1401 
1408 static __inline unsigned char*
1409 NETIO_PKT_L2_DATA(netio_pkt_t* pkt)
1410 {
1411  if (NETIO_PKT_IS_MINIMAL(pkt))
1412  {
1413  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1414 
1415  return NETIO_PKT_L2_DATA_MM(mmd, pkt);
1416  }
1417  else
1418  {
1419  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1420 
1421  return NETIO_PKT_L2_DATA_M(mda, pkt);
1422  }
1423 }
1424 
1425 
1433 static __inline netio_size_t
1434 NETIO_PKT_L3_LENGTH(netio_pkt_t* pkt)
1435 {
1436  if (NETIO_PKT_IS_MINIMAL(pkt))
1437  {
1438  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1439 
1440  return NETIO_PKT_L3_LENGTH_MM(mmd, pkt);
1441  }
1442  else
1443  {
1444  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1445 
1446  return NETIO_PKT_L3_LENGTH_M(mda, pkt);
1447  }
1448 }
1449 
1450 
1459 static __inline unsigned char*
1460 NETIO_PKT_L3_DATA(netio_pkt_t* pkt)
1461 {
1462  if (NETIO_PKT_IS_MINIMAL(pkt))
1463  {
1464  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1465 
1466  return NETIO_PKT_L3_DATA_MM(mmd, pkt);
1467  }
1468  else
1469  {
1470  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1471 
1472  return NETIO_PKT_L3_DATA_M(mda, pkt);
1473  }
1474 }
1475 
1476 
1494 static __inline unsigned int
1495 NETIO_PKT_ORDINAL(netio_pkt_t* pkt)
1496 {
1497  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1498 
1499  return NETIO_PKT_ORDINAL_M(mda, pkt);
1500 }
1501 
1502 
1523 static __inline unsigned int
1524 NETIO_PKT_GROUP_ORDINAL(netio_pkt_t* pkt)
1525 {
1526  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1527 
1528  return NETIO_PKT_GROUP_ORDINAL_M(mda, pkt);
1529 }
1530 
1531 
1541 static __inline unsigned short
1542 NETIO_PKT_VLAN_ID(netio_pkt_t* pkt)
1543 {
1544  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1545 
1546  return NETIO_PKT_VLAN_ID_M(mda, pkt);
1547 }
1548 
1549 
1559 static __inline unsigned short
1560 NETIO_PKT_ETHERTYPE(netio_pkt_t* pkt)
1561 {
1562  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1563 
1564  return NETIO_PKT_ETHERTYPE_M(mda, pkt);
1565 }
1566 
1567 
1596 static __inline unsigned int
1597 NETIO_PKT_FLOW_HASH(netio_pkt_t* pkt)
1598 {
1599  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1600 
1601  return NETIO_PKT_FLOW_HASH_M(mda, pkt);
1602 }
1603 
1604 
1620 static __inline unsigned int
1621 NETIO_PKT_USER_DATA_0(netio_pkt_t* pkt)
1622 {
1623  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1624 
1625  return NETIO_PKT_USER_DATA_0_M(mda, pkt);
1626 }
1627 
1628 
1644 static __inline unsigned int
1645 NETIO_PKT_USER_DATA_1(netio_pkt_t* pkt)
1646 {
1647  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1648 
1649  return NETIO_PKT_USER_DATA_1_M(mda, pkt);
1650 }
1651 
1652 
1659 static __inline unsigned int
1660 NETIO_PKT_L4_CSUM_CALCULATED(netio_pkt_t* pkt)
1661 {
1662  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1663 
1664  return NETIO_PKT_L4_CSUM_CALCULATED_M(mda, pkt);
1665 }
1666 
1667 
1675 static __inline unsigned int
1676 NETIO_PKT_L4_CSUM_CORRECT(netio_pkt_t* pkt)
1677 {
1678  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1679 
1680  return NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt);
1681 }
1682 
1683 
1690 static __inline unsigned int
1691 NETIO_PKT_L3_CSUM_CALCULATED(netio_pkt_t* pkt)
1692 {
1693  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1694 
1695  return NETIO_PKT_L3_CSUM_CALCULATED_M(mda, pkt);
1696 }
1697 
1698 
1706 static __inline unsigned int
1707 NETIO_PKT_L3_CSUM_CORRECT(netio_pkt_t* pkt)
1708 {
1709  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1710 
1711  return NETIO_PKT_L3_CSUM_CORRECT_M(mda, pkt);
1712 }
1713 
1714 
1723 static __inline unsigned int
1724 NETIO_PKT_ETHERTYPE_RECOGNIZED(netio_pkt_t* pkt)
1725 {
1726  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1727 
1728  return NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt);
1729 }
1730 
1731 
1740 static __inline void
1741 NETIO_PKT_SET_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt,
1742  int len)
1743 {
1744  mmd->l2_length = len;
1745 }
1746 
1747 
1754 static __inline void
1755 NETIO_PKT_SET_L2_LENGTH(netio_pkt_t* pkt, int len)
1756 {
1757  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1758 
1759  NETIO_PKT_SET_L2_LENGTH_MM(mmd, pkt, len);
1760 }
1761 
1762 
1776 static __inline void
1777 NETIO_PKT_SET_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd,
1778  netio_pkt_t* pkt, int len)
1779 {
1780  mmd->l3_offset = mmd->l2_offset + len;
1781 }
1782 
1783 
1795 static __inline void
1796 NETIO_PKT_SET_L2_HEADER_LENGTH(netio_pkt_t* pkt, int len)
1797 {
1798  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1799 
1800  NETIO_PKT_SET_L2_HEADER_LENGTH_MM(mmd, pkt, len);
1801 }
1802 
1803 
1841 static __inline void
1842 NETIO_PKT_DO_EGRESS_CSUM_MM(netio_pkt_minimal_metadata_t* mmd,
1843  netio_pkt_t* pkt, int start, int length,
1844  int location, uint16_t seed)
1845 {
1846  mmd->csum_start = start;
1847  mmd->csum_length = length;
1848  mmd->csum_location = location;
1849  mmd->csum_seed = seed;
1851 }
1852 
1853 
1889 static __inline void
1890 NETIO_PKT_DO_EGRESS_CSUM(netio_pkt_t* pkt, int start, int length,
1891  int location, uint16_t seed)
1892 {
1893  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1894 
1895  NETIO_PKT_DO_EGRESS_CSUM_MM(mmd, pkt, start, length, location, seed);
1896 }
1897 
1898 
1907 static __inline int
1908 NETIO_PKT_PREPEND_AVAIL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
1909 {
1910  return (pkt->__packet.bits.__offset << 6) +
1911  NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt);
1912 }
1913 
1914 
1924 static __inline int
1925 NETIO_PKT_PREPEND_AVAIL_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
1926 {
1927  return (pkt->__packet.bits.__offset << 6) + mmd->l2_offset;
1928 }
1929 
1930 
1938 static __inline int
1939 NETIO_PKT_PREPEND_AVAIL(netio_pkt_t* pkt)
1940 {
1941  if (NETIO_PKT_IS_MINIMAL(pkt))
1942  {
1943  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
1944 
1945  return NETIO_PKT_PREPEND_AVAIL_MM(mmd, pkt);
1946  }
1947  else
1948  {
1949  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
1950 
1951  return NETIO_PKT_PREPEND_AVAIL_M(mda, pkt);
1952  }
1953 }
1954 
1955 
1963 static __inline void
1964 NETIO_PKT_FLUSH_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
1965  netio_pkt_t* pkt)
1966 {
1967 }
1968 
1969 
1977 static __inline void
1978 NETIO_PKT_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
1979  netio_pkt_t* pkt)
1980 {
1981 }
1982 
1983 
1991 static __inline void
1992 NETIO_PKT_FLUSH_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
1993  netio_pkt_t* pkt)
1994 {
1995 }
1996 
1997 
2005 static __inline void
2006 NETIO_PKT_FLUSH_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
2007 {
2008 }
2009 
2010 
2018 static __inline void
2019 NETIO_PKT_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
2020 {
2021 }
2022 
2023 
2031 static __inline void
2032 NETIO_PKT_FLUSH_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
2033 {
2034 }
2035 
2036 
2042 static __inline void
2043 NETIO_PKT_FLUSH_MINIMAL_METADATA(netio_pkt_t* pkt)
2044 {
2045 }
2046 
2047 
2053 static __inline void
2054 NETIO_PKT_INV_MINIMAL_METADATA(netio_pkt_t* pkt)
2055 {
2056 }
2057 
2058 
2064 static __inline void
2065 NETIO_PKT_FLUSH_INV_MINIMAL_METADATA(netio_pkt_t* pkt)
2066 {
2067 }
2068 
2069 
2075 static __inline void
2076 NETIO_PKT_FLUSH_METADATA(netio_pkt_t* pkt)
2077 {
2078 }
2079 
2080 
2086 static __inline void
2087 NETIO_PKT_INV_METADATA(netio_pkt_t* pkt)
2088 {
2089 }
2090 
2091 
2097 static __inline void
2098 NETIO_PKT_FLUSH_INV_METADATA(netio_pkt_t* pkt)
2099 {
2100 }
2101 
2104 #define NETIO_NUM_NODE_WEIGHTS 16
2105 
2184 typedef struct
2185 {
2227  int flags;
2228 
2235  const char* interface;
2236 
2249 
2258  unsigned int queue_id;
2259 
2270 
2279 
2289 
2298 
2308 
2317 
2342 
2406  uint8_t buffer_node_weights[NETIO_NUM_NODE_WEIGHTS];
2407 
2413 
2441 }
2443 
2444 
2452 #define NETIO_STRICT_HOMING 0x00000002
2453 
2455 #define NETIO_TAG_NONE 0x00000004
2456 
2458 #define NETIO_TAG_MRVL 0x00000008
2459 
2461 #define NETIO_TAG_BRCM 0x00000010
2462 
2464 #define NETIO_RECV 0x00000020
2465 
2467 #define NETIO_NO_RECV 0x00000040
2468 
2470 #define NETIO_XMIT 0x00000080
2471 
2474 #define NETIO_XMIT_CSUM 0x00000100
2475 
2477 #define NETIO_NO_XMIT 0x00000200
2478 
2504 #define NETIO_FIXED_BUFFER_VA 0x00000400
2505 
2521 #define NETIO_REQUIRE_LINK_UP 0x00000800
2522 
2531 #define NETIO_NOREQUIRE_LINK_UP 0x00001000
2532 
2533 #ifndef __DOXYGEN__
2534 /*
2535  * These are part of the implementation of the NETIO_AUTO_LINK_xxx flags,
2536  * but should not be used directly by applications, and are thus not
2537  * documented.
2538  */
2539 #define _NETIO_AUTO_UP 0x00002000
2540 #define _NETIO_AUTO_DN 0x00004000
2541 #define _NETIO_AUTO_PRESENT 0x00008000
2542 #endif
2543 
2551 #define NETIO_AUTO_LINK_UP (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP)
2552 
2560 #define NETIO_AUTO_LINK_UPDN (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP | \
2561  _NETIO_AUTO_DN)
2562 
2568 #define NETIO_AUTO_LINK_DN (_NETIO_AUTO_PRESENT | _NETIO_AUTO_DN)
2569 
2575 #define NETIO_AUTO_LINK_NONE _NETIO_AUTO_PRESENT
2576 
2577 
2579 #define NETIO_MIN_RECEIVE_PKTS 16
2580 
2583 #define NETIO_MAX_RECEIVE_PKTS 128
2584 
2586 #define NETIO_MAX_SEND_BUFFERS 16
2587 
2589 #define NETIO_TOTAL_SENDS_OUTSTANDING 2015
2590 
2593 #define NETIO_MIN_SENDS_OUTSTANDING 16
2594 
2595 
2598 #ifndef __DOXYGEN__
2599 
2603 struct __netio_queue_impl_t;
2604 
2609 
2610 #endif /* !__DOXYGEN__ */
2611 
2612 
2616 typedef struct
2617 {
2618 #ifdef __DOXYGEN__
2619  uint8_t opaque[8];
2620 #else
2623 #ifdef _NETIO_PTHREAD
2624  _netio_percpu_mutex_t lock;
2625 #endif
2626 #endif
2627 }
2629 
2630 
2638 typedef struct
2639 {
2640 #ifdef __DOXYGEN__
2641  uint8_t opaque[44];
2642 #else
2650 #endif
2651 }
2653 
2654 
2655 #ifndef __DOXYGEN__
2656 #define SEND_PKT_CTX_USE_EPP 1
2657 #define SEND_PKT_CTX_SEND_CSUM 2
2658 #endif
2659 
2673 typedef struct
2674 #ifndef __DOXYGEN__
2676 #endif
2677 {
2684 
2685  /* Structure members below this point should not be accessed directly by
2686  * applications, as they may change in the future. */
2687 
2690  uint8_t buffer_address_low;
2691 
2693  uint16_t size;
2694 
2698 }
2700 
2701 
2721 static __inline void
2722 netio_pkt_vector_set(volatile netio_pkt_vector_entry_t* v, netio_pkt_t* pkt,
2724 {
2725  if (pkt)
2726  {
2727  if (NETIO_PKT_IS_MINIMAL(pkt))
2728  {
2731  v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_MM(mmd, pkt) & 0xFF;
2732  v->size = NETIO_PKT_L2_LENGTH_MM(mmd, pkt);
2733  }
2734  else
2735  {
2736  netio_pkt_metadata_t* mda = &pkt->__metadata;
2737  v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_M(mda, pkt) & 0xFF;
2738  v->size = NETIO_PKT_L2_LENGTH_M(mda, pkt);
2739  }
2740  v->handle.word = pkt->__packet.word;
2741  }
2742  else
2743  {
2744  v->handle.word = 0; /* Set handle to NETIO_PKT_HANDLE_NONE. */
2745  }
2746 
2747  __asm__("" : : : "memory");
2748 
2749  v->user_data = user_data;
2750 }
2751 
2752 
2760 #define NETIO_PARAM 0
2761 
2764 #define NETIO_PARAM_MAC 0
2765 
2769 #define NETIO_PARAM_PAUSE_IN 1
2770 
2775 #define NETIO_PARAM_PAUSE_OUT 2
2776 
2780 #define NETIO_PARAM_JUMBO 3
2781 
2790 #define NETIO_PARAM_OVERFLOW 4
2791 
2796 #define NETIO_PARAM_STAT 5
2797 
2806 #define NETIO_PARAM_LINK_POSSIBLE_STATE 6
2807 
2819 #define NETIO_PARAM_LINK_CONFIG NETIO_PARAM_LINK_POSSIBLE_STATE
2820 
2827 #define NETIO_PARAM_LINK_CURRENT_STATE 7
2828 
2831 #define NETIO_PARAM_LINK_STATUS NETIO_PARAM_LINK_CURRENT_STATE
2832 
2836 #define NETIO_PARAM_COHERENT 8
2837 
2855 #define NETIO_PARAM_LINK_DESIRED_STATE 9
2856 
2859 typedef struct
2860 {
2865 
2874 
2875  /*
2876  * Note: the #defines after each of the following four one-byte values
2877  * denote their location within the third word of the netio_stat_t. They
2878  * are intended for use only by the IPP implementation and are thus omitted
2879  * from the Doxygen output.
2880  */
2881 
2886 #ifndef __DOXYGEN__
2887 #define NETIO_STAT_DROPS_NO_WORKER 0
2888 #endif
2889 
2893 #ifndef __DOXYGEN__
2894 #define NETIO_STAT_DROPS_NO_SMALLBUF 1
2895 #endif
2896 
2900 #ifndef __DOXYGEN__
2901 #define NETIO_STAT_DROPS_NO_LARGEBUF 2
2902 #endif
2903 
2907 #ifndef __DOXYGEN__
2908 #define NETIO_STAT_DROPS_NO_JUMBOBUF 3
2909 #endif
2910 }
2911 netio_stat_t;
2912 
2913 
2915 #define NETIO_LINK_10M 0x01
2916 
2918 #define NETIO_LINK_100M 0x02
2919 
2921 #define NETIO_LINK_1G 0x04
2922 
2924 #define NETIO_LINK_10G 0x08
2925 
2930 #define NETIO_LINK_ANYSPEED 0x10
2931 
2933 #define NETIO_LINK_SPEED (NETIO_LINK_10M | \
2934  NETIO_LINK_100M | \
2935  NETIO_LINK_1G | \
2936  NETIO_LINK_10G | \
2937  NETIO_LINK_ANYSPEED)
2938 
2939 
2944 #define NETIO_MAC 1
2945 
2948 #define NETIO_MDIO 2
2949 
2952 #define NETIO_MDIO_CLAUSE45 3
2953 
2956 typedef union
2957 {
2958  struct
2959  {
2960  unsigned int reg:16;
2962  unsigned int phy:5;
2963  unsigned int dev:5;
2966  }
2967  bits;
2970 }
2972 
2975 #endif /* __NETIO_INTF_H__ */