aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/cxgbe/common
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cxgbe/common')
-rw-r--r--sys/dev/cxgbe/common/common.h43
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c7
-rw-r--r--sys/dev/cxgbe/common/t4vf_hw.c32
3 files changed, 78 insertions, 4 deletions
diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h
index 894e0444b710..6e80ce40648b 100644
--- a/sys/dev/cxgbe/common/common.h
+++ b/sys/dev/cxgbe/common/common.h
@@ -948,6 +948,7 @@ int t4vf_get_vfres(struct adapter *adapter);
int t4vf_prep_adapter(struct adapter *adapter);
int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port,
unsigned int *naddr, u8 *addr);
+int t4vf_get_vf_vlan(struct adapter *adapter);
int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid,
enum t4_bar2_qtype qtype, int user, u64 *pbar2_qoffset,
unsigned int *pbar2_qid);
@@ -963,4 +964,46 @@ port_top_speed(const struct port_info *pi)
return (fwcap_to_speed(pi->link_cfg.pcaps) / 1000);
}
+/* SET_TCB_FIELD sent as a ULP command looks like this */
+#define LEN__SET_TCB_FIELD_ULP (sizeof(struct ulp_txpkt) + \
+ sizeof(struct ulptx_idata) + sizeof(struct cpl_set_tcb_field_core))
+
+static inline void *
+mk_set_tcb_field_ulp(struct adapter *sc, void *cur, int tid, uint16_t word,
+ uint64_t mask, uint64_t val)
+{
+ struct ulp_txpkt *ulpmc;
+ struct ulptx_idata *ulpsc;
+ struct cpl_set_tcb_field_core *req;
+
+ MPASS(((uintptr_t)cur & 7) == 0);
+
+ ulpmc = cur;
+ ulpmc->cmd_dest = htobe32(V_ULPTX_CMD(ULP_TX_PKT) |
+ V_ULP_TXPKT_DEST(ULP_TXPKT_DEST_TP));
+ ulpmc->len = htobe32(howmany(LEN__SET_TCB_FIELD_ULP, 16));
+
+ ulpsc = (struct ulptx_idata *)(ulpmc + 1);
+ ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_IMM));
+ ulpsc->len = htobe32(sizeof(*req));
+
+ req = (struct cpl_set_tcb_field_core *)(ulpsc + 1);
+ OPCODE_TID(req) = htobe32(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
+ req->reply_ctrl = htobe16(F_NO_REPLY);
+ req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(0));
+ req->mask = htobe64(mask);
+ req->val = htobe64(val);
+
+ /*
+ * ULP_TX is an 8B processor but the firmware transfers WRs in 16B
+ * chunks. The master command for set_tcb_field does not end at a 16B
+ * boundary so it needs to be padded with a no-op.
+ */
+ MPASS((LEN__SET_TCB_FIELD_ULP & 0xf) != 0);
+ ulpsc = (struct ulptx_idata *)(req + 1);
+ ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
+ ulpsc->len = htobe32(0);
+
+ return (ulpsc + 1);
+}
#endif /* __CHELSIO_COMMON_H */
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index 3d22673d34c1..07940a44f66e 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -11377,7 +11377,7 @@ out:
* @vlan: The vlanid to be set
*
*/
-int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
+int t4_set_vlan_acl(struct adapter *adap, unsigned int pf, unsigned int vf,
u16 vlan)
{
struct fw_acl_vlan_cmd vlan_cmd;
@@ -11389,9 +11389,10 @@ int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
F_FW_CMD_REQUEST |
F_FW_CMD_WRITE |
F_FW_CMD_EXEC |
- V_FW_ACL_VLAN_CMD_PFN(adap->pf) |
+ V_FW_ACL_VLAN_CMD_PFN(pf) |
V_FW_ACL_VLAN_CMD_VFN(vf));
- vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd));
+ vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd) |
+ V_FW_ACL_VLAN_CMD_PMASK(1 << pf));
/* Drop all packets that donot match vlan id */
vlan_cmd.dropnovlan_fm = (enable
? (F_FW_ACL_VLAN_CMD_DROPNOVLAN |
diff --git a/sys/dev/cxgbe/common/t4vf_hw.c b/sys/dev/cxgbe/common/t4vf_hw.c
index 25ab3db77c72..8091eb5db2f9 100644
--- a/sys/dev/cxgbe/common/t4vf_hw.c
+++ b/sys/dev/cxgbe/common/t4vf_hw.c
@@ -139,7 +139,10 @@ int t4vf_get_sge_params(struct adapter *adapter)
* This is based on the PF from which we're instantiated.
*/
whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI));
- pf = G_SOURCEPF(whoami);
+ if (chip_id(adapter) <= CHELSIO_T5)
+ pf = G_SOURCEPF(whoami);
+ else
+ pf = G_T6_SOURCEPF(whoami);
s_hps = (S_HOSTPAGESIZEPF0 +
(S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf);
@@ -426,3 +429,30 @@ int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port,
return ret;
}
+
+/*
+ * t4vf_get_vf_vlan - Get the VLAN ID to be set to the VI of this VF.
+ * @adapter: The adapter
+ *
+ * Find the VLAN ID to be set to the VF's VI. The requested VLAN ID
+ * is from the host OS via callback in the PF driver.
+ */
+int t4vf_get_vf_vlan(struct adapter *adapter)
+{
+ struct fw_acl_vlan_cmd cmd = {0};
+ int vlan = 0;
+ int ret = 0;
+
+ cmd.op_to_vfn = htonl(V_FW_CMD_OP(FW_ACL_VLAN_CMD) |
+ F_FW_CMD_REQUEST | F_FW_CMD_READ);
+
+ /* Note: Do not enable the ACL */
+ cmd.en_to_len16 = htonl((unsigned int)FW_LEN16(cmd));
+
+ ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
+
+ if (!ret)
+ vlan = be16_to_cpu(cmd.vlanid[0]);
+
+ return vlan;
+}