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