Date: Mon, 28 Jul 2014 21:57:10 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269198 - in head/sys: dev/i40e modules/i40e Message-ID: <201407282157.s6SLvAJI028590@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Mon Jul 28 21:57:09 2014 New Revision: 269198 URL: http://svnweb.freebsd.org/changeset/base/269198 Log: Update the new 40G XL710 driver to Release version 1.0.0 Modified: head/sys/dev/i40e/i40e.h head/sys/dev/i40e/i40e_adminq.c head/sys/dev/i40e/i40e_adminq.h head/sys/dev/i40e/i40e_adminq_cmd.h head/sys/dev/i40e/i40e_common.c head/sys/dev/i40e/i40e_hmc.h head/sys/dev/i40e/i40e_lan_hmc.c head/sys/dev/i40e/i40e_lan_hmc.h head/sys/dev/i40e/i40e_nvm.c head/sys/dev/i40e/i40e_osdep.c head/sys/dev/i40e/i40e_prototype.h head/sys/dev/i40e/i40e_register.h head/sys/dev/i40e/i40e_register_x710_int.h head/sys/dev/i40e/i40e_txrx.c head/sys/dev/i40e/i40e_type.h head/sys/dev/i40e/if_i40e.c head/sys/modules/i40e/Makefile Modified: head/sys/dev/i40e/i40e.h ============================================================================== --- head/sys/dev/i40e/i40e.h Mon Jul 28 21:14:41 2014 (r269197) +++ head/sys/dev/i40e/i40e.h Mon Jul 28 21:57:09 2014 (r269198) @@ -92,13 +92,23 @@ #include "i40e_prototype.h" #ifdef I40E_DEBUG +#include <sys/sbuf.h> + #define MAC_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_FORMAT_ARGS(mac_addr) \ (mac_addr)[0], (mac_addr)[1], (mac_addr)[2], (mac_addr)[3], \ (mac_addr)[4], (mac_addr)[5] #define ON_OFF_STR(is_set) ((is_set) ? "On" : "Off") +#define DPRINTF(...) printf(__VA_ARGS__) +#define DDPRINTF(dev, ...) device_printf(dev, __VA_ARGS__) +#define IDPRINTF(ifp, ...) if_printf(ifp, __VA_ARGS__) + // static void i40e_dump_desc(void *, u8, u16); +#else +#define DPRINTF(...) +#define DDPRINTF(...) +#define IDPRINTF(...) #endif /* Tunables */ @@ -173,10 +183,21 @@ #define I40E_ITR_NONE 3 #define I40E_QUEUE_EOL 0x7FF #define I40E_MAX_FRAME 0x2600 -#define I40E_MAX_SEGS 32 -#define I40E_MAX_FILTERS 256 /* This is artificial */ +#define I40E_MAX_TX_SEGS 8 +#define I40E_MAX_TSO_SEGS 66 +#define I40E_SPARSE_CHAIN 6 +#define I40E_QUEUE_HUNG 0x80000000 + +/* ERJ: hardware can support ~1.5k filters between all functions */ +#define I40E_MAX_FILTERS 256 #define I40E_MAX_TX_BUSY 10 +#define I40E_NVM_VERSION_LO_SHIFT 0 +#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT) +#define I40E_NVM_VERSION_HI_SHIFT 12 +#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT) + + /* * Interrupt Moderation parameters */ @@ -200,7 +221,9 @@ /* used in the vlan field of the filter when not a vlan */ #define I40E_VLAN_ANY -1 -#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) +#define CSUM_OFFLOAD_IPV4 (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) +#define CSUM_OFFLOAD_IPV6 (CSUM_TCP_IPV6|CSUM_UDP_IPV6|CSUM_SCTP_IPV6) +#define CSUM_OFFLOAD (CSUM_OFFLOAD_IPV4|CSUM_OFFLOAD_IPV6|CSUM_TSO) /* Misc flags for i40e_vsi.flags */ #define I40E_FLAGS_KEEP_TSO4 (1 << 0) @@ -238,6 +261,7 @@ struct i40e_tx_buf { u32 eop_index; struct mbuf *m_head; bus_dmamap_t map; + bus_dma_tag_t tag; }; struct i40e_rx_buf { @@ -248,15 +272,6 @@ struct i40e_rx_buf { bus_dmamap_t pmap; }; -struct i40e_pkt_info { - u16 etype; - u32 elen; - u32 iplen; - struct ip *ip; - struct ip6_hdr *ip6; - struct tcphdr *th; -}; - /* ** This struct has multiple uses, multicast ** addresses, vlans, and mac filters all use it. @@ -275,7 +290,7 @@ struct i40e_mac_filter { struct tx_ring { struct i40e_queue *que; struct mtx mtx; - int watchdog; + u32 tail; struct i40e_tx_desc *base; struct i40e_dma_mem dma; u16 next_avail; @@ -287,7 +302,8 @@ struct tx_ring { struct i40e_tx_buf *buffers; volatile u16 avail; u32 cmd; - bus_dma_tag_t tag; + bus_dma_tag_t tx_tag; + bus_dma_tag_t tso_tag; char mtx_name[16]; struct buf_ring *br; @@ -318,6 +334,7 @@ struct rx_ring { char mtx_name[16]; struct i40e_rx_buf *buffers; u32 mbuf_sz; + u32 tail; bus_dma_tag_t htag; bus_dma_tag_t ptag; @@ -407,6 +424,7 @@ struct i40e_vsi { u64 hw_filters_add; /* Misc. */ + u64 active_queues; u64 flags; }; @@ -433,8 +451,9 @@ i40e_get_filter(struct i40e_vsi *vsi) { struct i40e_mac_filter *f; - // create a new empty filter - f = malloc(sizeof(struct i40e_mac_filter) , M_DEVBUF, M_NOWAIT | M_ZERO); + /* create a new empty filter */ + f = malloc(sizeof(struct i40e_mac_filter), + M_DEVBUF, M_NOWAIT | M_ZERO); SLIST_INSERT_HEAD(&vsi->ftl, f, next); return (f); @@ -467,6 +486,25 @@ struct i40e_sysctl_info { extern int i40e_atr_rate; +/* +** i40e_fw_version_str - format the FW and NVM version strings +*/ +static inline char * +i40e_fw_version_str(struct i40e_hw *hw) +{ + static char buf[32]; + + snprintf(buf, sizeof(buf), + "f%d.%d a%d.%d n%02x.%02x e%08x", + hw->aq.fw_maj_ver, hw->aq.fw_min_ver, + hw->aq.api_maj_ver, hw->aq.api_min_ver, + (hw->nvm.version & I40E_NVM_VERSION_HI_MASK) >> + I40E_NVM_VERSION_HI_SHIFT, + (hw->nvm.version & I40E_NVM_VERSION_LO_MASK) >> + I40E_NVM_VERSION_LO_SHIFT, + hw->nvm.eetrack); + return buf; +} /********************************************************************* * TXRX Function prototypes Modified: head/sys/dev/i40e/i40e_adminq.c ============================================================================== --- head/sys/dev/i40e/i40e_adminq.c Mon Jul 28 21:14:41 2014 (r269197) +++ head/sys/dev/i40e/i40e_adminq.c Mon Jul 28 21:57:09 2014 (r269198) @@ -61,16 +61,37 @@ static void i40e_adminq_init_regs(struct hw->aq.asq.tail = I40E_VF_ATQT1; hw->aq.asq.head = I40E_VF_ATQH1; hw->aq.asq.len = I40E_VF_ATQLEN1; + hw->aq.asq.bal = I40E_VF_ATQBAL1; + hw->aq.asq.bah = I40E_VF_ATQBAH1; hw->aq.arq.tail = I40E_VF_ARQT1; hw->aq.arq.head = I40E_VF_ARQH1; hw->aq.arq.len = I40E_VF_ARQLEN1; + hw->aq.arq.bal = I40E_VF_ARQBAL1; + hw->aq.arq.bah = I40E_VF_ARQBAH1; +#ifdef I40E_QV + } else if (hw->aq_dbg_ena) { + hw->aq.asq.tail = I40E_GL_ATQT; + hw->aq.asq.head = I40E_GL_ATQH; + hw->aq.asq.len = I40E_GL_ATQLEN; + hw->aq.asq.bal = I40E_GL_ATQBAL; + hw->aq.asq.bah = I40E_GL_ATQBAH; + hw->aq.arq.tail = I40E_GL_ARQT; + hw->aq.arq.head = I40E_GL_ARQH; + hw->aq.arq.len = I40E_GL_ARQLEN; + hw->aq.arq.bal = I40E_GL_ARQBAL; + hw->aq.arq.bah = I40E_GL_ARQBAH; +#endif } else { hw->aq.asq.tail = I40E_PF_ATQT; hw->aq.asq.head = I40E_PF_ATQH; hw->aq.asq.len = I40E_PF_ATQLEN; + hw->aq.asq.bal = I40E_PF_ATQBAL; + hw->aq.asq.bah = I40E_PF_ATQBAH; hw->aq.arq.tail = I40E_PF_ARQT; hw->aq.arq.head = I40E_PF_ARQH; hw->aq.arq.len = I40E_PF_ARQLEN; + hw->aq.arq.bal = I40E_PF_ARQBAL; + hw->aq.arq.bah = I40E_PF_ARQBAH; } } @@ -148,6 +169,10 @@ void i40e_free_adminq_arq(struct i40e_hw **/ static enum i40e_status_code i40e_alloc_arq_bufs(struct i40e_hw *hw) { +#ifdef I40E_QV + struct i40e_aq_desc qv_desc; + struct i40e_aq_desc *qv_desc_on_ring; +#endif enum i40e_status_code ret_code; struct i40e_aq_desc *desc; struct i40e_dma_mem *bi; @@ -176,6 +201,13 @@ static enum i40e_status_code i40e_alloc_ /* now configure the descriptors for use */ desc = I40E_ADMINQ_DESC(hw->aq.arq, i); +#ifdef I40E_QV + /* swap the descriptor with userspace version */ + i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + qv_desc_on_ring = desc; + desc = &qv_desc; +#endif desc->flags = CPU_TO_LE16(I40E_AQ_FLAG_BUF); if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF) @@ -194,6 +226,11 @@ static enum i40e_status_code i40e_alloc_ CPU_TO_LE32(I40E_LO_DWORD(bi->pa)); desc->params.external.param0 = 0; desc->params.external.param1 = 0; +#ifdef I40E_QV + /* put the initialized descriptor back to the ring */ + i40e_memcpy(qv_desc_on_ring, desc, sizeof(struct i40e_aq_desc), + I40E_NONDMA_TO_DMA); +#endif } alloc_arq_bufs: @@ -306,27 +343,14 @@ static enum i40e_status_code i40e_config wr32(hw, hw->aq.asq.head, 0); wr32(hw, hw->aq.asq.tail, 0); - if (hw->mac.type == I40E_MAC_VF) { - /* configure the transmit queue */ - wr32(hw, I40E_VF_ATQBAH1, - I40E_HI_DWORD(hw->aq.asq.desc_buf.pa)); - wr32(hw, I40E_VF_ATQBAL1, - I40E_LO_DWORD(hw->aq.asq.desc_buf.pa)); - wr32(hw, I40E_VF_ATQLEN1, (hw->aq.num_asq_entries | - I40E_VF_ATQLEN1_ATQENABLE_MASK)); - reg = rd32(hw, I40E_VF_ATQBAL1); - } else { - /* configure the transmit queue */ - wr32(hw, I40E_PF_ATQBAH, - I40E_HI_DWORD(hw->aq.asq.desc_buf.pa)); - wr32(hw, I40E_PF_ATQBAL, - I40E_LO_DWORD(hw->aq.asq.desc_buf.pa)); - wr32(hw, I40E_PF_ATQLEN, (hw->aq.num_asq_entries | - I40E_PF_ATQLEN_ATQENABLE_MASK)); - reg = rd32(hw, I40E_PF_ATQBAL); - } + /* set starting point */ + wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries | + I40E_PF_ATQLEN_ATQENABLE_MASK)); + wr32(hw, hw->aq.asq.bal, I40E_LO_DWORD(hw->aq.asq.desc_buf.pa)); + wr32(hw, hw->aq.asq.bah, I40E_HI_DWORD(hw->aq.asq.desc_buf.pa)); /* Check one register to verify that config was applied */ + reg = rd32(hw, hw->aq.asq.bal); if (reg != I40E_LO_DWORD(hw->aq.asq.desc_buf.pa)) ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; @@ -348,30 +372,17 @@ static enum i40e_status_code i40e_config wr32(hw, hw->aq.arq.head, 0); wr32(hw, hw->aq.arq.tail, 0); - if (hw->mac.type == I40E_MAC_VF) { - /* configure the receive queue */ - wr32(hw, I40E_VF_ARQBAH1, - I40E_HI_DWORD(hw->aq.arq.desc_buf.pa)); - wr32(hw, I40E_VF_ARQBAL1, - I40E_LO_DWORD(hw->aq.arq.desc_buf.pa)); - wr32(hw, I40E_VF_ARQLEN1, (hw->aq.num_arq_entries | - I40E_VF_ARQLEN1_ARQENABLE_MASK)); - reg = rd32(hw, I40E_VF_ARQBAL1); - } else { - /* configure the receive queue */ - wr32(hw, I40E_PF_ARQBAH, - I40E_HI_DWORD(hw->aq.arq.desc_buf.pa)); - wr32(hw, I40E_PF_ARQBAL, - I40E_LO_DWORD(hw->aq.arq.desc_buf.pa)); - wr32(hw, I40E_PF_ARQLEN, (hw->aq.num_arq_entries | - I40E_PF_ARQLEN_ARQENABLE_MASK)); - reg = rd32(hw, I40E_PF_ARQBAL); - } + /* set starting point */ + wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries | + I40E_PF_ARQLEN_ARQENABLE_MASK)); + wr32(hw, hw->aq.arq.bal, I40E_LO_DWORD(hw->aq.arq.desc_buf.pa)); + wr32(hw, hw->aq.arq.bah, I40E_HI_DWORD(hw->aq.arq.desc_buf.pa)); /* Update tail in the HW to post pre-allocated buffers */ wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1); /* Check one register to verify that config was applied */ + reg = rd32(hw, hw->aq.arq.bal); if (reg != I40E_LO_DWORD(hw->aq.arq.desc_buf.pa)) ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; @@ -510,9 +521,22 @@ enum i40e_status_code i40e_shutdown_asq( return I40E_ERR_NOT_READY; /* Stop firmware AdminQ processing */ +#ifdef I40E_QV + /* Do not reset registers, as Tools AQ is shared resource for QV */ + if (!hw->aq_dbg_ena) { + wr32(hw, hw->aq.asq.head, 0); + wr32(hw, hw->aq.asq.tail, 0); + wr32(hw, hw->aq.asq.len, 0); + wr32(hw, hw->aq.asq.bal, 0); + wr32(hw, hw->aq.asq.bah, 0); + } +#else wr32(hw, hw->aq.asq.head, 0); wr32(hw, hw->aq.asq.tail, 0); wr32(hw, hw->aq.asq.len, 0); + wr32(hw, hw->aq.asq.bal, 0); + wr32(hw, hw->aq.asq.bah, 0); +#endif /* make sure spinlock is available */ i40e_acquire_spinlock(&hw->aq.asq_spinlock); @@ -541,9 +565,22 @@ enum i40e_status_code i40e_shutdown_arq( return I40E_ERR_NOT_READY; /* Stop firmware AdminQ processing */ +#ifdef I40E_QV + /* Do not reset registers, as Tools AQ is shared resource for QV */ + if (!hw->aq_dbg_ena) { + wr32(hw, hw->aq.arq.head, 0); + wr32(hw, hw->aq.arq.tail, 0); + wr32(hw, hw->aq.arq.len, 0); + wr32(hw, hw->aq.arq.bal, 0); + wr32(hw, hw->aq.arq.bah, 0); + } +#else wr32(hw, hw->aq.arq.head, 0); wr32(hw, hw->aq.arq.tail, 0); wr32(hw, hw->aq.arq.len, 0); + wr32(hw, hw->aq.arq.bal, 0); + wr32(hw, hw->aq.arq.bah, 0); +#endif /* make sure spinlock is available */ i40e_acquire_spinlock(&hw->aq.arq_spinlock); @@ -591,6 +628,9 @@ enum i40e_status_code i40e_init_adminq(s /* Set up register offsets */ i40e_adminq_init_regs(hw); + /* setup ASQ command write back timeout */ + hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT; + /* allocate the ASQ */ ret_code = i40e_init_asq(hw); if (ret_code != I40E_SUCCESS) @@ -627,16 +667,19 @@ enum i40e_status_code i40e_init_adminq(s i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi); hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo; -#ifdef FORTVILLE_A0_SUPPORT - if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR || - !((hw->aq.api_min_ver == I40E_FW_API_VERSION_MINOR) || - (hw->aq.api_min_ver == I40E_FW_API_VERSION_A0_MINOR))) { +#ifdef I40E_QV + if (!hw->qv_force_init) { + if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) { + ret_code = I40E_ERR_FIRMWARE_API_VERSION; + goto init_adminq_free_arq; + } + } #else if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) { -#endif ret_code = I40E_ERR_FIRMWARE_API_VERSION; goto init_adminq_free_arq; } +#endif /* pre-emptive resource lock release */ i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); @@ -671,8 +714,16 @@ enum i40e_status_code i40e_shutdown_admi { enum i40e_status_code ret_code = I40E_SUCCESS; +#ifdef I40E_QV + /* This command is not supported for Tools AQ */ + if (!hw->aq_dbg_ena) { + if (i40e_check_asq_alive(hw)) + i40e_aq_queue_shutdown(hw, TRUE); + } +#else if (i40e_check_asq_alive(hw)) i40e_aq_queue_shutdown(hw, TRUE); +#endif i40e_shutdown_asq(hw); i40e_shutdown_arq(hw); @@ -692,6 +743,10 @@ enum i40e_status_code i40e_shutdown_admi **/ u16 i40e_clean_asq(struct i40e_hw *hw) { +#ifdef I40E_QV + struct i40e_aq_desc qv_desc = {0}; + struct i40e_aq_desc *qv_desc_on_ring; +#endif /* I40E_QV */ struct i40e_adminq_ring *asq = &(hw->aq.asq); struct i40e_asq_cmd_details *details; u16 ntc = asq->next_to_clean; @@ -700,6 +755,13 @@ u16 i40e_clean_asq(struct i40e_hw *hw) desc = I40E_ADMINQ_DESC(*asq, ntc); details = I40E_ADMINQ_DETAILS(*asq, ntc); +#ifdef I40E_QV + /* copy the descriptor from ring to userspace buffer */ + i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + qv_desc_on_ring = desc; + desc = &qv_desc; +#endif /* I40E_QV */ while (rd32(hw, hw->aq.asq.head) != ntc) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "%s: ntc %d head %d.\n", __FUNCTION__, ntc, @@ -714,11 +776,23 @@ u16 i40e_clean_asq(struct i40e_hw *hw) } i40e_memset(desc, 0, sizeof(*desc), I40E_DMA_MEM); i40e_memset(details, 0, sizeof(*details), I40E_NONDMA_MEM); +#ifdef I40E_QV + /* copy the descriptor from userspace buffer to ring */ + i40e_memcpy(qv_desc_on_ring, desc, + sizeof(struct i40e_aq_desc), I40E_NONDMA_TO_DMA); +#endif /* I40E_QV */ ntc++; if (ntc == asq->count) ntc = 0; desc = I40E_ADMINQ_DESC(*asq, ntc); details = I40E_ADMINQ_DETAILS(*asq, ntc); +#ifdef I40E_QV + /* copy the descriptor from ring to userspace buffer */ + i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + qv_desc_on_ring = desc; + desc = &qv_desc; +#endif /* I40E_QV */ } asq->next_to_clean = ntc; @@ -759,6 +833,10 @@ enum i40e_status_code i40e_asq_send_comm u16 buff_size, struct i40e_asq_cmd_details *cmd_details) { +#ifdef I40E_QV + struct i40e_aq_desc qv_desc = {0}; + struct i40e_aq_desc *qv_desc_on_ring; +#endif /* I40E_QV */ enum i40e_status_code status = I40E_SUCCESS; struct i40e_dma_mem *dma_buff = NULL; struct i40e_asq_cmd_details *details; @@ -855,6 +933,13 @@ enum i40e_status_code i40e_asq_send_comm /* if the desc is available copy the temp desc to the right place */ i40e_memcpy(desc_on_ring, desc, sizeof(struct i40e_aq_desc), I40E_NONDMA_TO_DMA); +#ifdef I40E_QV + /* copy the descriptor from ring to userspace buffer */ + i40e_memcpy(&qv_desc, desc_on_ring, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + qv_desc_on_ring = desc_on_ring; + desc_on_ring = &qv_desc; +#endif /* I40E_QV */ /* if buff is not NULL assume indirect command */ if (buff != NULL) { @@ -871,11 +956,17 @@ enum i40e_status_code i40e_asq_send_comm CPU_TO_LE32(I40E_HI_DWORD(dma_buff->pa)); desc_on_ring->params.external.addr_low = CPU_TO_LE32(I40E_LO_DWORD(dma_buff->pa)); +#ifdef I40E_QV + /* copy the descriptor from userspace buffer to ring */ + i40e_memcpy(qv_desc_on_ring, desc_on_ring, + sizeof(struct i40e_aq_desc), I40E_NONDMA_TO_DMA); +#endif /* I40E_QV */ } /* bump the tail */ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n"); - i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff); + i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, + buff, buff_size); (hw->aq.asq.next_to_use)++; if (hw->aq.asq.next_to_use == hw->aq.asq.count) hw->aq.asq.next_to_use = 0; @@ -890,6 +981,11 @@ enum i40e_status_code i40e_asq_send_comm u32 delay_len = 10; do { +#ifdef I40E_QV + /* copy the descriptor from ring to user buffer */ + i40e_memcpy(desc_on_ring, qv_desc_on_ring, + sizeof(struct i40e_aq_desc), I40E_DMA_TO_NONDMA); +#endif /* I40E_QV */ /* AQ designers suggest use of head for better * timing reliability than DD bit */ @@ -898,11 +994,15 @@ enum i40e_status_code i40e_asq_send_comm /* ugh! delay while spin_lock */ i40e_usec_delay(delay_len); total_delay += delay_len; - } while (total_delay < I40E_ASQ_CMD_TIMEOUT); + } while (total_delay < hw->aq.asq_cmd_timeout); } /* if ready, copy the desc back to temp */ if (i40e_asq_done(hw)) { +#ifdef I40E_QV + /* Swap pointer back */ + desc_on_ring = qv_desc_on_ring; +#endif /* I40E_QV */ i40e_memcpy(desc, desc_on_ring, sizeof(struct i40e_aq_desc), I40E_DMA_TO_NONDMA); if (buff != NULL) @@ -926,11 +1026,9 @@ enum i40e_status_code i40e_asq_send_comm hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; } - if (desc->datalen == buff_size) { - i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, - "AQTX: desc and buffer writeback:\n"); - i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff); - } + i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, + "AQTX: desc and buffer writeback:\n"); + i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size); /* update the error if time out occurred */ if ((!cmd_completed) && @@ -981,6 +1079,10 @@ enum i40e_status_code i40e_clean_arq_ele struct i40e_arq_event_info *e, u16 *pending) { +#ifdef I40E_QV + struct i40e_aq_desc qv_desc = {0}; + struct i40e_aq_desc *qv_desc_on_ring; +#endif /* I40E_QV */ enum i40e_status_code ret_code = I40E_SUCCESS; u16 ntc = hw->aq.arq.next_to_clean; struct i40e_aq_desc *desc; @@ -1006,6 +1108,13 @@ enum i40e_status_code i40e_clean_arq_ele /* now clean the next descriptor */ desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc); +#ifdef I40E_QV + /* copy the descriptor from ring to userspace buffer */ + i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + qv_desc_on_ring = desc; + desc = &qv_desc; +#endif /* I40E_QV */ desc_idx = ntc; flags = LE16_TO_CPU(desc->flags); @@ -1017,19 +1126,20 @@ enum i40e_status_code i40e_clean_arq_ele I40E_DEBUG_AQ_MESSAGE, "AQRX: Event received with error 0x%X.\n", hw->aq.arq_last_status); - } else { - i40e_memcpy(&e->desc, desc, sizeof(struct i40e_aq_desc), - I40E_DMA_TO_NONDMA); - datalen = LE16_TO_CPU(desc->datalen); - e->msg_size = min(datalen, e->msg_size); - if (e->msg_buf != NULL && (e->msg_size != 0)) - i40e_memcpy(e->msg_buf, - hw->aq.arq.r.arq_bi[desc_idx].va, - e->msg_size, I40E_DMA_TO_NONDMA); } + i40e_memcpy(&e->desc, desc, sizeof(struct i40e_aq_desc), + I40E_DMA_TO_NONDMA); + datalen = LE16_TO_CPU(desc->datalen); + e->msg_size = min(datalen, e->msg_size); + if (e->msg_buf != NULL && (e->msg_size != 0)) + i40e_memcpy(e->msg_buf, + hw->aq.arq.r.arq_bi[desc_idx].va, + e->msg_size, I40E_DMA_TO_NONDMA); + i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); - i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf); + i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf, + hw->aq.arq_buf_size); /* Restore the original datalen and buffer address in the desc, * FW updates datalen to indicate the event message @@ -1044,6 +1154,11 @@ enum i40e_status_code i40e_clean_arq_ele desc->datalen = CPU_TO_LE16((u16)bi->size); desc->params.external.addr_high = CPU_TO_LE32(I40E_HI_DWORD(bi->pa)); desc->params.external.addr_low = CPU_TO_LE32(I40E_LO_DWORD(bi->pa)); +#ifdef I40E_QV + /* copy the descriptor from userspace buffer to ring */ + i40e_memcpy(qv_desc_on_ring, desc, + sizeof(struct i40e_aq_desc), I40E_NONDMA_TO_DMA); +#endif /* I40E_QV */ /* set tail = the last cleaned desc index. */ wr32(hw, hw->aq.arq.tail, ntc); Modified: head/sys/dev/i40e/i40e_adminq.h ============================================================================== --- head/sys/dev/i40e/i40e_adminq.h Mon Jul 28 21:14:41 2014 (r269197) +++ head/sys/dev/i40e/i40e_adminq.h Mon Jul 28 21:57:09 2014 (r269198) @@ -64,6 +64,8 @@ struct i40e_adminq_ring { u32 head; u32 tail; u32 len; + u32 bah; + u32 bal; }; /* ASQ transaction details */ @@ -90,6 +92,7 @@ struct i40e_arq_event_info { struct i40e_adminq_info { struct i40e_adminq_ring arq; /* receive queue */ struct i40e_adminq_ring asq; /* send queue */ + u32 asq_cmd_timeout; /* send queue cmd write back timeout*/ u16 num_arq_entries; /* receive queue depth */ u16 num_asq_entries; /* send queue depth */ u16 arq_buf_size; /* receive queue buffer size */ @@ -110,8 +113,8 @@ struct i40e_adminq_info { }; /* general information */ -#define I40E_AQ_LARGE_BUF 512 -#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ +#define I40E_AQ_LARGE_BUF 512 +#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ void i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc, u16 opcode); Modified: head/sys/dev/i40e/i40e_adminq_cmd.h ============================================================================== --- head/sys/dev/i40e/i40e_adminq_cmd.h Mon Jul 28 21:14:41 2014 (r269197) +++ head/sys/dev/i40e/i40e_adminq_cmd.h Mon Jul 28 21:57:09 2014 (r269198) @@ -43,9 +43,6 @@ #define I40E_FW_API_VERSION_MAJOR 0x0001 #define I40E_FW_API_VERSION_MINOR 0x0002 -#ifdef FORTVILLE_A0_SUPPORT -#define I40E_FW_API_VERSION_A0_MINOR 0x0000 -#endif struct i40e_aq_desc { __le16 flags; @@ -698,9 +695,6 @@ struct i40e_aqc_add_get_update_vsi { #define I40E_AQ_VSI_TYPE_PF 0x2 #define I40E_AQ_VSI_TYPE_EMP_MNG 0x3 #define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4 -#ifdef FORTVILLE_A0_SUPPORT -#define I40E_AQ_VSI_FLAG_CLOUD_VSI 0x8 -#endif __le32 addr_high; __le32 addr_low; }; @@ -1223,11 +1217,6 @@ struct i40e_aqc_add_remove_cloud_filters #define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0 #define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \ I40E_AQC_ADD_CLOUD_FILTER_SHIFT) -#ifdef FORTVILLE_A0_SUPPORT -#define I40E_AQC_ADD_CLOUD_FILTER_OIP_GRE 0x0002 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_GRE 0x0004 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_VNL 0x0007 -#endif /* 0x0000 reserved */ #define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001 /* 0x0002 reserved */ @@ -2012,22 +2001,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_star /* Add Udp Tunnel command and completion (direct 0x0B00) */ struct i40e_aqc_add_udp_tunnel { -#ifdef FORTVILLE_A0_SUPPORT - __le16 udp_port; - u8 header_len; /* in DWords, 1 to 15 */ - u8 protocol_type; -#define I40E_AQC_TUNNEL_TYPE_TEREDO 0x0 -#define I40E_AQC_TUNNEL_TYPE_VXLAN 0x2 -#define I40E_AQC_TUNNEL_TYPE_NGE 0x3 - u8 variable_udp_length; -#define I40E_AQC_TUNNEL_FIXED_UDP_LENGTH 0x0 -#define I40E_AQC_TUNNEL_VARIABLE_UDP_LENGTH 0x1 - u8 udp_key_index; -#define I40E_AQC_TUNNEL_KEY_INDEX_VXLAN 0x0 -#define I40E_AQC_TUNNEL_KEY_INDEX_NGE 0x1 -#define I40E_AQC_TUNNEL_KEY_INDEX_PROPRIETARY_UDP 0x2 - u8 reserved[10]; -#else __le16 udp_port; u8 reserved0[3]; u8 protocol_type; @@ -2035,7 +2008,6 @@ struct i40e_aqc_add_udp_tunnel { #define I40E_AQC_TUNNEL_TYPE_NGE 0x01 #define I40E_AQC_TUNNEL_TYPE_TEREDO 0x10 u8 reserved1[10]; -#endif }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel); @@ -2056,13 +2028,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_t struct i40e_aqc_remove_udp_tunnel { u8 reserved[2]; u8 index; /* 0 to 15 */ -#ifdef FORTVILLE_A0_SUPPORT - u8 pf_filters; - u8 total_filters; - u8 reserved2[11]; -#else u8 reserved2[13]; -#endif }; I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel); @@ -2072,37 +2038,13 @@ struct i40e_aqc_del_udp_tunnel_completio u8 index; /* 0 to 15 */ u8 multiple_pfs; u8 total_filters_used; -#ifdef FORTVILLE_A0_SUPPORT - u8 reserved; - u8 tunnels_free; - u8 reserved1[9]; -#else u8 reserved1[11]; -#endif }; I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion); /* tunnel key structure 0x0B10 */ -#ifdef FORTVILLE_A0_SUPPORT -struct i40e_aqc_tunnel_key_structure_A0 { - __le16 key1_off; - __le16 key1_len; - __le16 key2_off; - __le16 key2_len; - __le16 flags; -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01 -/* response flags */ -#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01 -#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02 -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03 - u8 resreved[6]; -}; - -I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure_A0); - -#endif struct i40e_aqc_tunnel_key_structure { u8 key1_off; u8 key2_off; Modified: head/sys/dev/i40e/i40e_common.c ============================================================================== --- head/sys/dev/i40e/i40e_common.c Mon Jul 28 21:14:41 2014 (r269197) +++ head/sys/dev/i40e/i40e_common.c Mon Jul 28 21:57:09 2014 (r269198) @@ -52,9 +52,6 @@ static enum i40e_status_code i40e_set_ma if (hw->vendor_id == I40E_INTEL_VENDOR_ID) { switch (hw->device_id) { -#if defined(FORTVILLE_A0_SUPPORT) || defined(I40E_FPGA_SUPPORT) - case I40E_DEV_ID_FPGA_A: -#endif case I40E_DEV_ID_SFP_XL710: case I40E_DEV_ID_QEMU: case I40E_DEV_ID_KX_A: @@ -63,9 +60,6 @@ static enum i40e_status_code i40e_set_ma case I40E_DEV_ID_QSFP_A: case I40E_DEV_ID_QSFP_B: case I40E_DEV_ID_QSFP_C: -#ifdef FORTVILLE_A0_SUPPORT - case I40E_DEV_ID_10G_BASE_T: -#endif hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_VF: @@ -91,13 +85,15 @@ static enum i40e_status_code i40e_set_ma * @mask: debug mask * @desc: pointer to admin queue descriptor * @buffer: pointer to command buffer + * @buf_len: max length of buffer * * Dumps debug log about adminq command with descriptor contents. **/ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, - void *buffer) + void *buffer, u16 buf_len) { struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc; + u16 len = LE16_TO_CPU(aq_desc->datalen); u8 *aq_buffer = (u8 *)buffer; u32 data[4]; u32 i = 0; @@ -121,7 +117,9 @@ void i40e_debug_aq(struct i40e_hw *hw, e if ((buffer != NULL) && (aq_desc->datalen != 0)) { i40e_memset(data, 0, sizeof(data), I40E_NONDMA_MEM); i40e_debug(hw, mask, "AQ CMD Buffer:\n"); - for (i = 0; i < LE16_TO_CPU(aq_desc->datalen); i++) { + if (buf_len < len) + len = buf_len; + for (i = 0; i < len; i++) { data[((i % 16) / 4)] |= ((u32)aq_buffer[i]) << (8 * (i % 4)); if ((i % 16) == 15) { @@ -572,7 +570,6 @@ enum i40e_status_code i40e_init_shared_c break; default: return I40E_ERR_DEVICE_NOT_SUPPORTED; - break; } hw->phy.get_link_info = TRUE; @@ -712,8 +709,10 @@ void i40e_pre_tx_queue_cfg(struct i40e_h u32 reg_block = 0; u32 reg_val; - if (abs_queue_idx >= 128) + if (abs_queue_idx >= 128) { reg_block = abs_queue_idx / 128; + abs_queue_idx %= 128; + } reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block)); reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK; @@ -762,6 +761,8 @@ static enum i40e_media_type i40e_get_med switch (hw->phy.link_info.phy_type) { case I40E_PHY_TYPE_10GBASE_SR: case I40E_PHY_TYPE_10GBASE_LR: + case I40E_PHY_TYPE_1000BASE_SX: + case I40E_PHY_TYPE_1000BASE_LX: case I40E_PHY_TYPE_40GBASE_SR4: case I40E_PHY_TYPE_40GBASE_LR4: media = I40E_MEDIA_TYPE_FIBER; @@ -797,11 +798,7 @@ static enum i40e_media_type i40e_get_med return media; } -#ifndef FORTVILLE_A0_SUPPORT #define I40E_PF_RESET_WAIT_COUNT 100 -#else -#define I40E_PF_RESET_WAIT_COUNT 200 -#endif /** * i40e_pf_reset - Reset the PF * @hw: pointer to the hardware structure @@ -878,6 +875,99 @@ enum i40e_status_code i40e_pf_reset(stru } /** + * i40e_clear_hw - clear out any left over hw state + * @hw: pointer to the hw struct + * + * Clear queues and interrupts, typically called at init time, + * but after the capabilities have been found so we know how many + * queues and msix vectors have been allocated. + **/ +void i40e_clear_hw(struct i40e_hw *hw) +{ + u32 num_queues, base_queue; + u32 num_pf_int; + u32 num_vf_int; + u32 num_vfs; + u32 i, j; + u32 val; + u32 eol = 0x7ff; + + /* get number of interrupts, queues, and vfs */ + val = rd32(hw, I40E_GLPCI_CNF2); + num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >> + I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT; + num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >> + I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT; + + val = rd32(hw, I40E_PFLAN_QALLOC); + base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >> + I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; + j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> + I40E_PFLAN_QALLOC_LASTQ_SHIFT; + if (val & I40E_PFLAN_QALLOC_VALID_MASK) + num_queues = (j - base_queue) + 1; + else + num_queues = 0; + + val = rd32(hw, I40E_PF_VT_PFALLOC); + i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >> + I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; + j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> + I40E_PF_VT_PFALLOC_LASTVF_SHIFT; + if (val & I40E_PF_VT_PFALLOC_VALID_MASK) + num_vfs = (j - i) + 1; + else + num_vfs = 0; + + /* stop all the interrupts */ + wr32(hw, I40E_PFINT_ICR0_ENA, 0); + val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT; + for (i = 0; i < num_pf_int - 2; i++) + wr32(hw, I40E_PFINT_DYN_CTLN(i), val); + + /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */ + val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT; + wr32(hw, I40E_PFINT_LNKLST0, val); + for (i = 0; i < num_pf_int - 2; i++) + wr32(hw, I40E_PFINT_LNKLSTN(i), val); + val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT; + for (i = 0; i < num_vfs; i++) + wr32(hw, I40E_VPINT_LNKLST0(i), val); + for (i = 0; i < num_vf_int - 2; i++) + wr32(hw, I40E_VPINT_LNKLSTN(i), val); + + /* warn the HW of the coming Tx disables */ + for (i = 0; i < num_queues; i++) { + u32 abs_queue_idx = base_queue + i; + u32 reg_block = 0; + + if (abs_queue_idx >= 128) { + reg_block = abs_queue_idx / 128; + abs_queue_idx %= 128; + } + + val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block)); + val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK; + val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT); + val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK; + + wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val); + } + i40e_usec_delay(400); + + /* stop all the queues */ + for (i = 0; i < num_queues; i++) { + wr32(hw, I40E_QINT_TQCTL(i), 0); + wr32(hw, I40E_QTX_ENA(i), 0); + wr32(hw, I40E_QINT_RQCTL(i), 0); + wr32(hw, I40E_QRX_ENA(i), 0); + } + + /* short wait for all queue disables to settle */ + i40e_usec_delay(50); +} + +/** * i40e_clear_pxe_mode - clear pxe operations mode * @hw: pointer to the hw struct * @@ -886,16 +976,8 @@ enum i40e_status_code i40e_pf_reset(stru **/ void i40e_clear_pxe_mode(struct i40e_hw *hw) { -#if defined(FORTVILLE_A0_SUPPORT) || defined(I40E_FPGA_SUPPORT) - u32 reg; - - /* Clear single descriptor fetch/write-back mode */ - reg = rd32(hw, I40E_GLLAN_RCTL_0); - wr32(hw, I40E_GLLAN_RCTL_0, (reg & (~I40E_GLLAN_RCTL_0_PXE_MODE_MASK))); -#else if (i40e_check_asq_alive(hw)) i40e_aq_clear_pxe_mode(hw, NULL); -#endif } /** @@ -1120,7 +1202,7 @@ enum i40e_status_code i40e_set_fc(struct status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities, NULL); if (status) { - *aq_failures |= I40E_SET_FC_AQ_FAIL_GET1; + *aq_failures |= I40E_SET_FC_AQ_FAIL_GET; return status; } @@ -1145,31 +1227,19 @@ enum i40e_status_code i40e_set_fc(struct if (status) *aq_failures |= I40E_SET_FC_AQ_FAIL_SET; - - /* Get the abilities to set hw->fc.current_mode correctly */ - status = i40e_aq_get_phy_capabilities(hw, FALSE, false, - &abilities, NULL); - if (status) { - /* Wait a little bit and try once more */ - i40e_msec_delay(1000); - status = i40e_aq_get_phy_capabilities(hw, FALSE, false, - &abilities, NULL); - } - if (status) { - *aq_failures |= I40E_SET_FC_AQ_FAIL_GET2; - return status; - } } - /* Copy the what was returned from get capabilities into fc */ - if ((abilities.abilities & I40E_AQ_PHY_FLAG_PAUSE_TX) && - (abilities.abilities & I40E_AQ_PHY_FLAG_PAUSE_RX)) - hw->fc.current_mode = I40E_FC_FULL; - else if (abilities.abilities & I40E_AQ_PHY_FLAG_PAUSE_TX) - hw->fc.current_mode = I40E_FC_TX_PAUSE; - else if (abilities.abilities & I40E_AQ_PHY_FLAG_PAUSE_RX) - hw->fc.current_mode = I40E_FC_RX_PAUSE; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407282157.s6SLvAJI028590>