1227064Sbz/* 2250340Sdavidcs * Copyright (c) 2011-2013 Qlogic Corporation 3227064Sbz * All rights reserved. 4227064Sbz * 5227064Sbz * Redistribution and use in source and binary forms, with or without 6227064Sbz * modification, are permitted provided that the following conditions 7227064Sbz * are met: 8227064Sbz * 9227064Sbz * 1. Redistributions of source code must retain the above copyright 10227064Sbz * notice, this list of conditions and the following disclaimer. 11227064Sbz * 2. Redistributions in binary form must reproduce the above copyright 12227064Sbz * notice, this list of conditions and the following disclaimer in the 13227064Sbz * documentation and/or other materials provided with the distribution. 14227064Sbz * 15227064Sbz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16227064Sbz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17227064Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18227064Sbz * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19227064Sbz * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20227064Sbz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21227064Sbz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22227064Sbz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23227064Sbz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24227064Sbz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25227064Sbz * POSSIBILITY OF SUCH DAMAGE. 26227064Sbz * 27227064Sbz * $FreeBSD$ 28227064Sbz */ 29227064Sbz/* 30227064Sbz * File: qla_hw.h 31227064Sbz * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 32227064Sbz */ 33227064Sbz#ifndef _QLA_HW_H_ 34227064Sbz#define _QLA_HW_H_ 35227064Sbz 36227064Sbz#define Q8_MAX_NUM_MULTICAST_ADDRS 128 37227064Sbz#define Q8_MAC_ADDR_LEN 6 38227064Sbz 39227064Sbz/* 40227064Sbz * Firmware Interface 41227064Sbz */ 42227064Sbz 43227064Sbz/* 44227064Sbz * Command Response Interface - Commands 45227064Sbz */ 46227064Sbztypedef struct qla_cdrp { 47227064Sbz uint32_t cmd; 48227064Sbz uint32_t cmd_arg1; 49227064Sbz uint32_t cmd_arg2; 50227064Sbz uint32_t cmd_arg3; 51227064Sbz uint32_t rsp; 52227064Sbz uint32_t rsp_arg1; 53227064Sbz uint32_t rsp_arg2; 54227064Sbz uint32_t rsp_arg3; 55227064Sbz} qla_cdrp_t; 56227064Sbz 57227064Sbz#define Q8_CMD_RD_MAX_RDS_PER_CNTXT 0x80000002 58227064Sbz#define Q8_CMD_RD_MAX_SDS_PER_CNTXT 0x80000003 59227064Sbz#define Q8_CMD_RD_MAX_RULES_PER_CNTXT 0x80000004 60227064Sbz#define Q8_CMD_RD_MAX_RX_CNTXT 0x80000005 61227064Sbz#define Q8_CMD_RD_MAX_TX_CNTXT 0x80000006 62227064Sbz#define Q8_CMD_CREATE_RX_CNTXT 0x80000007 63227064Sbz#define Q8_CMD_DESTROY_RX_CNTXT 0x80000008 64227064Sbz#define Q8_CMD_CREATE_TX_CNTXT 0x80000009 65227064Sbz#define Q8_CMD_DESTROY_TX_CNTXT 0x8000000A 66227064Sbz#define Q8_CMD_SETUP_STATS 0x8000000E 67227064Sbz#define Q8_CMD_GET_STATS 0x8000000F 68227064Sbz#define Q8_CMD_DELETE_STATS 0x80000010 69227064Sbz#define Q8_CMD_GEN_INT 0x80000011 70227064Sbz#define Q8_CMD_SET_MTU 0x80000012 71227064Sbz#define Q8_CMD_GET_FLOW_CNTRL 0x80000016 72227064Sbz#define Q8_CMD_SET_FLOW_CNTRL 0x80000017 73227064Sbz#define Q8_CMD_RD_MAX_MTU 0x80000018 74227064Sbz#define Q8_CMD_RD_MAX_LRO 0x80000019 75227064Sbz 76227064Sbz/* 77227064Sbz * Command Response Interface - Response 78227064Sbz */ 79227064Sbz#define Q8_RSP_SUCCESS 0x00000000 80227064Sbz#define Q8_RSP_NO_HOST_MEM 0x00000001 81227064Sbz#define Q8_RSP_NO_HOST_RSRC 0x00000002 82227064Sbz#define Q8_RSP_NO_CARD_CRB 0x00000003 83227064Sbz#define Q8_RSP_NO_CARD_MEM 0x00000004 84227064Sbz#define Q8_RSP_NO_CARD_RSRC 0x00000005 85227064Sbz#define Q8_RSP_INVALID_ARGS 0x00000006 86227064Sbz#define Q8_RSP_INVALID_ACTION 0x00000007 87227064Sbz#define Q8_RSP_INVALID_STATE 0x00000008 88227064Sbz#define Q8_RSP_NOT_SUPPORTED 0x00000009 89227064Sbz#define Q8_RSP_NOT_PERMITTED 0x0000000A 90227064Sbz#define Q8_RSP_NOT_READY 0x0000000B 91227064Sbz#define Q8_RSP_DOES_NOT_EXIST 0x0000000C 92227064Sbz#define Q8_RSP_ALREADY_EXISTS 0x0000000D 93227064Sbz#define Q8_RSP_BAD_SIGNATURE 0x0000000E 94227064Sbz#define Q8_RSP_CMD_NOT_IMPLEMENTED 0x0000000F 95227064Sbz#define Q8_RSP_CMD_INVALID 0x00000010 96227064Sbz#define Q8_RSP_TIMEOUT 0x00000011 97227064Sbz 98227064Sbz 99227064Sbz/* 100227064Sbz * Transmit Related Definitions 101227064Sbz */ 102227064Sbz 103227064Sbz/* 104227064Sbz * Transmit Context - Q8_CMD_CREATE_TX_CNTXT Command Configuration Data 105227064Sbz */ 106227064Sbz 107227064Sbztypedef struct _q80_tx_cntxt_req { 108227064Sbz uint64_t rsp_dma_addr; /* rsp from firmware is DMA'ed here */ 109227064Sbz uint64_t cmd_cons_dma_addr; 110227064Sbz uint64_t rsrvd0; 111227064Sbz 112227064Sbz uint32_t caps[4]; /* capabilities - bit vector*/ 113227064Sbz#define CNTXT_CAP0_BASEFW 0x0001 114227064Sbz#define CNTXT_CAP0_LEGACY_MN 0x0004 115227064Sbz#define CNTXT_CAP0_LSO 0x0040 116227064Sbz 117227064Sbz uint32_t intr_mode; /* Interrupt Mode */ 118227064Sbz#define CNTXT_INTR_MODE_UNIQUE 0x0000 119227064Sbz#define CNTXT_INTR_MODE_SHARED 0x0001 120227064Sbz 121227064Sbz uint64_t rsrvd1; 122227064Sbz uint16_t msi_index; 123227064Sbz uint16_t rsrvd2; 124227064Sbz uint64_t phys_addr; /* physical address of transmit ring 125227064Sbz * in system memory */ 126227064Sbz uint32_t num_entries; /* number of entries in transmit ring */ 127227064Sbz uint8_t rsrvd3[128]; 128227064Sbz} __packed q80_tx_cntxt_req_t; /* 188 bytes total */ 129227064Sbz 130227064Sbz 131227064Sbz/* 132227064Sbz * Transmit Context - Response from Firmware to Q8_CMD_CREATE_TX_CNTXT 133227064Sbz */ 134227064Sbz 135227064Sbztypedef struct _q80_tx_cntxt_rsp { 136227064Sbz uint32_t cntxt_state; /* starting state */ 137227064Sbz#define CNTXT_STATE_ALLOCATED_NOT_ACTIVE 0x0001 138227064Sbz#define CNTXT_STATE_ACTIVE 0x0002 139227064Sbz#define CNTXT_STATE_QUIESCED 0x0004 140227064Sbz 141227064Sbz uint16_t cntxt_id; /* handle for context */ 142227064Sbz uint8_t phys_port_id; /* physical id of port */ 143227064Sbz uint8_t virt_port_id; /* virtual or logical id of port */ 144227064Sbz uint32_t producer_reg; /* producer register for transmit ring */ 145227064Sbz uint32_t intr_mask_reg; /* interrupt mask register */ 146227064Sbz uint8_t rsrvd[128]; 147227064Sbz} __packed q80_tx_cntxt_rsp_t; /* 144 bytes */ 148227064Sbz 149227064Sbz/* 150227064Sbz * Transmit Command Descriptor 151227064Sbz * These commands are issued on the Transmit Ring associated with a Transmit 152227064Sbz * context 153227064Sbz */ 154227064Sbztypedef struct _q80_tx_cmd { 155227064Sbz uint8_t tcp_hdr_off; /* TCP Header Offset */ 156227064Sbz uint8_t ip_hdr_off; /* IP Header Offset */ 157227064Sbz uint16_t flags_opcode; /* Bits 0-6: flags; 7-12: opcode */ 158227064Sbz 159227064Sbz /* flags field */ 160227064Sbz#define Q8_TX_CMD_FLAGS_MULTICAST 0x01 161227064Sbz#define Q8_TX_CMD_FLAGS_LSO_TSO 0x02 162227064Sbz#define Q8_TX_CMD_FLAGS_VLAN_TAGGED 0x10 163227064Sbz#define Q8_TX_CMD_FLAGS_HW_VLAN_ID 0x40 164227064Sbz 165227064Sbz /* opcode field */ 166227064Sbz#define Q8_TX_CMD_OP_XMT_UDP_CHKSUM_IPV6 (0xC << 7) 167227064Sbz#define Q8_TX_CMD_OP_XMT_TCP_CHKSUM_IPV6 (0xB << 7) 168227064Sbz#define Q8_TX_CMD_OP_XMT_TCP_LSO_IPV6 (0x6 << 7) 169227064Sbz#define Q8_TX_CMD_OP_XMT_TCP_LSO (0x5 << 7) 170227064Sbz#define Q8_TX_CMD_OP_XMT_UDP_CHKSUM (0x3 << 7) 171227064Sbz#define Q8_TX_CMD_OP_XMT_TCP_CHKSUM (0x2 << 7) 172227064Sbz#define Q8_TX_CMD_OP_XMT_ETHER (0x1 << 7) 173227064Sbz 174227064Sbz uint8_t n_bufs; /* # of data segs in data buffer */ 175227064Sbz uint8_t data_len_lo; /* data length lower 8 bits */ 176227064Sbz uint16_t data_len_hi; /* data length upper 16 bits */ 177227064Sbz 178227064Sbz uint64_t buf2_addr; /* buffer 2 address */ 179227064Sbz 180227064Sbz uint16_t rsrvd0; 181227064Sbz uint16_t mss; /* MSS for this packet */ 182227064Sbz uint8_t port_cntxtid; /* Bits 7-4: ContextId; 3-0: reserved */ 183227064Sbz 184227064Sbz#define Q8_TX_CMD_PORT_CNXTID(c_id) ((c_id & 0xF) << 4) 185227064Sbz 186227064Sbz uint8_t total_hdr_len; /* MAC+IP+TCP Header Length for LSO */ 187227064Sbz uint16_t rsrvd1; 188227064Sbz 189227064Sbz uint64_t buf3_addr; /* buffer 3 address */ 190227064Sbz uint64_t buf1_addr; /* buffer 1 address */ 191227064Sbz 192227064Sbz uint16_t buf1_len; /* length of buffer 1 */ 193227064Sbz uint16_t buf2_len; /* length of buffer 2 */ 194227064Sbz uint16_t buf3_len; /* length of buffer 3 */ 195227064Sbz uint16_t buf4_len; /* length of buffer 4 */ 196227064Sbz 197227064Sbz uint64_t buf4_addr; /* buffer 4 address */ 198227064Sbz 199227064Sbz uint32_t rsrvd2; 200227064Sbz uint16_t rsrvd3; 201227064Sbz uint16_t vlan_tci; /* VLAN TCI when hw tagging is enabled*/ 202227064Sbz 203227064Sbz} __packed q80_tx_cmd_t; /* 64 bytes */ 204227064Sbz 205227064Sbz#define Q8_TX_CMD_MAX_SEGMENTS 4 206227064Sbz#define Q8_TX_CMD_TSO_ALIGN 2 207227064Sbz#define Q8_TX_MAX_SEGMENTS 14 208227064Sbz 209227064Sbz 210227064Sbz/* 211227064Sbz * Receive Related Definitions 212227064Sbz */ 213227064Sbz/* 214227064Sbz * Receive Context - Q8_CMD_CREATE_RX_CNTXT Command Configuration Data 215227064Sbz */ 216227064Sbz 217227064Sbztypedef struct _q80_rq_sds_ring { 218227064Sbz uint64_t phys_addr; /* physical addr of status ring in system memory */ 219227064Sbz uint32_t size; /* number of entries in status ring */ 220227064Sbz uint16_t msi_index; 221227064Sbz uint16_t rsrvd; 222227064Sbz} __packed q80_rq_sds_ring_t; /* 16 bytes */ 223227064Sbz 224227064Sbztypedef struct _q80_rq_rds_ring { 225227064Sbz uint64_t phys_addr; /* physical addr of rcv ring in system memory */ 226227064Sbz uint64_t buf_size; /* packet buffer size */ 227227064Sbz uint32_t size; /* number of entries in ring */ 228227064Sbz uint32_t rsrvd; 229227064Sbz} __packed q80_rq_rds_ring_t; /* 24 bytes */ 230227064Sbz 231227064Sbztypedef struct _q80_rq_rcv_cntxt { 232227064Sbz uint64_t rsp_dma_addr; /* rsp from firmware is DMA'ed here */ 233227064Sbz uint32_t caps[4]; /* bit vector */ 234227064Sbz#define CNTXT_CAP0_JUMBO 0x0080 /* Contiguous Jumbo buffers*/ 235227064Sbz#define CNTXT_CAP0_LRO 0x0100 236227064Sbz#define CNTXT_CAP0_HW_LRO 0x0800 /* HW LRO */ 237227064Sbz 238227064Sbz uint32_t intr_mode; /* same as q80_tx_cntxt_req_t */ 239227064Sbz uint32_t rds_intr_mode; /* same as q80_tx_cntxt_req_t */ 240227064Sbz 241227064Sbz uint32_t rds_ring_offset; /* rds configuration relative to data[0] */ 242227064Sbz uint32_t sds_ring_offset; /* sds configuration relative to data[0] */ 243227064Sbz 244227064Sbz uint16_t num_rds_rings; 245227064Sbz uint16_t num_sds_rings; 246227064Sbz 247227064Sbz uint8_t rsrvd1[132]; 248227064Sbz} __packed q80_rq_rcv_cntxt_t; /* 176 bytes header + rds + sds ring rqsts */ 249227064Sbz 250227064Sbz/* 251227064Sbz * Receive Context - Response from Firmware to Q8_CMD_CREATE_RX_CNTXT 252227064Sbz */ 253227064Sbz 254227064Sbztypedef struct _q80_rsp_rds_ring { 255227064Sbz uint32_t producer_reg; 256227064Sbz uint32_t rsrvd; 257227064Sbz} __packed q80_rsp_rds_ring_t; /* 8 bytes */ 258227064Sbz 259227064Sbztypedef struct _q80_rsp_sds_ring { 260227064Sbz uint32_t consumer_reg; 261227064Sbz uint32_t intr_mask_reg; 262227064Sbz} __packed q80_rsp_sds_ring_t; /* 8 bytes */ 263227064Sbz 264227064Sbztypedef struct _q80_rsp_rcv_cntxt { 265227064Sbz uint32_t rds_ring_offset; /* rds configuration relative to data[0] */ 266227064Sbz uint32_t sds_ring_offset; /* sds configuration relative to data[0] */ 267227064Sbz 268227064Sbz uint32_t cntxt_state; /* starting state */ 269227064Sbz uint32_t funcs_per_port; /* number of PCI functions sharing each port */ 270227064Sbz 271227064Sbz uint16_t num_rds_rings; 272227064Sbz uint16_t num_sds_rings; 273227064Sbz 274227064Sbz uint16_t cntxt_id; /* handle for context */ 275227064Sbz 276227064Sbz uint8_t phys_port; /* physical id of port */ 277227064Sbz uint8_t virt_port; /* virtual or logical id of port */ 278227064Sbz 279227064Sbz uint8_t rsrvd[128]; 280227064Sbz uint8_t data[0]; 281227064Sbz} __packed q80_rsp_rcv_cntxt_t; /* 152 bytes header + rds + sds ring rspncs */ 282227064Sbz 283227064Sbz 284227064Sbz/* 285227064Sbz * Note: 286227064Sbz * Transmit Context 287227064Sbz * 188 (rq) + 144 (rsp) = 332 bytes are required 288227064Sbz * 289227064Sbz * Receive Context 290227064Sbz * 1 RDS and 1 SDS rings: (16+24+176)+(8+8+152) = 384 bytes 291227064Sbz * 292227064Sbz * 3 RDS and 4 SDS rings: (((16+24)*3)+176) + (((8+8)*4)+152) = 293227064Sbz * = 296 + 216 = 512 bytes 294227064Sbz * Clearly this within the minimum PAGE size of most O.S platforms 295227064Sbz * (typically 4Kbytes). Hence it is simpler to simply allocate one PAGE 296227064Sbz * and then carve out space for each context. It is also a good idea to 297227064Sbz * to throw in the shadown register for the consumer index of the transmit 298227064Sbz * ring in this PAGE. 299227064Sbz */ 300227064Sbz 301227064Sbz/* 302227064Sbz * Receive Descriptor corresponding to each entry in the receive ring 303227064Sbz */ 304227064Sbztypedef struct _q80_rcv_desc { 305227064Sbz uint16_t handle; 306227064Sbz uint16_t rsrvd; 307227064Sbz uint32_t buf_size; /* buffer size in bytes */ 308227064Sbz uint64_t buf_addr; /* physical address of buffer */ 309227064Sbz} __packed q80_recv_desc_t; 310227064Sbz 311227064Sbz/* 312227064Sbz * Status Descriptor corresponding to each entry in the Status ring 313227064Sbz */ 314227064Sbztypedef struct _q80_stat_desc { 315227064Sbz uint64_t data[2]; 316227064Sbz} __packed q80_stat_desc_t; 317227064Sbz 318227064Sbz/* 319227064Sbz * definitions for data[0] field of Status Descriptor 320227064Sbz */ 321227064Sbz#define Q8_STAT_DESC_OWNER(data) ((data >> 56) & 0x3) 322227064Sbz#define Q8_STAT_DESC_OWNER_HOST 0x1 323227064Sbz#define Q8_STAT_DESC_OWNER_FW 0x2 324227064Sbz 325227064Sbz#define Q8_STAT_DESC_OWNER_MASK (((uint64_t)0x3) << 56) 326227064Sbz#define Q8_STAT_DESC_SET_OWNER(owner) (uint64_t)(((uint64_t)owner) << 56) 327227064Sbz 328227064Sbz#define Q8_STAT_DESC_OPCODE(data) ((data >> 58) & 0x003F) 329227064Sbz#define Q8_STAT_DESC_OPCODE_SYN_OFFLOAD 0x03 330227064Sbz#define Q8_STAT_DESC_OPCODE_RCV_PKT 0x04 331227064Sbz#define Q8_STAT_DESC_OPCODE_CTRL_MSG 0x05 332227064Sbz#define Q8_STAT_DESC_OPCODE_LRO_PKT 0x12 333227064Sbz 334227064Sbz/* 335227064Sbz * definitions for data[0] field of Status Descriptor for standard frames 336227064Sbz * status descriptor opcode equals 0x04 337227064Sbz */ 338227064Sbz#define Q8_STAT_DESC_PORT(data) ((data) & 0x000F) 339227064Sbz#define Q8_STAT_DESC_STATUS(data) ((data >> 4) & 0x000F) 340227064Sbz#define Q8_STAT_DESC_STATUS_NO_CHKSUM 0x01 341227064Sbz#define Q8_STAT_DESC_STATUS_CHKSUM_OK 0x02 342227064Sbz#define Q8_STAT_DESC_STATUS_CHKSUM_ERR 0x03 343227064Sbz 344227064Sbz#define Q8_STAT_DESC_TYPE(data) ((data >> 8) & 0x000F) 345227064Sbz#define Q8_STAT_DESC_TOTAL_LENGTH(data) ((data >> 12) & 0xFFFF) 346227064Sbz#define Q8_STAT_DESC_HANDLE(data) ((data >> 28) & 0xFFFF) 347227064Sbz#define Q8_STAT_DESC_PROTOCOL(data) ((data >> 44) & 0x000F) 348227064Sbz#define Q8_STAT_DESC_L2_OFFSET(data) ((data >> 48) & 0x001F) 349227064Sbz#define Q8_STAT_DESC_COUNT(data) ((data >> 53) & 0x0007) 350227064Sbz 351227064Sbz/* 352227064Sbz * definitions for data[0-1] fields of Status Descriptor for LRO 353227064Sbz * status descriptor opcode equals 0x05 354227064Sbz */ 355227064Sbz/* definitions for data[0] field */ 356227064Sbz#define Q8_LRO_STAT_DESC_HANDLE(data) ((data) & 0xFFFF) 357227064Sbz#define Q8_LRO_STAT_DESC_PAYLOAD_LENGTH(data) ((data >> 16) & 0xFFFF) 358227064Sbz#define Q8_LRO_STAT_DESC_L2_OFFSET(data) ((data >> 32) & 0xFF) 359227064Sbz#define Q8_LRO_STAT_DESC_L4_OFFSET(data) ((data >> 40) & 0xFF) 360227064Sbz#define Q8_LRO_STAT_DESC_TS_PRESENT(data) ((data >> 48) & 0x1) 361227064Sbz#define Q8_LRO_STAT_DESC_TYPE(data) ((data >> 49) & 0x7) 362227064Sbz#define Q8_LRO_STAT_DESC_PUSH_BIT(data) ((data >> 52) & 0x1) 363227064Sbz 364227064Sbz/* definitions for data[1] field */ 365227064Sbz#define Q8_LRO_STAT_DESC_SEQ_NUM(data) (uint32_t)(data) 366227064Sbz 367227064Sbz/** Driver Related Definitions Begin **/ 368227064Sbz 369227064Sbz#define MAX_RDS_RINGS 2 /* Max# of Receive Descriptor Rings */ 370227064Sbz#define MAX_SDS_RINGS 4 /* Max# of Status Descriptor Rings */ 371227064Sbz#define TX_SMALL_PKT_SIZE 128 /* size in bytes of small packets */ 372227064Sbz 373227064Sbz/* The number of descriptors should be a power of 2 */ 374227064Sbz#define NUM_TX_DESCRIPTORS 2048 375227064Sbz#define NUM_RX_DESCRIPTORS 8192 376227064Sbz//#define NUM_RX_JUMBO_DESCRIPTORS 1024 377227064Sbz#define NUM_RX_JUMBO_DESCRIPTORS 2048 378227064Sbz//#define NUM_STATUS_DESCRIPTORS 8192 379227064Sbz#define NUM_STATUS_DESCRIPTORS 2048 380227064Sbz 381227064Sbztypedef struct _q80_rcv_cntxt_req { 382227064Sbz q80_rq_rcv_cntxt_t rx_req; 383227064Sbz q80_rq_rds_ring_t rds_req[MAX_RDS_RINGS]; 384227064Sbz q80_rq_sds_ring_t sds_req[MAX_SDS_RINGS]; 385227064Sbz} __packed q80_rcv_cntxt_req_t; 386227064Sbz 387227064Sbztypedef struct _q80_rcv_cntxt_rsp { 388227064Sbz q80_rsp_rcv_cntxt_t rx_rsp; 389227064Sbz q80_rsp_rds_ring_t rds_rsp[MAX_RDS_RINGS]; 390227064Sbz q80_rsp_sds_ring_t sds_rsp[MAX_SDS_RINGS]; 391227064Sbz} __packed q80_rcv_cntxt_rsp_t; 392227064Sbz 393227064Sbz/* 394227064Sbz * structure describing various dma buffers 395227064Sbz */ 396227064Sbz#define RDS_RING_INDEX_NORMAL 0 397227064Sbz#define RDS_RING_INDEX_JUMBO 1 398227064Sbz 399227064Sbztypedef struct qla_dmabuf { 400227064Sbz volatile struct { 401227064Sbz uint32_t tx_ring :1, 402227064Sbz rds_ring :1, 403227064Sbz sds_ring :1, 404227064Sbz context :1; 405227064Sbz } flags; 406227064Sbz 407227064Sbz qla_dma_t tx_ring; 408227064Sbz qla_dma_t rds_ring[MAX_RDS_RINGS]; 409227064Sbz qla_dma_t sds_ring[MAX_SDS_RINGS]; 410227064Sbz qla_dma_t context; 411227064Sbz} qla_dmabuf_t; 412227064Sbz 413227064Sbz/** Driver Related Definitions End **/ 414227064Sbz 415227064Sbz/* 416227064Sbz * Firmware Control Descriptor 417227064Sbz */ 418227064Sbztypedef struct _qla_fw_cds_hdr { 419227064Sbz uint64_t cmd; 420227064Sbz#define Q8_FWCD_CNTRL_REQ (0x13 << 23) 421227064Sbz uint8_t opcode; 422227064Sbz uint8_t cookie; 423227064Sbz uint16_t cntxt_id; 424227064Sbz uint8_t response; 425227064Sbz#define Q8_FW_CDS_HDR_COMPLETION 0x1 426227064Sbz uint16_t rsrvd; 427227064Sbz uint8_t sub_opcode; 428227064Sbz} __packed qla_fw_cds_hdr_t; 429227064Sbz 430227064Sbz/* 431227064Sbz * definitions for opcode in qla_fw_cds_hdr_t 432227064Sbz */ 433227064Sbz#define Q8_FWCD_OPCODE_CONFIG_RSS 0x01 434227064Sbz#define Q8_FWCD_OPCODE_CONFIG_RSS_TABLE 0x02 435227064Sbz#define Q8_FWCD_OPCODE_CONFIG_INTR_COALESCING 0x03 436227064Sbz#define Q8_FWCD_OPCODE_CONFIG_LED 0x04 437227064Sbz#define Q8_FWCD_OPCODE_CONFIG_MAC_ADDR 0x06 438227064Sbz#define Q8_FWCD_OPCODE_LRO_FLOW 0x07 439227064Sbz#define Q8_FWCD_OPCODE_GET_SNMP_STATS 0x08 440227064Sbz#define Q8_FWCD_OPCODE_CONFIG_MAC_RCV_MODE 0x0C 441227064Sbz#define Q8_FWCD_OPCODE_STATISTICS 0x10 442227064Sbz#define Q8_FWCD_OPCODE_CONFIG_IPADDR 0x12 443227064Sbz#define Q8_FWCD_OPCODE_CONFIG_LOOPBACK 0x13 444227064Sbz#define Q8_FWCD_OPCODE_LINK_EVENT_REQ 0x15 445227064Sbz#define Q8_FWCD_OPCODE_CONFIG_BRIDGING 0x17 446227064Sbz#define Q8_FWCD_OPCODE_CONFIG_LRO 0x18 447227064Sbz 448227064Sbz/* 449227064Sbz * Configure RSS 450227064Sbz */ 451227064Sbztypedef struct _qla_fw_cds_config_rss { 452227064Sbz qla_fw_cds_hdr_t hdr; 453227064Sbz uint8_t hash_type; 454227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV4_TCP (0x2 << 4) 455227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV4_IP (0x1 << 4) 456227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV4_TCP_IP (0x3 << 4) 457227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV6_TCP (0x2 << 6) 458227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV6_IP (0x1 << 6) 459227064Sbz#define Q8_FWCD_RSS_HASH_TYPE_IPV6_TCP_IP (0x3 << 6) 460227064Sbz 461227064Sbz uint8_t flags; 462227064Sbz#define Q8_FWCD_RSS_FLAGS_ENABLE_RSS 0x1 463227064Sbz#define Q8_FWCD_RSS_FLAGS_USE_IND_TABLE 0x2 464227064Sbz uint8_t rsrvd[4]; 465227064Sbz uint16_t ind_tbl_mask; 466227064Sbz uint64_t rss_key[5]; 467227064Sbz} __packed qla_fw_cds_config_rss_t; 468227064Sbz 469227064Sbz/* 470227064Sbz * Configure RSS Table 471227064Sbz */ 472227064Sbztypedef struct _qla_fw_cds_config_rss_table { 473227064Sbz qla_fw_cds_hdr_t hdr; 474227064Sbz uint64_t index; 475227064Sbz uint8_t table[40]; 476227064Sbz} __packed qla_fw_cds_config_rss_table_t; 477227064Sbz 478227064Sbz/* 479227064Sbz * Configure Interrupt Coalescing 480227064Sbz */ 481227064Sbztypedef struct _qla_fw_cds_config_intr_coalesc { 482227064Sbz qla_fw_cds_hdr_t hdr; 483227064Sbz uint16_t rsrvd0; 484227064Sbz uint16_t rsrvd1; 485227064Sbz uint16_t flags; 486227064Sbz uint16_t rsrvd2; 487227064Sbz uint64_t rsrvd3; 488227064Sbz uint16_t max_rcv_pkts; 489227064Sbz uint16_t max_rcv_usecs; 490227064Sbz uint16_t max_snd_pkts; 491227064Sbz uint16_t max_snd_usecs; 492227064Sbz uint64_t rsrvd4; 493227064Sbz uint64_t rsrvd5; 494227064Sbz uint32_t usecs_to; 495227064Sbz uint8_t timer_type; 496227064Sbz#define Q8_FWCMD_INTR_COALESC_TIMER_NONE 0x00 497227064Sbz#define Q8_FWCMD_INTR_COALESC_TIMER_ONCE 0x01 498227064Sbz#define Q8_FWCMD_INTR_COALESC_TIMER_PERIODIC 0x02 499227064Sbz 500227064Sbz uint8_t sds_ring_bitmask; 501227064Sbz#define Q8_FWCMD_INTR_COALESC_SDS_RING_0 0x01 502227064Sbz#define Q8_FWCMD_INTR_COALESC_SDS_RING_1 0x02 503227064Sbz#define Q8_FWCMD_INTR_COALESC_SDS_RING_2 0x04 504227064Sbz#define Q8_FWCMD_INTR_COALESC_SDS_RING_3 0x08 505227064Sbz 506227064Sbz uint16_t rsrvd6; 507227064Sbz} __packed qla_fw_cds_config_intr_coalesc_t; 508227064Sbz 509227064Sbz/* 510227064Sbz * Configure LED Parameters 511227064Sbz */ 512227064Sbztypedef struct _qla_fw_cds_config_led { 513227064Sbz qla_fw_cds_hdr_t hdr; 514227064Sbz uint32_t cntxt_id; 515227064Sbz uint32_t blink_rate; 516227064Sbz uint32_t blink_state; 517227064Sbz uint32_t rsrvd; 518227064Sbz} __packed qla_fw_cds_config_led_t; 519227064Sbz 520227064Sbz/* 521227064Sbz * Configure MAC Address 522227064Sbz */ 523227064Sbztypedef struct _qla_fw_cds_config_mac_addr { 524227064Sbz qla_fw_cds_hdr_t hdr; 525227064Sbz uint8_t cmd; 526227064Sbz#define Q8_FWCD_ADD_MAC_ADDR 0x1 527227064Sbz#define Q8_FWCD_DEL_MAC_ADDR 0x2 528227064Sbz uint8_t rsrvd; 529227064Sbz uint8_t mac_addr[6]; 530227064Sbz} __packed qla_fw_cds_config_mac_addr_t; 531227064Sbz 532227064Sbz/* 533227064Sbz * Configure Add/Delete LRO 534227064Sbz */ 535227064Sbztypedef struct _qla_fw_cds_config_lro { 536227064Sbz qla_fw_cds_hdr_t hdr; 537227064Sbz uint32_t dst_ip_addr; 538227064Sbz uint32_t src_ip_addr; 539227064Sbz uint16_t dst_tcp_port; 540227064Sbz uint16_t src_tcp_port; 541227064Sbz uint8_t ipv6; 542227064Sbz uint8_t time_stamp; 543227064Sbz uint16_t rsrvd; 544227064Sbz uint32_t rss_hash; 545227064Sbz uint32_t host_handle; 546227064Sbz} __packed qla_fw_cds_config_lro_t; 547227064Sbz 548227064Sbz/* 549227064Sbz * Get SNMP Statistics 550227064Sbz */ 551227064Sbztypedef struct _qla_fw_cds_get_snmp { 552227064Sbz qla_fw_cds_hdr_t hdr; 553227064Sbz uint64_t phys_addr; 554227064Sbz uint16_t size; 555227064Sbz uint16_t cntxt_id; 556227064Sbz uint32_t rsrvd; 557227064Sbz} __packed qla_fw_cds_get_snmp_t; 558227064Sbz 559227064Sbztypedef struct _qla_snmp_stats { 560227064Sbz uint64_t jabber_state; 561227064Sbz uint64_t false_carrier; 562227064Sbz uint64_t rsrvd; 563227064Sbz uint64_t mac_cntrl; 564227064Sbz uint64_t align_errors; 565227064Sbz uint64_t chksum_errors; 566227064Sbz uint64_t oversize_frames; 567227064Sbz uint64_t tx_errors; 568227064Sbz uint64_t mac_rcv_errors; 569227064Sbz uint64_t phy_rcv_errors; 570227064Sbz uint64_t rcv_pause; 571227064Sbz uint64_t tx_pause; 572227064Sbz} __packed qla_snmp_stats_t; 573227064Sbz 574227064Sbz/* 575227064Sbz * Enable Link Event Requests 576227064Sbz */ 577227064Sbztypedef struct _qla_link_event_req { 578227064Sbz qla_fw_cds_hdr_t hdr; 579227064Sbz uint8_t enable; 580227064Sbz uint8_t get_clnk_params; 581227064Sbz uint8_t pad[6]; 582227064Sbz} __packed qla_link_event_req_t; 583227064Sbz 584227064Sbz 585227064Sbz/* 586227064Sbz * Set MAC Receive Mode 587227064Sbz */ 588227064Sbztypedef struct _qla_set_mac_rcv_mode { 589227064Sbz qla_fw_cds_hdr_t hdr; 590227064Sbz 591227064Sbz uint32_t mode; 592227064Sbz#define Q8_MAC_RCV_RESET_PROMISC_ALLMULTI 0x00 593227064Sbz#define Q8_MAC_RCV_ENABLE_PROMISCUOUS 0x01 594227064Sbz#define Q8_MAC_RCV_ENABLE_ALLMULTI 0x02 595227064Sbz 596227064Sbz uint8_t pad[4]; 597227064Sbz} __packed qla_set_mac_rcv_mode_t; 598227064Sbz 599227064Sbz/* 600227064Sbz * Configure IP Address 601227064Sbz */ 602227064Sbztypedef struct _qla_config_ipv4 { 603227064Sbz qla_fw_cds_hdr_t hdr; 604227064Sbz 605227064Sbz uint64_t cmd; 606227064Sbz#define Q8_CONFIG_CMD_IP_ENABLE 0x02 607227064Sbz#define Q8_CONFIG_CMD_IP_DISABLE 0x03 608227064Sbz 609227064Sbz uint64_t ipv4_addr; 610227064Sbz} __packed qla_config_ipv4_t; 611227064Sbz 612227064Sbz/* 613227064Sbz * Configure LRO 614227064Sbz */ 615227064Sbztypedef struct _qla_config_lro { 616227064Sbz qla_fw_cds_hdr_t hdr; 617227064Sbz 618227064Sbz uint64_t cmd; 619227064Sbz#define Q8_CONFIG_LRO_ENABLE 0x08 620227064Sbz} __packed qla_config_lro_t; 621227064Sbz 622227064Sbz 623227064Sbz/* 624227064Sbz * Control Messages Received on SDS Ring 625227064Sbz */ 626227064Sbz/* Header */ 627227064Sbztypedef struct _qla_cntrl_msg_hdr { 628227064Sbz uint16_t rsrvd0; 629227064Sbz uint16_t err_code; 630227064Sbz uint8_t rsp_type; 631227064Sbz uint8_t comp_id; 632227064Sbz uint16_t tag; 633227064Sbz#define Q8_CTRL_MSG_TAG_DESC_COUNT_MASK (0x7 << 5) 634227064Sbz#define Q8_CTRL_MSG_TAG_OWNER_MASK (0x3 << 8) 635227064Sbz#define Q8_CTRL_MSG_TAG_OPCODE_MASK (0x3F << 10) 636227064Sbz} __packed qla_cntrl_msg_hdr_t; 637227064Sbz 638227064Sbz/* 639227064Sbz * definitions for rsp_type in qla_cntrl_msg_hdr_t 640227064Sbz */ 641227064Sbz#define Q8_CTRL_CONFIG_MAC_RSP 0x85 642227064Sbz#define Q8_CTRL_LRO_FLOW_DELETE_RSP 0x86 643227064Sbz#define Q8_CTRL_LRO_FLOW_ADD_FAILURE_RSP 0x87 644227064Sbz#define Q8_CTRL_GET_SNMP_STATS_RSP 0x88 645227064Sbz#define Q8_CTRL_GET_NETWORK_STATS_RSP 0x8C 646227064Sbz#define Q8_CTRL_LINK_EVENT_NOTIFICATION 0x8D 647227064Sbz 648227064Sbz/* 649227064Sbz * Configure MAC Response 650227064Sbz */ 651227064Sbztypedef struct _qla_config_mac_rsp { 652227064Sbz uint32_t rval; 653227064Sbz uint32_t rsrvd; 654227064Sbz} __packed qla_config_mac_rsp_t; 655227064Sbz 656227064Sbz/* 657227064Sbz * LRO Flow Response (can be LRO Flow Delete and LRO Flow Add Failure) 658227064Sbz */ 659227064Sbztypedef struct _qla_lro_flow_rsp { 660227064Sbz uint32_t handle; 661227064Sbz uint32_t rss_hash; 662227064Sbz uint32_t dst_ip; 663227064Sbz uint32_t src_ip; 664227064Sbz uint16_t dst_tcp_port; 665227064Sbz uint16_t src_tcp_port; 666227064Sbz uint8_t ipv6; 667227064Sbz uint8_t rsrvd0; 668227064Sbz uint16_t rsrvd1; 669227064Sbz} __packed qla_lro_flow_rsp_t; 670227064Sbz 671227064Sbz/* 672227064Sbz * Get SNMP Statistics Response 673227064Sbz */ 674227064Sbztypedef struct _qla_get_snmp_stats_rsp { 675227064Sbz uint64_t rsrvd; 676227064Sbz} __packed qla_get_snmp_stats_rsp_t; 677227064Sbz 678227064Sbz/* 679227064Sbz * Get Network Statistics Response 680227064Sbz */ 681227064Sbztypedef struct _qla_get_net_stats_rsp { 682227064Sbz uint64_t rsrvd; 683227064Sbz} __packed qla_get_net_stats_rsp_t; 684227064Sbz 685227064Sbz/* 686227064Sbz * Link Event Notification 687227064Sbz */ 688227064Sbztypedef struct _qla_link_event { 689227064Sbz uint32_t cable_oui; 690227064Sbz uint16_t cable_length; 691227064Sbz 692227064Sbz uint16_t link_speed; 693227064Sbz#define Q8_LE_SPEED_MASK 0xFFF 694227064Sbz#define Q8_LE_SPEED_10GBPS 0x710 695227064Sbz#define Q8_LE_SPEED_1GBPS 0x3E8 696227064Sbz#define Q8_LE_SPEED_100MBPS 0x064 697227064Sbz#define Q8_LE_SPEED_10MBPS 0x00A 698227064Sbz 699227064Sbz uint8_t link_up;/* 0 = down; else up */ 700227064Sbz 701227064Sbz uint8_t mod_info; 702227064Sbz#define Q8_LE_MI_MODULE_NOT_PRESENT 0x01 703227064Sbz#define Q8_LE_MI_UNKNOWN_OPTICAL_MODULE 0x02 704227064Sbz#define Q8_LE_MI_SR_LR_OPTICAL_MODULE 0x03 705227064Sbz#define Q8_LE_MI_LRM_OPTICAL_MODULE 0x04 706227064Sbz#define Q8_LE_MI_SFP_1G_MODULE 0x05 707227064Sbz#define Q8_LE_MI_UNSUPPORTED_TWINAX 0x06 708227064Sbz#define Q8_LE_MI_UNSUPPORTED_TWINAX_LENGTH 0x07 709227064Sbz#define Q8_LE_MI_SUPPORTED_TWINAX 0x08 710227064Sbz 711227064Sbz uint8_t fduplex; /* 1 = full duplex; 0 = half duplex */ 712227064Sbz uint8_t autoneg; /* 1 = autoneg enable; 0 = disabled */ 713227064Sbz uint32_t rsrvd; 714227064Sbz} __packed qla_link_event_t; 715227064Sbz 716227064Sbztypedef struct _qla_sds { 717227064Sbz q80_stat_desc_t *sds_ring_base; /* start of sds ring */ 718227064Sbz uint32_t sdsr_next; /* next entry in SDS ring to process */ 719227064Sbz struct lro_ctrl lro; 720227064Sbz void *rxb_free; 721227064Sbz uint32_t rx_free; 722227064Sbz void *rxjb_free; 723227064Sbz uint32_t rxj_free; 724227064Sbz volatile uint32_t rcv_active; 725227064Sbz} qla_sds_t; 726227064Sbz 727250340Sdavidcs#define QL_FRAME_HDR_SIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +\ 728250340Sdavidcs sizeof (struct ip) + sizeof (struct tcphdr) + 16) 729227064Sbz/* 730227064Sbz * struct for storing hardware specific information for a given interface 731227064Sbz */ 732227064Sbztypedef struct _qla_hw { 733227064Sbz struct { 734227064Sbz uint32_t 735227064Sbz lro :1, 736227064Sbz init_tx_cnxt :1, 737227064Sbz init_rx_cnxt :1, 738227064Sbz fduplex :1, 739227064Sbz autoneg :1, 740227064Sbz link_up :1; 741227064Sbz } flags; 742227064Sbz 743227064Sbz uint16_t link_speed; 744227064Sbz uint16_t cable_length; 745227064Sbz uint16_t cable_oui; 746227064Sbz uint8_t mod_info; 747227064Sbz uint8_t rsrvd; 748227064Sbz 749227064Sbz uint32_t max_rds_per_cntxt; 750227064Sbz uint32_t max_sds_per_cntxt; 751227064Sbz uint32_t max_rules_per_cntxt; 752227064Sbz uint32_t max_rcv_cntxts; 753227064Sbz uint32_t max_xmt_cntxts; 754227064Sbz uint32_t max_mtu; 755227064Sbz uint32_t max_lro; 756227064Sbz 757227064Sbz uint8_t mac_addr[ETHER_ADDR_LEN]; 758227064Sbz 759227064Sbz uint16_t num_rds_rings; 760227064Sbz uint16_t num_sds_rings; 761227064Sbz 762227064Sbz qla_dmabuf_t dma_buf; 763227064Sbz 764227064Sbz /* Transmit Side */ 765227064Sbz 766227064Sbz q80_tx_cmd_t *tx_ring_base; 767227064Sbz 768227064Sbz q80_tx_cntxt_req_t *tx_cntxt_req; /* TX Context Request */ 769227064Sbz bus_addr_t tx_cntxt_req_paddr; 770227064Sbz 771227064Sbz q80_tx_cntxt_rsp_t *tx_cntxt_rsp; /* TX Context Response */ 772227064Sbz bus_addr_t tx_cntxt_rsp_paddr; 773227064Sbz 774227064Sbz uint32_t *tx_cons; /* tx consumer shadow reg */ 775227064Sbz bus_addr_t tx_cons_paddr; 776227064Sbz 777227064Sbz volatile uint32_t txr_free; /* # of free entries in tx ring */ 778227064Sbz volatile uint32_t txr_next; /* # next available tx ring entry */ 779227064Sbz volatile uint32_t txr_comp; /* index of last tx entry completed */ 780227064Sbz 781227064Sbz uint32_t tx_prod_reg; 782227064Sbz 783227064Sbz /* Receive Side */ 784227064Sbz volatile uint32_t rx_next; /* next standard rcv ring to arm fw */ 785227064Sbz volatile int32_t rxj_next; /* next jumbo rcv ring to arm fw */ 786227064Sbz 787227064Sbz volatile int32_t rx_in; /* next standard rcv ring to add mbufs */ 788227064Sbz volatile int32_t rxj_in; /* next jumbo rcv ring to add mbufs */ 789227064Sbz 790227064Sbz q80_rcv_cntxt_req_t *rx_cntxt_req; /* Rcv Context Request */ 791227064Sbz bus_addr_t rx_cntxt_req_paddr; 792227064Sbz q80_rcv_cntxt_rsp_t *rx_cntxt_rsp; /* Rcv Context Response */ 793227064Sbz bus_addr_t rx_cntxt_rsp_paddr; 794227064Sbz 795227064Sbz qla_sds_t sds[MAX_SDS_RINGS]; 796250340Sdavidcs 797250340Sdavidcs uint8_t frame_hdr[QL_FRAME_HDR_SIZE]; 798227064Sbz} qla_hw_t; 799227064Sbz 800227064Sbz#define QL_UPDATE_RDS_PRODUCER_INDEX(ha, i, val) \ 801227064Sbz WRITE_REG32(ha, ((ha->hw.rx_cntxt_rsp)->rds_rsp[i].producer_reg +\ 802227064Sbz 0x1b2000), val) 803227064Sbz 804227064Sbz#define QL_UPDATE_TX_PRODUCER_INDEX(ha, val) \ 805227064Sbz WRITE_REG32(ha, (ha->hw.tx_prod_reg + 0x1b2000), val) 806227064Sbz 807227064Sbz#define QL_UPDATE_SDS_CONSUMER_INDEX(ha, i, val) \ 808227064Sbz WRITE_REG32(ha, ((ha->hw.rx_cntxt_rsp)->sds_rsp[i].consumer_reg +\ 809227064Sbz 0x1b2000), val) 810227064Sbz 811227064Sbz#define QL_CLEAR_INTERRUPTS(ha) \ 812227064Sbz if (ha->pci_func == 0) {\ 813227064Sbz WRITE_REG32(ha, Q8_INT_TARGET_STATUS_F0, 0xFFFFFFFF);\ 814227064Sbz } else {\ 815227064Sbz WRITE_REG32(ha, Q8_INT_TARGET_STATUS_F1, 0xFFFFFFFF);\ 816227064Sbz }\ 817227064Sbz 818227064Sbz#define QL_ENABLE_INTERRUPTS(ha, sds_index) \ 819227064Sbz {\ 820227064Sbz q80_rsp_sds_ring_t *rsp_sds;\ 821227064Sbz rsp_sds = &((ha->hw.rx_cntxt_rsp)->sds_rsp[sds_index]);\ 822227064Sbz WRITE_REG32(ha, (rsp_sds->intr_mask_reg + 0x1b2000), 0x1);\ 823227064Sbz } 824227064Sbz 825227064Sbz#define QL_DISABLE_INTERRUPTS(ha, sds_index) \ 826227064Sbz {\ 827227064Sbz q80_rsp_sds_ring_t *rsp_sds;\ 828227064Sbz rsp_sds = &((ha->hw.rx_cntxt_rsp)->sds_rsp[sds_index]);\ 829227064Sbz WRITE_REG32(ha, (rsp_sds->intr_mask_reg + 0x1b2000), 0x0);\ 830227064Sbz } 831227064Sbz 832227064Sbz 833227064Sbz#define QL_BUFFER_ALIGN 16 834227064Sbz 835227064Sbz#endif /* #ifndef _QLA_HW_H_ */ 836