blob: c6feffffa9b88aa08781a3f7935df35443794f85 [file] [log] [blame]
Robert Mustacchid14abf12014-06-06 22:58:53 +00001/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2014 QLogic Corporation
24 * The contents of this file are subject to the terms of the
25 * QLogic End User License (the "License").
26 * You may not use this file except in compliance with the License.
27 *
28 * You can obtain a copy of the License at
29 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30 * QLogic_End_User_Software_License.txt
31 * See the License for the specific language governing permissions
32 * and limitations under the License.
33 */
34
35/*
36 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37 */
38
39#include "bnxe.h"
40
41int BnxeRouteTxRing(um_device_t * pUM,
42 mblk_t * pMblk)
43{
44 u32_t numRings = pUM->devParams.numRings;
45 int ring = 0;
46 uint8_t * pHdr;
47 mblk_t * pTmpMblk;
48 size_t mblkLen;
49 ushort_t etype;
50 size_t eHdrSize;
51
52 if (!numRings)
53 {
54 return 0;
55 }
56
57 /*
58 * Need enough space to cover the ethernet header (+vlan), max ip header,
59 * and the first 4 bytes of the TCP/IP header (src/dst ports).
60 */
61 size_t hdrs_size;
62 uint8_t hdrs_buf[sizeof(struct ether_vlan_header) +
63 IP_MAX_HDR_LENGTH +
64 sizeof(uint32_t)];
65
66 switch (pUM->devParams.routeTxRingPolicy)
67 {
68 case BNXE_ROUTE_RING_TCPUDP:
69
70 pHdr = pMblk->b_rptr;
71
72 etype = ntohs(((struct ether_header *)pHdr)->ether_type);
73
74 if (etype == ETHERTYPE_VLAN)
75 {
76 etype = ntohs(((struct ether_vlan_header *)pHdr)->ether_type);
77 eHdrSize = sizeof(struct ether_vlan_header);
78 }
79 else
80 {
81 eHdrSize = sizeof(struct ether_header);
82 }
83
84 if (etype == ETHERTYPE_IP)
85 {
86 mblkLen = MBLKL(pMblk);
87 pHdr = NULL;
88
89 if (mblkLen > (eHdrSize + sizeof(uint8_t)))
90 {
91 pHdr = (pMblk->b_rptr + eHdrSize);
92 mblkLen -= eHdrSize;
93
94 pHdr = (mblkLen > (((*pHdr & 0x0f) << 2) + sizeof(uint32_t))) ?
95 pMblk->b_rptr : NULL;
96 }
97
98 if (pHdr == NULL)
99 {
100 /* copy the header so it's contiguous in the local hdrs_buf */
101 pTmpMblk = pMblk;
102 hdrs_size = 0;
103
104 while (pTmpMblk && (hdrs_size < sizeof(hdrs_buf)))
105 {
106 mblkLen = MBLKL(pTmpMblk);
107
108 if (mblkLen >= (sizeof(hdrs_buf) - hdrs_size))
109 {
110 mblkLen = (sizeof(hdrs_buf) - hdrs_size);
111 }
112
113 bcopy(pTmpMblk->b_rptr, &hdrs_buf[hdrs_size], mblkLen);
114
115 hdrs_size += mblkLen;
116 pTmpMblk = pTmpMblk->b_cont;
117 }
118
119 pHdr = hdrs_buf;
120 }
121
122 pHdr += eHdrSize;
123
124 if (!(pHdr[6] & 0x3f) && !(pHdr[7] & 0xff))
125 {
126 switch (pHdr[9])
127 {
128 case IPPROTO_TCP:
129 case IPPROTO_UDP:
130 case IPPROTO_ESP:
131
132 /* source and destination ports */
133 pHdr += (((*pHdr) & 0x0f) << 2);
134 ring = ((u32_t)(pHdr[0] ^ pHdr[1] ^ pHdr[2] ^ pHdr[3]) %
135 numRings);
136 break;
137
138 case IPPROTO_AH:
139
140 /* security parameters index */
141 pHdr += (((*pHdr) & 0x0f) << 2);
142 ring = ((pHdr[4] ^ pHdr[5] ^ pHdr[6] ^ pHdr[7]) %
143 numRings);
144 break;
145
146 default:
147
148 /* last byte of the destination IP address */
149 ring = (pHdr[19] % numRings);
150 break;
151 }
152 }
153 else
154 {
155 /* fragmented packet */
156 ring = (pHdr[19] % numRings);
157 }
158 }
159 else
160 {
161 ring = (pMblk->b_band % numRings);
162 }
163
164 break;
165
166 case BNXE_ROUTE_RING_DEST_MAC:
167
168 /* last byte of dst mac addr */
169 pHdr = pMblk->b_rptr;
170 ring = (pHdr[5] % numRings);
171 break;
172
173 case BNXE_ROUTE_RING_MSG_PRIO:
174
175 ring = (pMblk->b_band % numRings);
176 break;
177
178 case BNXE_ROUTE_RING_NONE:
179 default:
180
181 ring = 0;
182 break;
183 }
184
185 return ring;
186}
187