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 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