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