svn commit: r269198 - in head/sys: dev/i40e modules/i40e
Jack F Vogel
jfv at FreeBSD.org
Mon Jul 28 21:57:11 UTC 2014
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 ***
More information about the svn-src-head
mailing list