From 6b3e017e5d25f15da73f7700f7f2ac553ef1a2e9 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Thu, 8 Dec 2016 14:07:29 +0100 Subject: Imported Upstream version 16.11 Change-Id: I1944c65ddc88a9ad70f8c0eb6731552b84fbcb77 Signed-off-by: Christian Ehrhardt --- drivers/net/thunderx/base/nicvf_bsvf.c | 72 +++++++++++++++++++++++++++++ drivers/net/thunderx/base/nicvf_bsvf.h | 76 +++++++++++++++++++++++++++++++ drivers/net/thunderx/base/nicvf_hw.c | 37 ++++++++++++--- drivers/net/thunderx/base/nicvf_hw.h | 29 +++++++----- drivers/net/thunderx/base/nicvf_hw_defs.h | 3 ++ drivers/net/thunderx/base/nicvf_mbox.c | 47 ++++++++++++++++++- drivers/net/thunderx/base/nicvf_mbox.h | 21 ++++++++- 7 files changed, 264 insertions(+), 21 deletions(-) create mode 100644 drivers/net/thunderx/base/nicvf_bsvf.c create mode 100644 drivers/net/thunderx/base/nicvf_bsvf.h (limited to 'drivers/net/thunderx/base') diff --git a/drivers/net/thunderx/base/nicvf_bsvf.c b/drivers/net/thunderx/base/nicvf_bsvf.c new file mode 100644 index 00000000..9e028a3a --- /dev/null +++ b/drivers/net/thunderx/base/nicvf_bsvf.c @@ -0,0 +1,72 @@ +/* + * BSD LICENSE + * + * Copyright (C) Cavium networks Ltd. 2016. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Cavium networks nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "nicvf_bsvf.h" +#include "nicvf_plat.h" + +static SIMPLEQ_HEAD(, svf_entry) head = SIMPLEQ_HEAD_INITIALIZER(head); + +void +nicvf_bsvf_push(struct svf_entry *entry) +{ + assert(entry != NULL); + assert(entry->vf != NULL); + + SIMPLEQ_INSERT_TAIL(&head, entry, next); +} + +struct svf_entry * +nicvf_bsvf_pop(void) +{ + struct svf_entry *entry; + + assert(!SIMPLEQ_EMPTY(&head)); + + entry = SIMPLEQ_FIRST(&head); + + assert(entry != NULL); + assert(entry->vf != NULL); + + SIMPLEQ_REMOVE_HEAD(&head, next); + + return entry; +} + +int +nicvf_bsvf_empty(void) +{ + return SIMPLEQ_EMPTY(&head); +} diff --git a/drivers/net/thunderx/base/nicvf_bsvf.h b/drivers/net/thunderx/base/nicvf_bsvf.h new file mode 100644 index 00000000..5d5a25e2 --- /dev/null +++ b/drivers/net/thunderx/base/nicvf_bsvf.h @@ -0,0 +1,76 @@ +/* + * BSD LICENSE + * + * Copyright (C) Cavium networks Ltd. 2016. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Cavium networks nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __THUNDERX_NICVF_BSVF_H__ +#define __THUNDERX_NICVF_BSVF_H__ + +#include + +struct nicvf; + +/** + * The base queue structure to hold secondary qsets. + */ +struct svf_entry { + SIMPLEQ_ENTRY(svf_entry) next; /**< Next element's pointer */ + struct nicvf *vf; /**< Holder of a secondary qset */ +}; + +/** + * Enqueue new entry to secondary qsets. + * + * @param entry + * Entry to be enqueued. + */ +void +nicvf_bsvf_push(struct svf_entry *entry); + +/** + * Dequeue an entry from secondary qsets. + * + * @return + * Dequeued entry. + */ +struct svf_entry * +nicvf_bsvf_pop(void); + +/** + * Check if the queue of secondary qsets is empty. + * + * @return + * 0 on non-empty + * otherwise empty + */ +int +nicvf_bsvf_empty(void); + +#endif /* __THUNDERX_NICVF_BSVF_H__ */ diff --git a/drivers/net/thunderx/base/nicvf_hw.c b/drivers/net/thunderx/base/nicvf_hw.c index 001b0edd..04b3b69c 100644 --- a/drivers/net/thunderx/base/nicvf_hw.c +++ b/drivers/net/thunderx/base/nicvf_hw.c @@ -140,8 +140,15 @@ nicvf_base_init(struct nicvf *nic) if (nic->subsystem_device_id == 0) return NICVF_ERR_BASE_INIT; - if (nicvf_hw_version(nic) == NICVF_PASS2) - nic->hwcap |= NICVF_CAP_TUNNEL_PARSING; + if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN88XX_PASS2_NICVF) + nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2; + + if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN81XX_NICVF) + nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2; + + if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN83XX_NICVF) + nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2 | + NICVF_CAP_DISABLE_APAD; return NICVF_OK; } @@ -494,9 +501,9 @@ nicvf_qsize_rbdr_roundup(uint32_t val) } int -nicvf_qset_rbdr_precharge(struct nicvf *nic, uint16_t ridx, - rbdr_pool_get_handler handler, - void *opaque, uint32_t max_buffs) +nicvf_qset_rbdr_precharge(void *dev, struct nicvf *nic, + uint16_t ridx, rbdr_pool_get_handler handler, + uint32_t max_buffs) { struct rbdr_entry_t *desc, *desc0; struct nicvf_rbdr *rbdr = nic->rbdr; @@ -511,7 +518,7 @@ nicvf_qset_rbdr_precharge(struct nicvf *nic, uint16_t ridx, if (count >= max_buffs) break; desc0 = desc + count; - phy = handler(opaque); + phy = handler(dev, nic); if (phy) { desc0->full_addr = phy; count++; @@ -721,6 +728,24 @@ nicvf_vlan_hw_strip(struct nicvf *nic, bool enable) nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val); } +void +nicvf_apad_config(struct nicvf *nic, bool enable) +{ + uint64_t val; + + /* APAD always enabled in this device */ + if (!(nic->hwcap & NICVF_CAP_DISABLE_APAD)) + return; + + val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG); + if (enable) + val &= ~(1ULL << NICVF_QS_RQ_DIS_APAD_SHIFT); + else + val |= (1ULL << NICVF_QS_RQ_DIS_APAD_SHIFT); + + nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val); +} + void nicvf_rss_set_key(struct nicvf *nic, uint8_t *key) { diff --git a/drivers/net/thunderx/base/nicvf_hw.h b/drivers/net/thunderx/base/nicvf_hw.h index 9db1d30c..14fb2feb 100644 --- a/drivers/net/thunderx/base/nicvf_hw.h +++ b/drivers/net/thunderx/base/nicvf_hw.h @@ -37,11 +37,13 @@ #include "nicvf_hw_defs.h" -#define PCI_VENDOR_ID_CAVIUM 0x177D -#define PCI_DEVICE_ID_THUNDERX_PASS1_NICVF 0x0011 -#define PCI_DEVICE_ID_THUNDERX_PASS2_NICVF 0xA034 -#define PCI_SUB_DEVICE_ID_THUNDERX_PASS1_NICVF 0xA11E -#define PCI_SUB_DEVICE_ID_THUNDERX_PASS2_NICVF 0xA134 +#define PCI_VENDOR_ID_CAVIUM 0x177D +#define PCI_DEVICE_ID_THUNDERX_CN88XX_PASS1_NICVF 0x0011 +#define PCI_DEVICE_ID_THUNDERX_NICVF 0xA034 +#define PCI_SUB_DEVICE_ID_CN88XX_PASS1_NICVF 0xA11E +#define PCI_SUB_DEVICE_ID_CN88XX_PASS2_NICVF 0xA134 +#define PCI_SUB_DEVICE_ID_CN81XX_NICVF 0xA234 +#define PCI_SUB_DEVICE_ID_CN83XX_NICVF 0xA334 #define NICVF_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -50,10 +52,11 @@ #define NICVF_GET_TX_STATS(reg) \ nicvf_reg_read(nic, NIC_VNIC_TX_STAT_0_4 | (reg << 3)) -#define NICVF_PASS1 (PCI_SUB_DEVICE_ID_THUNDERX_PASS1_NICVF) -#define NICVF_PASS2 (PCI_SUB_DEVICE_ID_THUNDERX_PASS2_NICVF) - -#define NICVF_CAP_TUNNEL_PARSING (1ULL << 0) +#define NICVF_CAP_TUNNEL_PARSING (1ULL << 0) +/* Additional word in Rx descriptor to hold optional tunneling extension info */ +#define NICVF_CAP_CQE_RX2 (1ULL << 1) +/* The device capable of setting NIC_CQE_RX_S[APAD] == 0 */ +#define NICVF_CAP_DISABLE_APAD (1ULL << 2) enum nicvf_tns_mode { NIC_TNS_BYPASS_MODE, @@ -85,7 +88,7 @@ enum nicvf_err_e { NICVF_ERR_RSS_GET_SZ, /* -8171 */ }; -typedef nicvf_phys_addr_t (*rbdr_pool_get_handler)(void *opaque); +typedef nicvf_phys_addr_t (*rbdr_pool_get_handler)(void *dev, void *opaque); struct nicvf_hw_rx_qstats { uint64_t q_rx_bytes; @@ -194,8 +197,8 @@ int nicvf_qset_reclaim(struct nicvf *nic); int nicvf_qset_rbdr_config(struct nicvf *nic, uint16_t qidx); int nicvf_qset_rbdr_reclaim(struct nicvf *nic, uint16_t qidx); -int nicvf_qset_rbdr_precharge(struct nicvf *nic, uint16_t ridx, - rbdr_pool_get_handler handler, void *opaque, +int nicvf_qset_rbdr_precharge(void *dev, struct nicvf *nic, + uint16_t ridx, rbdr_pool_get_handler handler, uint32_t max_buffs); int nicvf_qset_rbdr_active(struct nicvf *nic, uint16_t qidx); @@ -217,6 +220,8 @@ uint32_t nicvf_qsize_sq_roundup(uint32_t val); void nicvf_vlan_hw_strip(struct nicvf *nic, bool enable); +void nicvf_apad_config(struct nicvf *nic, bool enable); + int nicvf_rss_config(struct nicvf *nic, uint32_t qcnt, uint64_t cfg); int nicvf_rss_term(struct nicvf *nic); diff --git a/drivers/net/thunderx/base/nicvf_hw_defs.h b/drivers/net/thunderx/base/nicvf_hw_defs.h index 2f2b2259..00dd2feb 100644 --- a/drivers/net/thunderx/base/nicvf_hw_defs.h +++ b/drivers/net/thunderx/base/nicvf_hw_defs.h @@ -105,6 +105,8 @@ #define NICVF_INTR_MBOX_SHIFT 22 #define NICVF_INTR_QS_ERR_SHIFT 23 +#define NICVF_QS_RQ_DIS_APAD_SHIFT 22 + #define NICVF_INTR_CQ_MASK (0xFF << NICVF_INTR_CQ_SHIFT) #define NICVF_INTR_SQ_MASK (0xFF << NICVF_INTR_SQ_SHIFT) #define NICVF_INTR_RBDR_MASK (0x03 << NICVF_INTR_RBDR_SHIFT) @@ -207,6 +209,7 @@ #define NICVF_CQE_RX2_RBPTR_WORD (7) #define NICVF_STATIC_ASSERT(s) _Static_assert(s, #s) +#define assert_primary(nic) assert((nic)->sqs_mode == 0) typedef uint64_t nicvf_phys_addr_t; diff --git a/drivers/net/thunderx/base/nicvf_mbox.c b/drivers/net/thunderx/base/nicvf_mbox.c index 9c5cd834..3b7b8a51 100644 --- a/drivers/net/thunderx/base/nicvf_mbox.c +++ b/drivers/net/thunderx/base/nicvf_mbox.c @@ -62,6 +62,9 @@ static const char *mbox_message[NIC_MBOX_MSG_MAX] = { [NIC_MBOX_MSG_RESET_STAT_COUNTER] = "NIC_MBOX_MSG_RESET_STAT_COUNTER", [NIC_MBOX_MSG_CFG_DONE] = "NIC_MBOX_MSG_CFG_DONE", [NIC_MBOX_MSG_SHUTDOWN] = "NIC_MBOX_MSG_SHUTDOWN", + [NIC_MBOX_MSG_RES_BIT] = "NIC_MBOX_MSG_RES_BIT", + [NIC_MBOX_MSG_RSS_SIZE_RES_BIT] = "NIC_MBOX_MSG_RSS_SIZE", + [NIC_MBOX_MSG_ALLOC_SQS_RES_BIT] = "NIC_MBOX_MSG_ALLOC_SQS", }; static inline const char * __attribute__((unused)) @@ -173,7 +176,7 @@ nicvf_handle_mbx_intr(struct nicvf *nic) case NIC_MBOX_MSG_NACK: nic->pf_nacked = true; break; - case NIC_MBOX_MSG_RSS_SIZE: + case NIC_MBOX_MSG_RSS_SIZE_RES_BIT: nic->rss_info.rss_size = mbx.rss_size.ind_tbl_size; nic->pf_acked = true; break; @@ -183,6 +186,26 @@ nicvf_handle_mbx_intr(struct nicvf *nic) nic->speed = mbx.link_status.speed; nic->pf_acked = true; break; + case NIC_MBOX_MSG_ALLOC_SQS_RES_BIT: + assert_primary(nic); + if (mbx.sqs_alloc.qs_count != nic->sqs_count) { + nicvf_log_error("Received %" PRIu8 "/%" PRIu8 + " secondary qsets", + mbx.sqs_alloc.qs_count, + nic->sqs_count); + abort(); + } + for (i = 0; i < mbx.sqs_alloc.qs_count; i++) { + if (mbx.sqs_alloc.svf[i] != nic->snicvf[i]->vf_id) { + nicvf_log_error("Received secondary qset[%zu] " + "ID %" PRIu8 " expected %" + PRIu8, i, mbx.sqs_alloc.svf[i], + nic->snicvf[i]->vf_id); + abort(); + } + } + nic->pf_acked = true; + break; default: nicvf_log_error("Invalid message from PF, msg_id=0x%hhx %s", mbx.msg.msg, nicvf_mbox_msg_str(mbx.msg.msg)); @@ -314,10 +337,32 @@ nicvf_mbox_qset_config(struct nicvf *nic, struct pf_qs_cfg *qs_cfg) /* Send a mailbox msg to PF to config Qset */ mbx.msg.msg = NIC_MBOX_MSG_QS_CFG; mbx.qs.num = nic->vf_id; + mbx.qs.sqs_count = nic->sqs_count; mbx.qs.cfg = qs_cfg->value; return nicvf_mbox_send_msg_to_pf(nic, &mbx); } +int +nicvf_mbox_request_sqs(struct nicvf *nic) +{ + struct nic_mbx mbx = { .msg = { 0 } }; + size_t i; + + assert_primary(nic); + assert(nic->sqs_count > 0); + assert(nic->sqs_count <= MAX_SQS_PER_VF); + + mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS; + mbx.sqs_alloc.spec = 1; + mbx.sqs_alloc.qs_count = nic->sqs_count; + + /* Set no of Rx/Tx queues in each of the SQsets */ + for (i = 0; i < nic->sqs_count; i++) + mbx.sqs_alloc.svf[i] = nic->snicvf[i]->vf_id; + + return nicvf_mbox_send_msg_to_pf(nic, &mbx); +} + int nicvf_mbox_rq_drop_config(struct nicvf *nic, uint16_t qidx, bool enable) { diff --git a/drivers/net/thunderx/base/nicvf_mbox.h b/drivers/net/thunderx/base/nicvf_mbox.h index 7c0c6a97..084f3a76 100644 --- a/drivers/net/thunderx/base/nicvf_mbox.h +++ b/drivers/net/thunderx/base/nicvf_mbox.h @@ -36,6 +36,7 @@ #include #include "nicvf_plat.h" +#include "../nicvf_struct.h" /* PF <--> VF Mailbox communication * Two 64bit registers are shared between PF and VF for each VF @@ -67,10 +68,16 @@ #define NIC_MBOX_MSG_ALLOC_SQS 0x12 /* Allocate secondary Qset */ #define NIC_MBOX_MSG_LOOPBACK 0x16 /* Set interface in loopback */ #define NIC_MBOX_MSG_RESET_STAT_COUNTER 0x17 /* Reset statistics counters */ -#define NIC_MBOX_MSG_CFG_DONE 0xF0 /* VF configuration done */ -#define NIC_MBOX_MSG_SHUTDOWN 0xF1 /* VF is being shutdown */ +#define NIC_MBOX_MSG_CFG_DONE 0x7E /* VF configuration done */ +#define NIC_MBOX_MSG_SHUTDOWN 0x7F /* VF is being shutdown */ +#define NIC_MBOX_MSG_RES_BIT 0x80 /* Reset bit from PF */ #define NIC_MBOX_MSG_MAX 0x100 /* Maximum number of messages */ +#define NIC_MBOX_MSG_RSS_SIZE_RES_BIT \ + (NIC_MBOX_MSG_RSS_SIZE | NIC_MBOX_MSG_RES_BIT) +#define NIC_MBOX_MSG_ALLOC_SQS_RES_BIT \ + (NIC_MBOX_MSG_ALLOC_SQS | NIC_MBOX_MSG_RES_BIT) + /* Get vNIC VF configuration */ struct nic_cfg_msg { uint8_t msg; @@ -155,6 +162,14 @@ struct bgx_link_status { uint32_t speed; }; +/* Allocate additional SQS to VF */ +struct sqs_alloc { + uint8_t msg; + uint8_t spec; + uint8_t qs_count; + uint8_t svf[MAX_SQS_PER_VF]; +}; + /* Set interface in loopback mode */ struct set_loopback { uint8_t msg; @@ -201,6 +216,7 @@ union { struct rss_sz_msg rss_size; struct rss_cfg_msg rss_cfg; struct bgx_link_status link_status; + struct sqs_alloc sqs_alloc; struct set_loopback lbk; struct reset_stat_cfg reset_stat; }; @@ -211,6 +227,7 @@ NICVF_STATIC_ASSERT(sizeof(struct nic_mbx) <= 16); int nicvf_handle_mbx_intr(struct nicvf *nic); int nicvf_mbox_check_pf_ready(struct nicvf *nic); int nicvf_mbox_qset_config(struct nicvf *nic, struct pf_qs_cfg *qs_cfg); +int nicvf_mbox_request_sqs(struct nicvf *nic); int nicvf_mbox_rq_config(struct nicvf *nic, uint16_t qidx, struct pf_rq_cfg *pf_rq_cfg); int nicvf_mbox_sq_config(struct nicvf *nic, uint16_t qidx); -- cgit 1.2.3-korg