diff options
Diffstat (limited to 'sys/dev/cxgbe/common')
-rw-r--r-- | sys/dev/cxgbe/common/common.h | 43 | ||||
-rw-r--r-- | sys/dev/cxgbe/common/t4_hw.c | 7 | ||||
-rw-r--r-- | sys/dev/cxgbe/common/t4vf_hw.c | 32 |
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; +} |