diff options
Diffstat (limited to 'drivers/net/cxgbe/base')
-rw-r--r-- | drivers/net/cxgbe/base/adapter.h | 75 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/common.h | 168 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_chip_type.h | 34 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_hw.c | 783 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_hw.h | 34 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_msg.h | 34 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_pci_id_tbl.h | 34 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_regs.h | 141 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4_regs_values.h | 34 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4fw_interface.h | 401 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4vf_hw.c | 874 | ||||
-rw-r--r-- | drivers/net/cxgbe/base/t4vf_hw.h | 15 |
12 files changed, 2136 insertions, 491 deletions
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h index f2057af1..55cb2e91 100644 --- a/drivers/net/cxgbe/base/adapter.h +++ b/drivers/net/cxgbe/base/adapter.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ /* This file should not be included directly. Include common.h instead. */ @@ -68,6 +40,7 @@ struct port_info { u8 port_type; /* firmware port type */ u8 mod_type; /* firmware module type */ u8 port_id; /* physical port ID */ + u8 pidx; /* port index for this PF */ u8 tx_chan; /* associated channel */ u8 n_rx_qsets; /* # of rx qsets */ @@ -77,6 +50,7 @@ struct port_info { u16 *rss; /* rss table */ u8 rss_mode; /* rss mode */ u16 rss_size; /* size of VI's RSS table slice */ + u64 rss_hf; /* RSS Hash Function */ }; /* Enable or disable autonegotiation. If this is set to enable, @@ -196,6 +170,7 @@ struct sge_eth_rxq { /* a SW Ethernet Rx queue */ * scenario where a packet needs 32 bytes. */ #define ETH_COALESCE_PKT_NUM 15 +#define ETH_COALESCE_VF_PKT_NUM 7 #define ETH_COALESCE_PKT_PER_DESC 2 struct tx_eth_coal_desc { @@ -225,6 +200,10 @@ struct eth_coalesce { unsigned int len; unsigned int flits; unsigned int max; + __u8 ethmacdst[ETHER_ADDR_LEN]; + __u8 ethmacsrc[ETHER_ADDR_LEN]; + __be16 ethtype; + __be16 vlantci; }; struct sge_txq { @@ -247,6 +226,7 @@ struct sge_txq { unsigned int equeidx; /* last sent credit request */ unsigned int last_pidx; /* last pidx recorded by tx monitor */ unsigned int last_coal_idx;/* last coal-idx recorded by tx monitor */ + unsigned int abs_id; int db_disabled; /* doorbell state */ unsigned short db_pidx; /* doorbell producer index */ @@ -267,6 +247,7 @@ struct sge_eth_tx_stats { /* Ethernet tx queue statistics */ struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */ struct sge_txq q; struct rte_eth_dev *eth_dev; /* port that this queue belongs to */ + struct rte_eth_dev_data *data; struct sge_eth_tx_stats stats; /* queue statistics */ rte_spinlock_t txq_lock; @@ -308,7 +289,7 @@ struct adapter { struct rte_pci_device *pdev; /* associated rte pci device */ struct rte_eth_dev *eth_dev; /* first port's rte eth device */ struct adapter_params params; /* adapter parameters */ - struct port_info port[MAX_NPORTS]; /* ports belonging to this adapter */ + struct port_info *port[MAX_NPORTS];/* ports belonging to this adapter */ struct sge sge; /* associated SGE */ /* support for single-threading access to adapter mailbox registers */ @@ -327,6 +308,18 @@ struct adapter { int use_unpacked_mode; /* unpacked rx mode state */ }; +/** + * adap2pinfo - return the port_info of a port + * @adap: the adapter + * @idx: the port index + * + * Return the port_info structure for the port of the given index. + */ +static inline struct port_info *adap2pinfo(const struct adapter *adap, int idx) +{ + return adap->port[idx]; +} + #define CXGBE_PCI_REG(reg) rte_read32(reg) static inline uint64_t cxgbe_read_addr64(volatile void *addr) @@ -602,7 +595,7 @@ static inline int t4_os_find_pci_capability(struct adapter *adapter, int cap) static inline void t4_os_set_hw_addr(struct adapter *adapter, int port_idx, u8 hw_addr[]) { - struct port_info *pi = &adapter->port[port_idx]; + struct port_info *pi = adap2pinfo(adapter, port_idx); ether_addr_copy((struct ether_addr *)hw_addr, &pi->eth_dev->data->mac_addrs[0]); @@ -687,18 +680,6 @@ static inline void t4_os_atomic_list_del(struct mbox_entry *entry, t4_os_unlock(lock); } -/** - * adap2pinfo - return the port_info of a port - * @adap: the adapter - * @idx: the port index - * - * Return the port_info structure for the port of the given index. - */ -static inline struct port_info *adap2pinfo(struct adapter *adap, int idx) -{ - return &adap->port[idx]; -} - void *t4_alloc_mem(size_t size); void t4_free_mem(void *addr); #define t4_os_alloc(_size) t4_alloc_mem((_size)) @@ -716,6 +697,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, const struct pkt_gl *gl); int t4_sge_init(struct adapter *adap); +int t4vf_sge_init(struct adapter *adap); int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, struct rte_eth_dev *eth_dev, uint16_t queue_id, unsigned int iqid, int socket_id); @@ -735,6 +717,7 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us, unsigned int cnt); int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts, unsigned int budget, unsigned int *work_done); -int cxgb4_write_rss(const struct port_info *pi, const u16 *queues); +int cxgbe_write_rss(const struct port_info *pi, const u16 *queues); +int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t flags); #endif /* __T4_ADAPTER_H__ */ diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h index 1eda57d0..155a3028 100644 --- a/drivers/net/cxgbe/base/common.h +++ b/drivers/net/cxgbe/base/common.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef __CHELSIO_COMMON_H @@ -36,6 +8,7 @@ #include "cxgbe_compat.h" #include "t4_hw.h" +#include "t4vf_hw.h" #include "t4_chip_type.h" #include "t4fw_interface.h" @@ -62,16 +35,16 @@ enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST }; enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR }; -enum { +enum cc_pause { PAUSE_RX = 1 << 0, PAUSE_TX = 1 << 1, PAUSE_AUTONEG = 1 << 2 }; -enum { - FEC_RS = 1 << 0, - FEC_BASER_RS = 1 << 1, - FEC_RESERVED = 1 << 2, +enum cc_fec { + FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */ + FEC_RS = 1 << 1, /* Reed-Solomon */ + FEC_BASER_RS = 1 << 2, /* BaseR/Reed-Solomon */ }; struct port_stats { @@ -209,12 +182,50 @@ struct arch_specific_params { u16 mps_tcam_size; }; +/* + * Global Receive Side Scaling (RSS) parameters in host-native format. + */ +struct rss_params { + unsigned int mode; /* RSS mode */ + union { + struct { + uint synmapen:1; /* SYN Map Enable */ + uint syn4tupenipv6:1; /* en 4-tuple IPv6 SYNs hash */ + uint syn2tupenipv6:1; /* en 2-tuple IPv6 SYNs hash */ + uint syn4tupenipv4:1; /* en 4-tuple IPv4 SYNs hash */ + uint syn2tupenipv4:1; /* en 2-tuple IPv4 SYNs hash */ + uint ofdmapen:1; /* Offload Map Enable */ + uint tnlmapen:1; /* Tunnel Map Enable */ + uint tnlalllookup:1; /* Tunnel All Lookup */ + uint hashtoeplitz:1; /* use Toeplitz hash */ + } basicvirtual; + } u; +}; + +/* + * Maximum resources provisioned for a PCI VF. + */ +struct vf_resources { + unsigned int nvi; /* N virtual interfaces */ + unsigned int neq; /* N egress Qs */ + unsigned int nethctrl; /* N egress ETH or CTRL Qs */ + unsigned int niqflint; /* N ingress Qs/w free list(s) & intr */ + unsigned int niq; /* N ingress Qs */ + unsigned int tc; /* PCI-E traffic class */ + unsigned int pmask; /* port access rights mask */ + unsigned int nexactf; /* N exact MPS filters */ + unsigned int r_caps; /* read capabilities */ + unsigned int wx_caps; /* write/execute capabilities */ +}; + struct adapter_params { struct sge_params sge; struct tp_params tp; struct vpd_params vpd; struct pci_params pci; struct devlog_params devlog; + struct rss_params rss; + struct vf_resources vfres; enum pcie_memwin drv_memwin; unsigned int sf_size; /* serial flash size in bytes */ @@ -239,19 +250,40 @@ struct adapter_params { struct arch_specific_params arch; /* chip specific params */ bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */ + u8 fw_caps_support; /* 32-bit Port Capabilities */ +}; + +/* Firmware Port Capabilities types. + */ +typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */ +typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */ + +enum fw_caps { + FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */ + FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */ + FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */ }; struct link_config { - unsigned short supported; /* link capabilities */ - unsigned short advertising; /* advertised capabilities */ - unsigned int requested_speed; /* speed user has requested */ - unsigned int speed; /* actual link speed */ - unsigned char requested_fc; /* flow control user has requested */ - unsigned char fc; /* actual link flow control */ - unsigned char requested_fec; /* Forward Error Correction user */ - unsigned char fec; /* has requested and actual FEC */ - unsigned char autoneg; /* autonegotiating? */ - unsigned char link_ok; /* link up? */ + fw_port_cap32_t pcaps; /* link capabilities */ + fw_port_cap32_t acaps; /* advertised capabilities */ + + u32 requested_speed; /* speed (Mb/s) user has requested */ + u32 speed; /* actual link speed (Mb/s) */ + + enum cc_pause requested_fc; /* flow control user has requested */ + enum cc_pause fc; /* actual link flow control */ + + enum cc_fec auto_fec; /* Forward Error Correction + * "automatic" (IEEE 802.3) + */ + enum cc_fec requested_fec; /* Forward Error Correction requested */ + enum cc_fec fec; /* Forward Error Correction actual */ + + unsigned char autoneg; /* autonegotiating? */ + + unsigned char link_ok; /* link up? */ + unsigned char link_down_rc; /* link down reason */ }; #include "adapter.h" @@ -269,6 +301,11 @@ static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask, delay, NULL); } +static inline int is_pf4(struct adapter *adap) +{ + return adap->pf == 4; +} + #define for_each_port(adapter, iter) \ for (iter = 0; iter < (adapter)->params.nports; ++iter) @@ -285,9 +322,12 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, enum dev_master master, enum dev_state *state); int t4_fw_bye(struct adapter *adap, unsigned int mbox); int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset); +int t4vf_fw_reset(struct adapter *adap); int t4_fw_halt(struct adapter *adap, unsigned int mbox, int reset); int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset); int t4_fl_pkt_align(struct adapter *adap); +int t4vf_fl_pkt_align(struct adapter *adap, u32 sge_control, u32 sge_control2); +int t4vf_get_vfres(struct adapter *adap); int t4_fixup_host_params_compat(struct adapter *adap, unsigned int page_size, unsigned int cache_line_size, enum chip_type chip_compat); @@ -297,6 +337,13 @@ int t4_fw_initialize(struct adapter *adap, unsigned int mbox); int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, u32 *val); +int t4vf_query_params(struct adapter *adap, unsigned int nparams, + const u32 *params, u32 *vals); +int t4vf_get_dev_params(struct adapter *adap); +int t4vf_get_vpd_params(struct adapter *adap); +int t4vf_get_rss_glb_config(struct adapter *adap); +int t4vf_set_params(struct adapter *adapter, unsigned int nparams, + const u32 *params, const u32 *vals); int t4_set_params_timeout(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, @@ -379,6 +426,21 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false); } +int t4vf_wr_mbox_core(struct adapter *, const void *, int, void *, bool); + +static inline int t4vf_wr_mbox(struct adapter *adapter, const void *cmd, + int size, void *rpl) +{ + return t4vf_wr_mbox_core(adapter, cmd, size, rpl, true); +} + +static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd, + int size, void *rpl) +{ + return t4vf_wr_mbox_core(adapter, cmd, size, rpl, false); +} + + void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, unsigned int data_reg, u32 *vals, unsigned int nregs, unsigned int start_idx); @@ -394,22 +456,34 @@ unsigned int t4_get_mps_bg_map(struct adapter *adapter, unsigned int pidx); unsigned int t4_get_tp_ch_map(struct adapter *adapter, unsigned int pidx); const char *t4_get_port_type_description(enum fw_port_type port_type); void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); +void t4vf_get_port_stats(struct adapter *adapter, int pidx, + struct port_stats *p); void t4_get_port_stats_offset(struct adapter *adap, int idx, struct port_stats *stats, struct port_stats *offset); void t4_clr_port_stats(struct adapter *adap, int idx); +void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps, + fw_port_cap32_t acaps); void t4_reset_link_config(struct adapter *adap, int idx); int t4_get_version_info(struct adapter *adapter); void t4_dump_version_info(struct adapter *adapter); int t4_get_flash_params(struct adapter *adapter); int t4_get_chip_type(struct adapter *adap, int ver); int t4_prep_adapter(struct adapter *adapter); +int t4vf_prep_adapter(struct adapter *adapter); int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); +int t4vf_port_init(struct adapter *adap); int t4_init_rss_mode(struct adapter *adap, int mbox); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, unsigned int flags, unsigned int defq); +int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, + u64 *flags, unsigned int *defq); +void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs, + unsigned int start_index, unsigned int rw); +void t4_write_rss_key(struct adapter *adap, u32 *key, int idx); +void t4_read_rss_key(struct adapter *adap, u32 *key); enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, @@ -421,8 +495,10 @@ int t4_init_tp_params(struct adapter *adap); int t4_filter_field_shift(const struct adapter *adap, unsigned int filter_sel); int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); unsigned int t4_get_regs_len(struct adapter *adap); +unsigned int t4vf_get_pf_from_vf(struct adapter *adap); void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size); int t4_seeprom_read(struct adapter *adapter, u32 addr, u32 *data); int t4_seeprom_write(struct adapter *adapter, u32 addr, u32 data); int t4_seeprom_wp(struct adapter *adapter, int enable); +fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16); #endif /* __CHELSIO_COMMON_H */ diff --git a/drivers/net/cxgbe/base/t4_chip_type.h b/drivers/net/cxgbe/base/t4_chip_type.h index cd7a9282..c0c5d0b2 100644 --- a/drivers/net/cxgbe/base/t4_chip_type.h +++ b/drivers/net/cxgbe/base/t4_chip_type.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef __T4_CHIP_TYPE_H__ diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c index 56f38c83..e5ef73b6 100644 --- a/drivers/net/cxgbe/base/t4_hw.c +++ b/drivers/net/cxgbe/base/t4_hw.c @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #include <netinet/in.h> @@ -55,9 +27,6 @@ #include "t4_regs_values.h" #include "t4fw_interface.h" -static void init_link_config(struct link_config *lc, unsigned int pcaps, - unsigned int acaps); - /** * t4_read_mtu_tbl - returns the values in the HW path MTU table * @adap: the adapter @@ -2167,6 +2136,91 @@ int t4_seeprom_wp(struct adapter *adapter, int enable) } /** + * t4_fw_tp_pio_rw - Access TP PIO through LDST + * @adap: the adapter + * @vals: where the indirect register values are stored/written + * @nregs: how many indirect registers to read/write + * @start_idx: index of first indirect register to read/write + * @rw: Read (1) or Write (0) + * + * Access TP PIO registers through LDST + */ +void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs, + unsigned int start_index, unsigned int rw) +{ + int cmd = FW_LDST_ADDRSPC_TP_PIO; + struct fw_ldst_cmd c; + unsigned int i; + int ret; + + for (i = 0 ; i < nregs; i++) { + memset(&c, 0, sizeof(c)); + c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | + F_FW_CMD_REQUEST | + (rw ? F_FW_CMD_READ : + F_FW_CMD_WRITE) | + V_FW_LDST_CMD_ADDRSPACE(cmd)); + c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); + + c.u.addrval.addr = cpu_to_be32(start_index + i); + c.u.addrval.val = rw ? 0 : cpu_to_be32(vals[i]); + ret = t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), &c); + if (ret == 0) { + if (rw) + vals[i] = be32_to_cpu(c.u.addrval.val); + } + } +} + +/** + * t4_read_rss_key - read the global RSS key + * @adap: the adapter + * @key: 10-entry array holding the 320-bit RSS key + * + * Reads the global 320-bit RSS key. + */ +void t4_read_rss_key(struct adapter *adap, u32 *key) +{ + t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 1); +} + +/** + * t4_write_rss_key - program one of the RSS keys + * @adap: the adapter + * @key: 10-entry array holding the 320-bit RSS key + * @idx: which RSS key to write + * + * Writes one of the RSS keys with the given 320-bit value. If @idx is + * 0..15 the corresponding entry in the RSS key table is written, + * otherwise the global RSS key is written. + */ +void t4_write_rss_key(struct adapter *adap, u32 *key, int idx) +{ + u32 vrt = t4_read_reg(adap, A_TP_RSS_CONFIG_VRT); + u8 rss_key_addr_cnt = 16; + + /* T6 and later: for KeyMode 3 (per-vf and per-vf scramble), + * allows access to key addresses 16-63 by using KeyWrAddrX + * as index[5:4](upper 2) into key table + */ + if ((CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) && + (vrt & F_KEYEXTEND) && (G_KEYMODE(vrt) == 3)) + rss_key_addr_cnt = 32; + + t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 0); + + if (idx >= 0 && idx < rss_key_addr_cnt) { + if (rss_key_addr_cnt > 16) + t4_write_reg(adap, A_TP_RSS_CONFIG_VRT, + V_KEYWRADDRX(idx >> 4) | + V_T6_VFWRADDR(idx) | F_KEYWREN); + else + t4_write_reg(adap, A_TP_RSS_CONFIG_VRT, + V_KEYWRADDR(idx) | F_KEYWREN); + } +} + +/** * t4_config_rss_range - configure a portion of the RSS mapping table * @adapter: the adapter * @mbox: mbox to use for the FW command @@ -2257,7 +2311,11 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, * Send this portion of the RRS table update to the firmware; * bail out on any errors. */ - ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL); + if (is_pf4(adapter)) + ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), + NULL); + else + ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); if (ret) return ret; } @@ -2287,7 +2345,44 @@ int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, c.retval_len16 = cpu_to_be32(FW_LEN16(c)); c.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(flags | V_FW_RSS_VI_CONFIG_CMD_DEFAULTQ(defq)); - return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); + if (is_pf4(adapter)) + return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); + else + return t4vf_wr_mbox(adapter, &c, sizeof(c), NULL); +} + +/** + * t4_read_config_vi_rss - read the configured per VI RSS settings + * @adapter: the adapter + * @mbox: mbox to use for the FW command + * @viid: the VI id + * @flags: where to place the configured flags + * @defq: where to place the id of the default RSS queue for the VI. + * + * Read configured VI-specific RSS properties. + */ +int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, + u64 *flags, unsigned int *defq) +{ + struct fw_rss_vi_config_cmd c; + unsigned int result; + int ret; + + memset(&c, 0, sizeof(c)); + c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_READ | + V_FW_RSS_VI_CONFIG_CMD_VIID(viid)); + c.retval_len16 = cpu_to_be32(FW_LEN16(c)); + ret = t4_wr_mbox(adapter, mbox, &c, sizeof(c), &c); + if (!ret) { + result = be32_to_cpu(c.u.basicvirtual.defaultq_to_udpen); + if (defq) + *defq = G_FW_RSS_VI_CONFIG_CMD_DEFAULTQ(result); + if (flags) + *flags = result & M_FW_RSS_VI_CONFIG_CMD_DEFAULTQ; + } + + return ret; } /** @@ -2670,14 +2765,142 @@ void t4_dump_version_info(struct adapter *adapter) G_FW_HDR_FW_VER_BUILD(adapter->params.er_vers)); } -#define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \ - FW_PORT_CAP_ANEG) +#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \ + FW_PORT_CAP32_ANEG) +/** + * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits + * @caps16: a 16-bit Port Capabilities value + * + * Returns the equivalent 32-bit Port Capabilities value. + */ +fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16) +{ + fw_port_cap32_t caps32 = 0; + +#define CAP16_TO_CAP32(__cap) \ + do { \ + if (caps16 & FW_PORT_CAP_##__cap) \ + caps32 |= FW_PORT_CAP32_##__cap; \ + } while (0) + + CAP16_TO_CAP32(SPEED_100M); + CAP16_TO_CAP32(SPEED_1G); + CAP16_TO_CAP32(SPEED_25G); + CAP16_TO_CAP32(SPEED_10G); + CAP16_TO_CAP32(SPEED_40G); + CAP16_TO_CAP32(SPEED_100G); + CAP16_TO_CAP32(FC_RX); + CAP16_TO_CAP32(FC_TX); + CAP16_TO_CAP32(ANEG); + CAP16_TO_CAP32(MDIX); + CAP16_TO_CAP32(MDIAUTO); + CAP16_TO_CAP32(FEC_RS); + CAP16_TO_CAP32(FEC_BASER_RS); + CAP16_TO_CAP32(802_3_PAUSE); + CAP16_TO_CAP32(802_3_ASM_DIR); + +#undef CAP16_TO_CAP32 + + return caps32; +} + +/** + * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits + * @caps32: a 32-bit Port Capabilities value + * + * Returns the equivalent 16-bit Port Capabilities value. Note that + * not all 32-bit Port Capabilities can be represented in the 16-bit + * Port Capabilities and some fields/values may not make it. + */ +static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32) +{ + fw_port_cap16_t caps16 = 0; + +#define CAP32_TO_CAP16(__cap) \ + do { \ + if (caps32 & FW_PORT_CAP32_##__cap) \ + caps16 |= FW_PORT_CAP_##__cap; \ + } while (0) + + CAP32_TO_CAP16(SPEED_100M); + CAP32_TO_CAP16(SPEED_1G); + CAP32_TO_CAP16(SPEED_10G); + CAP32_TO_CAP16(SPEED_25G); + CAP32_TO_CAP16(SPEED_40G); + CAP32_TO_CAP16(SPEED_100G); + CAP32_TO_CAP16(FC_RX); + CAP32_TO_CAP16(FC_TX); + CAP32_TO_CAP16(802_3_PAUSE); + CAP32_TO_CAP16(802_3_ASM_DIR); + CAP32_TO_CAP16(ANEG); + CAP32_TO_CAP16(MDIX); + CAP32_TO_CAP16(MDIAUTO); + CAP32_TO_CAP16(FEC_RS); + CAP32_TO_CAP16(FEC_BASER_RS); + +#undef CAP32_TO_CAP16 + + return caps16; +} + +/* Translate Firmware Pause specification to Common Code */ +static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause) +{ + enum cc_pause cc_pause = 0; + + if (fw_pause & FW_PORT_CAP32_FC_RX) + cc_pause |= PAUSE_RX; + if (fw_pause & FW_PORT_CAP32_FC_TX) + cc_pause |= PAUSE_TX; + + return cc_pause; +} + +/* Translate Common Code Pause Frame specification into Firmware */ +static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause) +{ + fw_port_cap32_t fw_pause = 0; + + if (cc_pause & PAUSE_RX) + fw_pause |= FW_PORT_CAP32_FC_RX; + if (cc_pause & PAUSE_TX) + fw_pause |= FW_PORT_CAP32_FC_TX; + + return fw_pause; +} + +/* Translate Firmware Forward Error Correction specification to Common Code */ +static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec) +{ + enum cc_fec cc_fec = 0; + + if (fw_fec & FW_PORT_CAP32_FEC_RS) + cc_fec |= FEC_RS; + if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS) + cc_fec |= FEC_BASER_RS; + + return cc_fec; +} + +/* Translate Common Code Forward Error Correction specification to Firmware */ +static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec) +{ + fw_port_cap32_t fw_fec = 0; + + if (cc_fec & FEC_RS) + fw_fec |= FW_PORT_CAP32_FEC_RS; + if (cc_fec & FEC_BASER_RS) + fw_fec |= FW_PORT_CAP32_FEC_BASER_RS; + + return fw_fec; +} /** * t4_link_l1cfg - apply link configuration to MAC/PHY - * @phy: the PHY to setup - * @mac: the MAC to setup - * @lc: the requested link configuration + * @adapter: the adapter + * @mbox: the Firmware Mailbox to use + * @port: the Port ID + * @lc: the Port's Link Configuration * * Set up a port's MAC and PHY according to a desired link configuration. * - If the PHY can auto-negotiate first decide what to advertise, then @@ -2689,48 +2912,60 @@ void t4_dump_version_info(struct adapter *adapter) int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc) { - struct fw_port_cmd c; - unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); - unsigned int fc, fec; + unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO); + unsigned int fw_caps = adap->params.fw_caps_support; + fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap; + struct fw_port_cmd cmd; lc->link_ok = 0; - fc = 0; - if (lc->requested_fc & PAUSE_RX) - fc |= FW_PORT_CAP_FC_RX; - if (lc->requested_fc & PAUSE_TX) - fc |= FW_PORT_CAP_FC_TX; - - fec = 0; - if (lc->requested_fec & FEC_RS) - fec |= FW_PORT_CAP_FEC_RS; - if (lc->requested_fec & FEC_BASER_RS) - fec |= FW_PORT_CAP_FEC_BASER_RS; - if (lc->requested_fec & FEC_RESERVED) - fec |= FW_PORT_CAP_FEC_RESERVED; - memset(&c, 0, sizeof(c)); - c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_EXEC | - V_FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = - cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | - FW_LEN16(c)); - - if (!(lc->supported & FW_PORT_CAP_ANEG)) { - c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) | - fc | fec); + fw_fc = cc_to_fwcap_pause(lc->requested_fc); + + /* Convert Common Code Forward Error Control settings into the + * Firmware's API. If the current Requested FEC has "Automatic" + * (IEEE 802.3) specified, then we use whatever the Firmware + * sent us as part of it's IEEE 802.3-based interpratation of + * the Transceiver Module EPROM FEC parameters. Otherwise we + * use whatever is in the current Requested FEC settings. + */ + if (lc->requested_fec & FEC_AUTO) + cc_fec = lc->auto_fec; + else + cc_fec = lc->requested_fec; + fw_fec = cc_to_fwcap_fec(cc_fec); + + /* Figure out what our Requested Port Capabilities are going to be. + */ + if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) { + rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec; lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; - lc->fec = lc->requested_fec; + lc->fec = cc_fec; } else if (lc->autoneg == AUTONEG_DISABLE) { - c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc | - fec | mdi); + rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi; lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; - lc->fec = lc->requested_fec; + lc->fec = cc_fec; } else { - c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | fec | mdi); + rcap = lc->acaps | fw_fc | fw_fec | fw_mdi; } - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + /* And send that on to the Firmware ... + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_EXEC | + V_FW_PORT_CMD_PORTID(port)); + cmd.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ? + FW_PORT_ACTION_L1_CFG : + FW_PORT_ACTION_L1_CFG32) | + FW_LEN16(cmd)); + + if (fw_caps == FW_CAPS16) + cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap)); + else + cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap); + + return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL); } /** @@ -3823,12 +4058,17 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) | F_FW_CMD_REQUEST | - F_FW_CMD_EXEC | V_FW_VI_CMD_PFN(pf) | - V_FW_VI_CMD_VFN(vf)); + F_FW_CMD_EXEC); + if (is_pf4(adap)) + c.op_to_vfn |= cpu_to_be32(V_FW_VI_CMD_PFN(pf) | + V_FW_VI_CMD_VFN(vf)); c.alloc_to_len16 = cpu_to_be32(F_FW_VI_CMD_FREE | FW_LEN16(c)); c.type_to_viid = cpu_to_be16(V_FW_VI_CMD_VIID(viid)); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + if (is_pf4(adap)) + return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + else + return t4vf_wr_mbox(adap, &c, sizeof(c), NULL); } /** @@ -3874,7 +4114,11 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, V_FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | V_FW_VI_RXMODE_CMD_BROADCASTEN(bcast) | V_FW_VI_RXMODE_CMD_VLANEXEN(vlanex)); - return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); + if (is_pf4(adap)) + return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, + sleep_ok); + else + return t4vf_wr_mbox(adap, &c, sizeof(c), NULL); } /** @@ -3921,7 +4165,10 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, V_FW_VI_MAC_CMD_IDX(idx)); memcpy(p->macaddr, addr, sizeof(p->macaddr)); - ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + if (is_pf4(adap)) + ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + else + ret = t4vf_wr_mbox(adap, &c, sizeof(c), &c); if (ret == 0) { ret = G_FW_VI_MAC_CMD_IDX(be16_to_cpu(p->valid_to_idx)); if (ret >= max_mac_addr) @@ -3955,7 +4202,10 @@ int t4_enable_vi_params(struct adapter *adap, unsigned int mbox, V_FW_VI_ENABLE_CMD_EEN(tx_en) | V_FW_VI_ENABLE_CMD_DCB_INFO(dcb_en) | FW_LEN16(c)); - return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); + if (is_pf4(adap)) + return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); + else + return t4vf_wr_mbox_ns(adap, &c, sizeof(c), NULL); } /** @@ -3996,15 +4246,20 @@ int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, memset(&c, 0, sizeof(c)); c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST | - F_FW_CMD_EXEC | V_FW_IQ_CMD_PFN(pf) | - V_FW_IQ_CMD_VFN(vf)); + F_FW_CMD_EXEC); c.alloc_to_len16 = cpu_to_be32(V_FW_IQ_CMD_IQSTART(start) | V_FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c)); c.iqid = cpu_to_be16(iqid); c.fl0id = cpu_to_be16(fl0id); c.fl1id = cpu_to_be16(fl1id); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + if (is_pf4(adap)) { + c.op_to_vfn |= cpu_to_be32(V_FW_IQ_CMD_PFN(pf) | + V_FW_IQ_CMD_VFN(vf)); + return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + } else { + return t4vf_wr_mbox(adap, &c, sizeof(c), NULL); + } } /** @@ -4028,14 +4283,19 @@ int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST | - F_FW_CMD_EXEC | V_FW_IQ_CMD_PFN(pf) | - V_FW_IQ_CMD_VFN(vf)); + F_FW_CMD_EXEC); + if (is_pf4(adap)) + c.op_to_vfn |= cpu_to_be32(V_FW_IQ_CMD_PFN(pf) | + V_FW_IQ_CMD_VFN(vf)); c.alloc_to_len16 = cpu_to_be32(F_FW_IQ_CMD_FREE | FW_LEN16(c)); c.type_to_iqandstindex = cpu_to_be32(V_FW_IQ_CMD_TYPE(iqtype)); c.iqid = cpu_to_be16(iqid); c.fl0id = cpu_to_be16(fl0id); c.fl1id = cpu_to_be16(fl1id); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + if (is_pf4(adap)) + return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + else + return t4vf_wr_mbox(adap, &c, sizeof(c), NULL); } /** @@ -4055,12 +4315,179 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_EQ_ETH_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_EXEC | - V_FW_EQ_ETH_CMD_PFN(pf) | - V_FW_EQ_ETH_CMD_VFN(vf)); + F_FW_CMD_REQUEST | F_FW_CMD_EXEC); + if (is_pf4(adap)) + c.op_to_vfn |= cpu_to_be32(V_FW_IQ_CMD_PFN(pf) | + V_FW_IQ_CMD_VFN(vf)); c.alloc_to_len16 = cpu_to_be32(F_FW_EQ_ETH_CMD_FREE | FW_LEN16(c)); c.eqid_pkd = cpu_to_be32(V_FW_EQ_ETH_CMD_EQID(eqid)); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + if (is_pf4(adap)) + return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); + else + return t4vf_wr_mbox(adap, &c, sizeof(c), NULL); +} + +/** + * t4_link_down_rc_str - return a string for a Link Down Reason Code + * @link_down_rc: Link Down Reason Code + * + * Returns a string representation of the Link Down Reason Code. + */ +static const char *t4_link_down_rc_str(unsigned char link_down_rc) +{ + static const char * const reason[] = { + "Link Down", + "Remote Fault", + "Auto-negotiation Failure", + "Reserved", + "Insufficient Airflow", + "Unable To Determine Reason", + "No RX Signal Detected", + "Reserved", + }; + + if (link_down_rc >= ARRAY_SIZE(reason)) + return "Bad Reason Code"; + + return reason[link_down_rc]; +} + +/* Return the highest speed set in the port capabilities, in Mb/s. */ +static unsigned int fwcap_to_speed(fw_port_cap32_t caps) +{ +#define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return __speed; \ + } while (0) + + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + +#undef TEST_SPEED_RETURN + + return 0; +} + +/** + * t4_handle_get_port_info - process a FW reply message + * @pi: the port info + * @rpl: start of the FW message + * + * Processes a GET_PORT_INFO FW reply message. + */ +static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) +{ + const struct fw_port_cmd *cmd = (const void *)rpl; + int action = G_FW_PORT_CMD_ACTION(be32_to_cpu(cmd->action_to_len16)); + fw_port_cap32_t pcaps, acaps, linkattr; + struct link_config *lc = &pi->link_cfg; + struct adapter *adapter = pi->adapter; + enum fw_port_module_type mod_type; + enum fw_port_type port_type; + unsigned int speed, fc, fec; + int link_ok, linkdnrc; + + /* Extract the various fields from the Port Information message. + */ + switch (action) { + case FW_PORT_ACTION_GET_PORT_INFO: { + u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); + + link_ok = (lstatus & F_FW_PORT_CMD_LSTATUS) != 0; + linkdnrc = G_FW_PORT_CMD_LINKDNRC(lstatus); + port_type = G_FW_PORT_CMD_PTYPE(lstatus); + mod_type = G_FW_PORT_CMD_MODTYPE(lstatus); + pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap)); + acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap)); + + /* Unfortunately the format of the Link Status in the old + * 16-bit Port Information message isn't the same as the + * 16-bit Port Capabilities bitfield used everywhere else ... + */ + linkattr = 0; + if (lstatus & F_FW_PORT_CMD_RXPAUSE) + linkattr |= FW_PORT_CAP32_FC_RX; + if (lstatus & F_FW_PORT_CMD_TXPAUSE) + linkattr |= FW_PORT_CAP32_FC_TX; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + linkattr |= FW_PORT_CAP32_SPEED_100M; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + linkattr |= FW_PORT_CAP32_SPEED_1G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + linkattr |= FW_PORT_CAP32_SPEED_10G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) + linkattr |= FW_PORT_CAP32_SPEED_25G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + linkattr |= FW_PORT_CAP32_SPEED_40G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) + linkattr |= FW_PORT_CAP32_SPEED_100G; + + break; + } + + case FW_PORT_ACTION_GET_PORT_INFO32: { + u32 lstatus32 = + be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32); + + link_ok = (lstatus32 & F_FW_PORT_CMD_LSTATUS32) != 0; + linkdnrc = G_FW_PORT_CMD_LINKDNRC32(lstatus32); + port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32); + mod_type = G_FW_PORT_CMD_MODTYPE32(lstatus32); + pcaps = be32_to_cpu(cmd->u.info32.pcaps32); + acaps = be32_to_cpu(cmd->u.info32.acaps32); + linkattr = be32_to_cpu(cmd->u.info32.linkattr32); + break; + } + + default: + dev_warn(adapter, "Handle Port Information: Bad Command/Action %#x\n", + be32_to_cpu(cmd->action_to_len16)); + return; + } + + fec = fwcap_to_cc_fec(acaps); + + fc = fwcap_to_cc_pause(linkattr); + speed = fwcap_to_speed(linkattr); + + if (mod_type != pi->mod_type) { + lc->auto_fec = fec; + pi->port_type = port_type; + pi->mod_type = mod_type; + t4_os_portmod_changed(adapter, pi->pidx); + } + if (link_ok != lc->link_ok || speed != lc->speed || + fc != lc->fc || fec != lc->fec) { /* something changed */ + if (!link_ok && lc->link_ok) { + lc->link_down_rc = linkdnrc; + dev_warn(adap, "Port %d link down, reason: %s\n", + pi->tx_chan, t4_link_down_rc_str(linkdnrc)); + } + lc->link_ok = link_ok; + lc->speed = speed; + lc->fc = fc; + lc->fec = fec; + lc->pcaps = pcaps; + lc->acaps = acaps & ADVERT_MASK; + + if (lc->acaps & FW_PORT_CAP32_ANEG) { + lc->autoneg = AUTONEG_ENABLE; + } else { + /* When Autoneg is disabled, user needs to set + * single speed. + * Similar to cxgb4_ethtool.c: set_link_ksettings + */ + lc->acaps = 0; + lc->requested_speed = fwcap_to_speed(acaps); + lc->autoneg = AUTONEG_DISABLE; + } + } } /** @@ -4084,67 +4511,21 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) unsigned int action = G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); - if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { + if (opcode == FW_PORT_CMD && + (action == FW_PORT_ACTION_GET_PORT_INFO || + action == FW_PORT_ACTION_GET_PORT_INFO32)) { /* link/module state change message */ - unsigned int speed = 0, fc = 0, i; int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid)); struct port_info *pi = NULL; - struct link_config *lc; - u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype); - int link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; - u32 mod = G_FW_PORT_CMD_MODTYPE(stat); - - if (stat & F_FW_PORT_CMD_RXPAUSE) - fc |= PAUSE_RX; - if (stat & F_FW_PORT_CMD_TXPAUSE) - fc |= PAUSE_TX; - if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = ETH_SPEED_NUM_100M; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = ETH_SPEED_NUM_1G; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = ETH_SPEED_NUM_10G; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) - speed = ETH_SPEED_NUM_25G; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) - speed = ETH_SPEED_NUM_40G; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) - speed = ETH_SPEED_NUM_100G; + int i; for_each_port(adap, i) { pi = adap2pinfo(adap, i); if (pi->tx_chan == chan) break; } - lc = &pi->link_cfg; - if (mod != pi->mod_type) { - pi->mod_type = mod; - t4_os_portmod_changed(adap, i); - } - if (link_ok != lc->link_ok || speed != lc->speed || - fc != lc->fc) { /* something changed */ - if (!link_ok && lc->link_ok) { - static const char * const reason[] = { - "Link Down", - "Remote Fault", - "Auto-negotiation Failure", - "Reserved", - "Insufficient Airflow", - "Unable To Determine Reason", - "No RX Signal Detected", - "Reserved", - }; - unsigned int rc = G_FW_PORT_CMD_LINKDNRC(stat); - - dev_warn(adap, "Port %d link down, reason: %s\n", - chan, reason[rc]); - } - lc->link_ok = link_ok; - lc->speed = speed; - lc->fc = fc; - lc->supported = be16_to_cpu(p->u.info.pcap); - } + t4_handle_get_port_info(pi, rpl); } else { dev_warn(adap, "Unknown firmware reply %d\n", opcode); return -EINVAL; @@ -4173,12 +4554,10 @@ void t4_reset_link_config(struct adapter *adap, int idx) * Initializes the SW state maintained for each link, including the link's * capabilities and default speed/flow-control/autonegotiation settings. */ -static void init_link_config(struct link_config *lc, unsigned int pcaps, - unsigned int acaps) +void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps, + fw_port_cap32_t acaps) { - unsigned int fec; - - lc->supported = pcaps; + lc->pcaps = pcaps; lc->requested_speed = 0; lc->speed = 0; lc->requested_fc = 0; @@ -4188,21 +4567,16 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps, * For Forward Error Control, we default to whatever the Firmware * tells us the Link is currently advertising. */ - fec = 0; - if (acaps & FW_PORT_CAP_FEC_RS) - fec |= FEC_RS; - if (acaps & FW_PORT_CAP_FEC_BASER_RS) - fec |= FEC_BASER_RS; - if (acaps & FW_PORT_CAP_FEC_RESERVED) - fec |= FEC_RESERVED; - lc->requested_fec = fec; - lc->fec = fec; - - if (lc->supported & FW_PORT_CAP_ANEG) { - lc->advertising = lc->supported & ADVERT_MASK; + lc->auto_fec = fwcap_to_cc_fec(acaps); + lc->requested_fec = FEC_AUTO; + lc->fec = lc->auto_fec; + + if (lc->pcaps & FW_PORT_CAP32_ANEG) { + lc->acaps = lc->pcaps & ADVERT_MASK; lc->autoneg = AUTONEG_ENABLE; + lc->requested_fc |= PAUSE_AUTONEG; } else { - lc->advertising = 0; + lc->acaps = 0; lc->autoneg = AUTONEG_DISABLE; } } @@ -4723,46 +5097,95 @@ int t4_init_rss_mode(struct adapter *adap, int mbox) int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) { - u8 addr[6]; + unsigned int fw_caps = adap->params.fw_caps_support; + fw_port_cap32_t pcaps, acaps; + enum fw_port_type port_type; + struct fw_port_cmd cmd; int ret, i, j = 0; - struct fw_port_cmd c; + int mdio_addr; + u32 action; + u8 addr[6]; - memset(&c, 0, sizeof(c)); + memset(&cmd, 0, sizeof(cmd)); for_each_port(adap, i) { + struct port_info *pi = adap2pinfo(adap, i); unsigned int rss_size = 0; - struct port_info *p = adap2pinfo(adap, i); while ((adap->params.portvec & (1 << j)) == 0) j++; - c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_READ | - V_FW_PORT_CMD_PORTID(j)); - c.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION( - FW_PORT_ACTION_GET_PORT_INFO) | - FW_LEN16(c)); - ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + /* If we haven't yet determined whether we're talking to + * Firmware which knows the new 32-bit Port Capabilities, it's + * time to find out now. This will also tell new Firmware to + * send us Port Status Updates using the new 32-bit Port + * Capabilities version of the Port Information message. + */ + if (fw_caps == FW_CAPS_UNKNOWN) { + u32 param, val, caps; + + caps = FW_PARAMS_PARAM_PFVF_PORT_CAPS32; + param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | + V_FW_PARAMS_PARAM_X(caps)); + val = 1; + ret = t4_set_params(adap, mbox, pf, vf, 1, ¶m, + &val); + fw_caps = ret == 0 ? FW_CAPS32 : FW_CAPS16; + adap->params.fw_caps_support = fw_caps; + } + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ | + V_FW_PORT_CMD_PORTID(j)); + action = fw_caps == FW_CAPS16 ? FW_PORT_ACTION_GET_PORT_INFO : + FW_PORT_ACTION_GET_PORT_INFO32; + cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) | + FW_LEN16(cmd)); + ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd); if (ret) return ret; + /* Extract the various fields from the Port Information message. + */ + if (fw_caps == FW_CAPS16) { + u32 lstatus = + be32_to_cpu(cmd.u.info.lstatus_to_modtype); + + port_type = G_FW_PORT_CMD_PTYPE(lstatus); + mdio_addr = (lstatus & F_FW_PORT_CMD_MDIOCAP) ? + (int)G_FW_PORT_CMD_MDIOADDR(lstatus) : -1; + pcaps = be16_to_cpu(cmd.u.info.pcap); + acaps = be16_to_cpu(cmd.u.info.acap); + pcaps = fwcaps16_to_caps32(pcaps); + acaps = fwcaps16_to_caps32(acaps); + } else { + u32 lstatus32 = + be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32); + + port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32); + mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ? + (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) : + -1; + pcaps = be32_to_cpu(cmd.u.info32.pcaps32); + acaps = be32_to_cpu(cmd.u.info32.acaps32); + } + ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size); if (ret < 0) return ret; - p->viid = ret; - p->tx_chan = j; - p->rss_size = rss_size; + pi->viid = ret; + pi->tx_chan = j; + pi->rss_size = rss_size; t4_os_set_hw_addr(adap, i, addr); - ret = be32_to_cpu(c.u.info.lstatus_to_modtype); - p->mdio_addr = (ret & F_FW_PORT_CMD_MDIOCAP) ? - G_FW_PORT_CMD_MDIOADDR(ret) : -1; - p->port_type = G_FW_PORT_CMD_PTYPE(ret); - p->mod_type = FW_PORT_MOD_TYPE_NA; + pi->port_type = port_type; + pi->mdio_addr = mdio_addr; + pi->mod_type = FW_PORT_MOD_TYPE_NA; - init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap), - be16_to_cpu(c.u.info.acap)); + init_link_config(&pi->link_cfg, pcaps, acaps); j++; } return 0; diff --git a/drivers/net/cxgbe/base/t4_hw.h b/drivers/net/cxgbe/base/t4_hw.h index 07498841..ac12afc0 100644 --- a/drivers/net/cxgbe/base/t4_hw.h +++ b/drivers/net/cxgbe/base/t4_hw.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef __T4_HW_H diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h index 6acd749a..74b4fc19 100644 --- a/drivers/net/cxgbe/base/t4_msg.h +++ b/drivers/net/cxgbe/base/t4_msg.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef T4_MSG_H diff --git a/drivers/net/cxgbe/base/t4_pci_id_tbl.h b/drivers/net/cxgbe/base/t4_pci_id_tbl.h index 1230e738..5f5cbe04 100644 --- a/drivers/net/cxgbe/base/t4_pci_id_tbl.h +++ b/drivers/net/cxgbe/base/t4_pci_id_tbl.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef __T4_PCI_ID_TBL_H__ diff --git a/drivers/net/cxgbe/base/t4_regs.h b/drivers/net/cxgbe/base/t4_regs.h index 1100e16f..c0d6ddca 100644 --- a/drivers/net/cxgbe/base/t4_regs.h +++ b/drivers/net/cxgbe/base/t4_regs.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #define MYPF_BASE 0x1b000 @@ -77,6 +49,7 @@ #define SGE_BASE_ADDR 0x1000 #define A_SGE_PF_KDOORBELL 0x0 +#define A_SGE_VF_KDOORBELL 0x0 #define S_QID 15 #define M_QID 0x1ffffU @@ -103,6 +76,9 @@ #define A_SGE_PF_GTS 0x4 +#define T4VF_SGE_BASE_ADDR 0x0000 +#define A_SGE_VF_GTS 0x4 + #define S_INGRESSQID 16 #define M_INGRESSQID 0xffffU #define V_INGRESSQID(x) ((x) << S_INGRESSQID) @@ -191,6 +167,8 @@ #define V_QUEUESPERPAGEPF0(x) ((x) << S_QUEUESPERPAGEPF0) #define G_QUEUESPERPAGEPF0(x) (((x) >> S_QUEUESPERPAGEPF0) & M_QUEUESPERPAGEPF0) +#define A_SGE_EGRESS_QUEUES_PER_PAGE_VF 0x1014 + #define S_ERR_CPL_EXCEED_IQE_SIZE 22 #define V_ERR_CPL_EXCEED_IQE_SIZE(x) ((x) << S_ERR_CPL_EXCEED_IQE_SIZE) #define F_ERR_CPL_EXCEED_IQE_SIZE V_ERR_CPL_EXCEED_IQE_SIZE(1U) @@ -280,6 +258,11 @@ #define A_SGE_CONM_CTRL 0x1094 +#define S_T6_EGRTHRESHOLDPACKING 16 +#define M_T6_EGRTHRESHOLDPACKING 0xffU +#define G_T6_EGRTHRESHOLDPACKING(x) (((x) >> S_T6_EGRTHRESHOLDPACKING) & \ + M_T6_EGRTHRESHOLDPACKING) + #define S_EGRTHRESHOLD 8 #define M_EGRTHRESHOLD 0x3fU #define V_EGRTHRESHOLD(x) ((x) << S_EGRTHRESHOLD) @@ -370,6 +353,7 @@ #define G_STATSOURCE_T5(x) (((x) >> S_STATSOURCE_T5) & M_STATSOURCE_T5) #define A_SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4 +#define A_SGE_INGRESS_QUEUES_PER_PAGE_VF 0x10f8 #define A_SGE_CONTROL2 0x1124 @@ -443,6 +427,8 @@ /* registers for module CIM */ #define CIM_BASE_ADDR 0x7b00 +#define A_CIM_VF_EXT_MAILBOX_CTRL 0x0 + #define A_CIM_PF_MAILBOX_DATA 0x240 #define A_CIM_PF_MAILBOX_CTRL 0x280 @@ -462,6 +448,8 @@ #define V_UPCRST(x) ((x) << S_UPCRST) #define F_UPCRST V_UPCRST(1U) +#define NUM_CIM_PF_MAILBOX_DATA_INSTANCES 16 + /* registers for module TP */ #define A_TP_OUT_CONFIG 0x7d04 @@ -503,9 +491,34 @@ #define V_MTUVALUE(x) ((x) << S_MTUVALUE) #define G_MTUVALUE(x) (((x) >> S_MTUVALUE) & M_MTUVALUE) +#define A_TP_RSS_CONFIG_VRT 0x7e00 + +#define S_KEYMODE 6 +#define M_KEYMODE 0x3U +#define G_KEYMODE(x) (((x) >> S_KEYMODE) & M_KEYMODE) + +#define S_KEYWRADDR 0 +#define V_KEYWRADDR(x) ((x) << S_KEYWRADDR) + +#define S_KEYWREN 4 +#define V_KEYWREN(x) ((x) << S_KEYWREN) +#define F_KEYWREN V_KEYWREN(1U) + +#define S_KEYWRADDRX 30 +#define V_KEYWRADDRX(x) ((x) << S_KEYWRADDRX) + +#define S_KEYEXTEND 26 +#define V_KEYEXTEND(x) ((x) << S_KEYEXTEND) +#define F_KEYEXTEND V_KEYEXTEND(1U) + +#define S_T6_VFWRADDR 8 +#define V_T6_VFWRADDR(x) ((x) << S_T6_VFWRADDR) + #define A_TP_PIO_ADDR 0x7e40 #define A_TP_PIO_DATA 0x7e44 +#define A_TP_RSS_SECRET_KEY0 0x40 + #define A_TP_VLAN_PRI_MAP 0x140 #define S_FRAGMENTATION 9 @@ -558,8 +571,12 @@ #define V_CSUM_HAS_PSEUDO_HDR(x) ((x) << S_CSUM_HAS_PSEUDO_HDR) #define F_CSUM_HAS_PSEUDO_HDR V_CSUM_HAS_PSEUDO_HDR(1U) +#define S_RM_OVLAN 9 +#define V_RM_OVLAN(x) ((x) << S_RM_OVLAN) + /* registers for module MPS */ #define MPS_BASE_ADDR 0x9000 +#define T4VF_MPS_BASE_ADDR 0x0100 #define S_REPLICATE 11 #define V_REPLICATE(x) ((x) << S_REPLICATE) @@ -766,6 +783,66 @@ #define A_MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_L 0x96b8 #define A_MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_H 0x96bc +#define A_MPS_VF_STAT_TX_VF_BCAST_FRAMES_L 0x88 +#define A_MPS_VF_STAT_TX_VF_MCAST_FRAMES_L 0x98 +#define A_MPS_VF_STAT_TX_VF_UCAST_FRAMES_L 0xa8 +#define A_MPS_VF_STAT_TX_VF_DROP_FRAMES_L 0xb0 +#define A_MPS_VF_STAT_RX_VF_BCAST_FRAMES_L 0xd0 +#define A_MPS_VF_STAT_RX_VF_MCAST_FRAMES_L 0xe0 +#define A_MPS_VF_STAT_RX_VF_UCAST_FRAMES_L 0xf0 +#define A_MPS_VF_STAT_RX_VF_ERR_FRAMES_L 0xf8 + +#define A_MPS_PORT0_RX_IVLAN 0x3011c + +#define S_IVLAN_ETYPE 0 +#define M_IVLAN_ETYPE 0xffffU +#define V_IVLAN_ETYPE(x) ((x) << S_IVLAN_ETYPE) + +#define MPS_PORT_RX_IVLAN_STRIDE 0x4000 +#define MPS_PORT_RX_IVLAN(idx) \ + (A_MPS_PORT0_RX_IVLAN + (idx) * MPS_PORT_RX_IVLAN_STRIDE) + +#define A_MPS_PORT0_RX_OVLAN0 0x30120 + +#define S_OVLAN_MASK 16 +#define M_OVLAN_MASK 0xffffU +#define V_OVLAN_MASK(x) ((x) << S_OVLAN_MASK) + +#define S_OVLAN_ETYPE 0 +#define M_OVLAN_ETYPE 0xffffU +#define V_OVLAN_ETYPE(x) ((x) << S_OVLAN_ETYPE) + +#define MPS_PORT_RX_OVLAN_STRIDE 0x4000 +#define MPS_PORT_RX_OVLAN_BASE(idx) \ +(A_MPS_PORT0_RX_OVLAN0 + (idx) * MPS_PORT_RX_OVLAN_STRIDE) +#define MPS_PORT_RX_OVLAN_REG(idx, reg) (MPS_PORT_RX_OVLAN_BASE(idx) + (reg)) + +#define A_RX_OVLAN0 0x0 +#define A_RX_OVLAN1 0x4 +#define A_RX_OVLAN2 0x8 + +#define A_MPS_PORT0_RX_CTL 0x30100 + +#define S_OVLAN_EN0 0 +#define V_OVLAN_EN0(x) ((x) << S_OVLAN_EN0) +#define F_OVLAN_EN0 V_OVLAN_EN0(1) + +#define S_OVLAN_EN1 1 +#define V_OVLAN_EN1(x) ((x) << S_OVLAN_EN1) +#define F_OVLAN_EN1 V_OVLAN_EN1(1) + +#define S_OVLAN_EN2 2 +#define V_OVLAN_EN2(x) ((x) << S_OVLAN_EN2) +#define F_OVLAN_EN2 V_OVLAN_EN2(1) + +#define S_IVLAN_EN 4 +#define V_IVLAN_EN(x) ((x) << S_IVLAN_EN) +#define F_IVLAN_EN V_IVLAN_EN(1) + +#define MPS_PORT_RX_CTL_STRIDE 0x4000 +#define MPS_PORT_RX_CTL(idx) \ + (A_MPS_PORT0_RX_CTL + (idx) * MPS_PORT_RX_CTL_STRIDE) + /* registers for module ULP_RX */ #define ULP_RX_BASE_ADDR 0x19150 @@ -823,6 +900,7 @@ #define F_PFCIM V_PFCIM(1U) #define A_PL_WHOAMI 0x19400 +#define A_PL_VF_WHOAMI 0x0 #define A_PL_RST 0x19428 @@ -837,6 +915,7 @@ #define F_PIORSTMODE V_PIORSTMODE(1U) #define A_PL_REV 0x1943c +#define A_PL_VF_REV 0x4 #define S_REV 0 #define M_REV 0xfU diff --git a/drivers/net/cxgbe/base/t4_regs_values.h b/drivers/net/cxgbe/base/t4_regs_values.h index 9085ff6d..a9414d20 100644 --- a/drivers/net/cxgbe/base/t4_regs_values.h +++ b/drivers/net/cxgbe/base/t4_regs_values.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef __T4_REGS_VALUES_H__ diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h index 6ca4f318..852e8f3c 100644 --- a/drivers/net/cxgbe/base/t4fw_interface.h +++ b/drivers/net/cxgbe/base/t4fw_interface.h @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2014-2017 Chelsio Communications. - * All rights reserved. - * - * 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 Chelsio Communications 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Chelsio Communications. + * All rights reserved. */ #ifndef _T4FW_INTERFACE_H_ @@ -84,6 +56,8 @@ enum fw_memtype { enum fw_wr_opcodes { FW_ETH_TX_PKT_WR = 0x08, FW_ETH_TX_PKTS_WR = 0x09, + FW_ETH_TX_PKT_VM_WR = 0x11, + FW_ETH_TX_PKTS_VM_WR = 0x12, FW_ETH_TX_PKTS2_WR = 0x78, }; @@ -146,6 +120,29 @@ struct fw_eth_tx_pkts_wr { __u8 type; }; +struct fw_eth_tx_pkt_vm_wr { + __be32 op_immdlen; + __be32 equiq_to_len16; + __be32 r3[2]; + __u8 ethmacdst[6]; + __u8 ethmacsrc[6]; + __be16 ethtype; + __be16 vlantci; +}; + +struct fw_eth_tx_pkts_vm_wr { + __be32 op_pkd; + __be32 equiq_to_len16; + __be32 r3; + __be16 plen; + __u8 npkt; + __u8 r4; + __u8 ethmacdst[6]; + __u8 ethmacsrc[6]; + __be16 ethtype; + __be16 vlantci; +}; + /****************************************************************************** * C O M M A N D s *********************/ @@ -171,24 +168,32 @@ struct fw_eth_tx_pkts_wr { #define FW_CMD_HELLO_RETRIES 3 enum fw_cmd_opcodes { + FW_LDST_CMD = 0x01, FW_RESET_CMD = 0x03, FW_HELLO_CMD = 0x04, FW_BYE_CMD = 0x05, FW_INITIALIZE_CMD = 0x06, FW_CAPS_CONFIG_CMD = 0x07, FW_PARAMS_CMD = 0x08, + FW_PFVF_CMD = 0x09, FW_IQ_CMD = 0x10, FW_EQ_ETH_CMD = 0x12, FW_VI_CMD = 0x14, FW_VI_MAC_CMD = 0x15, FW_VI_RXMODE_CMD = 0x16, FW_VI_ENABLE_CMD = 0x17, + FW_VI_STATS_CMD = 0x1a, FW_PORT_CMD = 0x1b, FW_RSS_IND_TBL_CMD = 0x20, + FW_RSS_GLB_CONFIG_CMD = 0x22, FW_RSS_VI_CONFIG_CMD = 0x23, FW_DEBUG_CMD = 0x81, }; +enum fw_cmd_cap { + FW_CMD_CAP_PORT = 0x04, +}; + /* * Generic command header flit0 */ @@ -238,6 +243,94 @@ struct fw_cmd_hdr { #define FW_LEN16(fw_struct) V_FW_CMD_LEN16(sizeof(fw_struct) / 16) +/* address spaces + */ +enum fw_ldst_addrspc { + FW_LDST_ADDRSPC_TP_PIO = 0x0010, +}; + +struct fw_ldst_cmd { + __be32 op_to_addrspace; + __be32 cycles_to_len16; + union fw_ldst { + struct fw_ldst_addrval { + __be32 addr; + __be32 val; + } addrval; + struct fw_ldst_idctxt { + __be32 physid; + __be32 msg_ctxtflush; + __be32 ctxt_data7; + __be32 ctxt_data6; + __be32 ctxt_data5; + __be32 ctxt_data4; + __be32 ctxt_data3; + __be32 ctxt_data2; + __be32 ctxt_data1; + __be32 ctxt_data0; + } idctxt; + struct fw_ldst_mdio { + __be16 paddr_mmd; + __be16 raddr; + __be16 vctl; + __be16 rval; + } mdio; + struct fw_ldst_mps { + __be16 fid_ctl; + __be16 rplcpf_pkd; + __be32 rplc127_96; + __be32 rplc95_64; + __be32 rplc63_32; + __be32 rplc31_0; + __be32 atrb; + __be16 vlan[16]; + } mps; + struct fw_ldst_func { + __u8 access_ctl; + __u8 mod_index; + __be16 ctl_id; + __be32 offset; + __be64 data0; + __be64 data1; + } func; + struct fw_ldst_pcie { + __u8 ctrl_to_fn; + __u8 bnum; + __u8 r; + __u8 ext_r; + __u8 select_naccess; + __u8 pcie_fn; + __be16 nset_pkd; + __be32 data[12]; + } pcie; + struct fw_ldst_i2c_deprecated { + __u8 pid_pkd; + __u8 base; + __u8 boffset; + __u8 data; + __be32 r9; + } i2c_deprecated; + struct fw_ldst_i2c { + __u8 pid; + __u8 did; + __u8 boffset; + __u8 blen; + __be32 r9; + __u8 data[48]; + } i2c; + struct fw_ldst_le { + __be32 index; + __be32 r9; + __u8 val[33]; + __u8 r11[7]; + } le; + } u; +}; + +#define S_FW_LDST_CMD_ADDRSPACE 0 +#define M_FW_LDST_CMD_ADDRSPACE 0xff +#define V_FW_LDST_CMD_ADDRSPACE(x) ((x) << S_FW_LDST_CMD_ADDRSPACE) + struct fw_reset_cmd { __be32 op_to_write; __be32 retval_len16; @@ -386,6 +479,7 @@ struct fw_caps_config_cmd { enum fw_params_mnem { FW_PARAMS_MNEM_DEV = 1, /* device params */ FW_PARAMS_MNEM_PFVF = 2, /* function params */ + FW_PARAMS_MNEM_REG = 3, /* limited register access */ FW_PARAMS_MNEM_DMAQ = 4, /* dma queue params */ }; @@ -395,6 +489,8 @@ enum fw_params_mnem { enum fw_params_param_dev { FW_PARAMS_PARAM_DEV_CCLK = 0x00, /* chip core clock in khz */ FW_PARAMS_PARAM_DEV_PORTVEC = 0x01, /* the port vector */ + FW_PARAMS_PARAM_DEV_FWREV = 0x0B, /* fw version */ + FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */ FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17, }; @@ -402,7 +498,8 @@ enum fw_params_param_dev { * physical and virtual function parameters */ enum fw_params_param_pfvf { - FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31 + FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31, + FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A }; /* @@ -443,6 +540,10 @@ enum fw_params_param_dmaq { #define G_FW_PARAMS_PARAM_YZ(x) \ (((x) >> S_FW_PARAMS_PARAM_YZ) & M_FW_PARAMS_PARAM_YZ) +#define S_FW_PARAMS_PARAM_XYZ 0 +#define M_FW_PARAMS_PARAM_XYZ 0xffffff +#define V_FW_PARAMS_PARAM_XYZ(x) ((x) << S_FW_PARAMS_PARAM_XYZ) + struct fw_params_cmd { __be32 op_to_vfn; __be32 retval_len16; @@ -464,6 +565,68 @@ struct fw_params_cmd { #define G_FW_PARAMS_CMD_VFN(x) \ (((x) >> S_FW_PARAMS_CMD_VFN) & M_FW_PARAMS_CMD_VFN) +struct fw_pfvf_cmd { + __be32 op_to_vfn; + __be32 retval_len16; + __be32 niqflint_niq; + __be32 type_to_neq; + __be32 tc_to_nexactf; + __be32 r_caps_to_nethctrl; + __be16 nricq; + __be16 nriqp; + __be32 r4; +}; + +#define S_FW_PFVF_CMD_NIQFLINT 20 +#define M_FW_PFVF_CMD_NIQFLINT 0xfff +#define G_FW_PFVF_CMD_NIQFLINT(x) \ + (((x) >> S_FW_PFVF_CMD_NIQFLINT) & M_FW_PFVF_CMD_NIQFLINT) + +#define S_FW_PFVF_CMD_NIQ 0 +#define M_FW_PFVF_CMD_NIQ 0xfffff +#define G_FW_PFVF_CMD_NIQ(x) \ + (((x) >> S_FW_PFVF_CMD_NIQ) & M_FW_PFVF_CMD_NIQ) + +#define S_FW_PFVF_CMD_PMASK 20 +#define M_FW_PFVF_CMD_PMASK 0xf +#define G_FW_PFVF_CMD_PMASK(x) \ + (((x) >> S_FW_PFVF_CMD_PMASK) & M_FW_PFVF_CMD_PMASK) + +#define S_FW_PFVF_CMD_NEQ 0 +#define M_FW_PFVF_CMD_NEQ 0xfffff +#define G_FW_PFVF_CMD_NEQ(x) \ + (((x) >> S_FW_PFVF_CMD_NEQ) & M_FW_PFVF_CMD_NEQ) + +#define S_FW_PFVF_CMD_TC 24 +#define M_FW_PFVF_CMD_TC 0xff +#define G_FW_PFVF_CMD_TC(x) \ + (((x) >> S_FW_PFVF_CMD_TC) & M_FW_PFVF_CMD_TC) + +#define S_FW_PFVF_CMD_NVI 16 +#define M_FW_PFVF_CMD_NVI 0xff +#define G_FW_PFVF_CMD_NVI(x) \ + (((x) >> S_FW_PFVF_CMD_NVI) & M_FW_PFVF_CMD_NVI) + +#define S_FW_PFVF_CMD_NEXACTF 0 +#define M_FW_PFVF_CMD_NEXACTF 0xffff +#define G_FW_PFVF_CMD_NEXACTF(x) \ + (((x) >> S_FW_PFVF_CMD_NEXACTF) & M_FW_PFVF_CMD_NEXACTF) + +#define S_FW_PFVF_CMD_R_CAPS 24 +#define M_FW_PFVF_CMD_R_CAPS 0xff +#define G_FW_PFVF_CMD_R_CAPS(x) \ + (((x) >> S_FW_PFVF_CMD_R_CAPS) & M_FW_PFVF_CMD_R_CAPS) + +#define S_FW_PFVF_CMD_WX_CAPS 16 +#define M_FW_PFVF_CMD_WX_CAPS 0xff +#define G_FW_PFVF_CMD_WX_CAPS(x) \ + (((x) >> S_FW_PFVF_CMD_WX_CAPS) & M_FW_PFVF_CMD_WX_CAPS) + +#define S_FW_PFVF_CMD_NETHCTRL 0 +#define M_FW_PFVF_CMD_NETHCTRL 0xffff +#define G_FW_PFVF_CMD_NETHCTRL(x) \ + (((x) >> S_FW_PFVF_CMD_NETHCTRL) & M_FW_PFVF_CMD_NETHCTRL) + /* * ingress queue type; the first 1K ingress queues can have associated 0, * 1 or 2 free lists and an interrupt, all other ingress queues lack these @@ -724,6 +887,11 @@ struct fw_eq_eth_cmd { #define G_FW_EQ_ETH_CMD_EQID(x) \ (((x) >> S_FW_EQ_ETH_CMD_EQID) & M_FW_EQ_ETH_CMD_EQID) +#define S_FW_EQ_ETH_CMD_PHYSEQID 0 +#define M_FW_EQ_ETH_CMD_PHYSEQID 0xfffff +#define G_FW_EQ_ETH_CMD_PHYSEQID(x) \ + (((x) >> S_FW_EQ_ETH_CMD_PHYSEQID) & M_FW_EQ_ETH_CMD_PHYSEQID) + #define S_FW_EQ_ETH_CMD_FETCHRO 22 #define M_FW_EQ_ETH_CMD_FETCHRO 0x1 #define V_FW_EQ_ETH_CMD_FETCHRO(x) ((x) << S_FW_EQ_ETH_CMD_FETCHRO) @@ -988,6 +1156,9 @@ struct fw_vi_enable_cmd { (((x) >> S_FW_VI_ENABLE_CMD_DCB_INFO) & M_FW_VI_ENABLE_CMD_DCB_INFO) #define F_FW_VI_ENABLE_CMD_DCB_INFO V_FW_VI_ENABLE_CMD_DCB_INFO(1U) +/* VI VF stats offset definitions */ +#define VI_VF_NUM_STATS 16 + /* VI PF stats offset definitions */ #define VI_PF_NUM_STATS 17 enum fw_vi_stats_pf_index { @@ -1065,7 +1236,16 @@ struct fw_vi_stats_cmd { } u; }; -/* port capabilities bitmap */ +#define S_FW_VI_STATS_CMD_VIID 0 +#define V_FW_VI_STATS_CMD_VIID(x) ((x) << S_FW_VI_STATS_CMD_VIID) + +#define S_FW_VI_STATS_CMD_NSTATS 12 +#define V_FW_VI_STATS_CMD_NSTATS(x) ((x) << S_FW_VI_STATS_CMD_NSTATS) + +#define S_FW_VI_STATS_CMD_IX 0 +#define V_FW_VI_STATS_CMD_IX(x) ((x) << S_FW_VI_STATS_CMD_IX) + +/* old 16-bit port capabilities bitmap */ enum fw_port_cap { FW_PORT_CAP_SPEED_100M = 0x0001, FW_PORT_CAP_SPEED_1G = 0x0002, @@ -1100,9 +1280,45 @@ enum fw_port_mdi { #define V_FW_PORT_CAP_MDI(x) ((x) << S_FW_PORT_CAP_MDI) #define G_FW_PORT_CAP_MDI(x) (((x) >> S_FW_PORT_CAP_MDI) & M_FW_PORT_CAP_MDI) +/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */ +#define FW_PORT_CAP32_SPEED_100M 0x00000001UL +#define FW_PORT_CAP32_SPEED_1G 0x00000002UL +#define FW_PORT_CAP32_SPEED_10G 0x00000004UL +#define FW_PORT_CAP32_SPEED_25G 0x00000008UL +#define FW_PORT_CAP32_SPEED_40G 0x00000010UL +#define FW_PORT_CAP32_SPEED_50G 0x00000020UL +#define FW_PORT_CAP32_SPEED_100G 0x00000040UL +#define FW_PORT_CAP32_FC_RX 0x00010000UL +#define FW_PORT_CAP32_FC_TX 0x00020000UL +#define FW_PORT_CAP32_802_3_PAUSE 0x00040000UL +#define FW_PORT_CAP32_802_3_ASM_DIR 0x00080000UL +#define FW_PORT_CAP32_ANEG 0x00100000UL +#define FW_PORT_CAP32_MDIX 0x00200000UL +#define FW_PORT_CAP32_MDIAUTO 0x00400000UL +#define FW_PORT_CAP32_FEC_RS 0x00800000UL +#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL + +#define S_FW_PORT_CAP32_SPEED 0 +#define M_FW_PORT_CAP32_SPEED 0xfff +#define V_FW_PORT_CAP32_SPEED(x) ((x) << S_FW_PORT_CAP32_SPEED) +#define G_FW_PORT_CAP32_SPEED(x) \ + (((x) >> S_FW_PORT_CAP32_SPEED) & M_FW_PORT_CAP32_SPEED) + +enum fw_port_mdi32 { + FW_PORT_CAP32_MDI_AUTO, +}; + +#define S_FW_PORT_CAP32_MDI 21 +#define M_FW_PORT_CAP32_MDI 3 +#define V_FW_PORT_CAP32_MDI(x) ((x) << S_FW_PORT_CAP32_MDI) +#define G_FW_PORT_CAP32_MDI(x) \ + (((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI) + enum fw_port_action { FW_PORT_ACTION_L1_CFG = 0x0001, FW_PORT_ACTION_GET_PORT_INFO = 0x0003, + FW_PORT_ACTION_L1_CFG32 = 0x0009, + FW_PORT_ACTION_GET_PORT_INFO32 = 0x000a, }; struct fw_port_cmd { @@ -1191,6 +1407,18 @@ struct fw_port_cmd { __be64 r12; } control; } dcb; + struct fw_port_l1cfg32 { + __be32 rcap32; + __be32 r; + } l1cfg32; + struct fw_port_info32 { + __be32 lstatus32_to_cbllen32; + __be32 auxlinfo32_mtu32; + __be32 linkattr32; + __be32 pcaps32; + __be32 acaps32; + __be32 lpacaps32; + } info32; } u; }; @@ -1264,6 +1492,36 @@ struct fw_port_cmd { #define G_FW_PORT_CMD_MODTYPE(x) \ (((x) >> S_FW_PORT_CMD_MODTYPE) & M_FW_PORT_CMD_MODTYPE) +#define S_FW_PORT_CMD_LSTATUS32 31 +#define M_FW_PORT_CMD_LSTATUS32 0x1 +#define V_FW_PORT_CMD_LSTATUS32(x) ((x) << S_FW_PORT_CMD_LSTATUS32) +#define F_FW_PORT_CMD_LSTATUS32 V_FW_PORT_CMD_LSTATUS32(1U) + +#define S_FW_PORT_CMD_LINKDNRC32 28 +#define M_FW_PORT_CMD_LINKDNRC32 0x7 +#define G_FW_PORT_CMD_LINKDNRC32(x) \ + (((x) >> S_FW_PORT_CMD_LINKDNRC32) & M_FW_PORT_CMD_LINKDNRC32) + +#define S_FW_PORT_CMD_MDIOCAP32 26 +#define M_FW_PORT_CMD_MDIOCAP32 0x1 +#define V_FW_PORT_CMD_MDIOCAP32(x) ((x) << S_FW_PORT_CMD_MDIOCAP32) +#define F_FW_PORT_CMD_MDIOCAP32 V_FW_PORT_CMD_MDIOCAP32(1U) + +#define S_FW_PORT_CMD_MDIOADDR32 21 +#define M_FW_PORT_CMD_MDIOADDR32 0x1f +#define G_FW_PORT_CMD_MDIOADDR32(x) \ + (((x) >> S_FW_PORT_CMD_MDIOADDR32) & M_FW_PORT_CMD_MDIOADDR32) + +#define S_FW_PORT_CMD_PORTTYPE32 13 +#define M_FW_PORT_CMD_PORTTYPE32 0xff +#define G_FW_PORT_CMD_PORTTYPE32(x) \ + (((x) >> S_FW_PORT_CMD_PORTTYPE32) & M_FW_PORT_CMD_PORTTYPE32) + +#define S_FW_PORT_CMD_MODTYPE32 8 +#define M_FW_PORT_CMD_MODTYPE32 0x1f +#define G_FW_PORT_CMD_MODTYPE32(x) \ + (((x) >> S_FW_PORT_CMD_MODTYPE32) & M_FW_PORT_CMD_MODTYPE32) + /* * These are configured into the VPD and hence tools that generate * VPD may use this enumeration. @@ -1532,6 +1790,83 @@ struct fw_rss_ind_tbl_cmd { #define G_FW_RSS_IND_TBL_CMD_IQ2(x) \ (((x) >> S_FW_RSS_IND_TBL_CMD_IQ2) & M_FW_RSS_IND_TBL_CMD_IQ2) +struct fw_rss_glb_config_cmd { + __be32 op_to_write; + __be32 retval_len16; + union fw_rss_glb_config { + struct fw_rss_glb_config_manual { + __be32 mode_pkd; + __be32 r3; + __be64 r4; + __be64 r5; + } manual; + struct fw_rss_glb_config_basicvirtual { + __be32 mode_keymode; + __be32 synmapen_to_hashtoeplitz; + __be64 r8; + __be64 r9; + } basicvirtual; + } u; +}; + +#define S_FW_RSS_GLB_CONFIG_CMD_MODE 28 +#define M_FW_RSS_GLB_CONFIG_CMD_MODE 0xf +#define G_FW_RSS_GLB_CONFIG_CMD_MODE(x) \ + (((x) >> S_FW_RSS_GLB_CONFIG_CMD_MODE) & M_FW_RSS_GLB_CONFIG_CMD_MODE) + +#define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL 1 + +#define S_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN 8 +#define V_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) +#define F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN V_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 7 +#define V_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) +#define F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 \ + V_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 6 +#define V_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) +#define F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 \ + V_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 5 +#define V_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) +#define F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 \ + V_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 4 +#define V_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) +#define F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 \ + V_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN 3 +#define V_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) +#define F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN V_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN 2 +#define V_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) +#define F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN V_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP 1 +#define V_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) +#define F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP \ + V_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP(1U) + +#define S_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ 0 +#define V_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ(x) \ + ((x) << S_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) +#define F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ \ + V_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ(1U) + struct fw_rss_vi_config_cmd { __be32 op_to_viid; __be32 retval_len16; diff --git a/drivers/net/cxgbe/base/t4vf_hw.c b/drivers/net/cxgbe/base/t4vf_hw.c new file mode 100644 index 00000000..9fd0b879 --- /dev/null +++ b/drivers/net/cxgbe/base/t4vf_hw.c @@ -0,0 +1,874 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Chelsio Communications. + * All rights reserved. + */ + +#include <rte_ethdev_driver.h> +#include <rte_ether.h> + +#include "common.h" +#include "t4_regs.h" + +/** + * t4vf_wait_dev_ready - wait till to reads of registers work + * + * Wait for the device to become ready (signified by our "who am I" register + * returning a value other than all 1's). Return an error if it doesn't + * become ready ... + */ +static int t4vf_wait_dev_ready(struct adapter *adapter) +{ + const u32 whoami = T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI; + const u32 notready1 = 0xffffffff; + const u32 notready2 = 0xeeeeeeee; + u32 val; + + val = t4_read_reg(adapter, whoami); + if (val != notready1 && val != notready2) + return 0; + + msleep(500); + val = t4_read_reg(adapter, whoami); + if (val != notready1 && val != notready2) + return 0; + + dev_err(adapter, "Device didn't become ready for access, whoami = %#x\n", + val); + return -EIO; +} + +/* + * Get the reply to a mailbox command and store it in @rpl in big-endian order. + */ +static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, + u32 mbox_addr) +{ + for ( ; nflit; nflit--, mbox_addr += 8) + *rpl++ = htobe64(t4_read_reg64(adap, mbox_addr)); +} + +/** + * t4vf_wr_mbox_core - send a command to FW through the mailbox + * @adapter: the adapter + * @cmd: the command to write + * @size: command length in bytes + * @rpl: where to optionally store the reply + * @sleep_ok: if true we may sleep while awaiting command completion + * + * Sends the given command to FW through the mailbox and waits for the + * FW to execute the command. If @rpl is not %NULL it is used to store + * the FW's reply to the command. The command and its optional reply + * are of the same length. FW can take up to 500 ms to respond. + * @sleep_ok determines whether we may sleep while awaiting the response. + * If sleeping is allowed we use progressive backoff otherwise we spin. + * + * The return value is 0 on success or a negative errno on failure. A + * failure can happen either because we are not able to execute the + * command or FW executes it but signals an error. In the latter case + * the return value is the error code indicated by FW (negated). + */ +int t4vf_wr_mbox_core(struct adapter *adapter, + const void __attribute__((__may_alias__)) *cmd, + int size, void *rpl, bool sleep_ok) +{ + /* + * We delay in small increments at first in an effort to maintain + * responsiveness for simple, fast executing commands but then back + * off to larger delays to a maximum retry delay. + */ + static const int delay[] = { + 1, 1, 3, 5, 10, 10, 20, 50, 100 + }; + + + u32 mbox_ctl = T4VF_CIM_BASE_ADDR + A_CIM_VF_EXT_MAILBOX_CTRL; + __be64 cmd_rpl[MBOX_LEN / 8]; + struct mbox_entry entry; + unsigned int delay_idx; + u32 v, mbox_data; + const __be64 *p; + int i, ret; + int ms; + + /* In T6, mailbox size is changed to 128 bytes to avoid + * invalidating the entire prefetch buffer. + */ + if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) + mbox_data = T4VF_MBDATA_BASE_ADDR; + else + mbox_data = T6VF_MBDATA_BASE_ADDR; + + /* + * Commands must be multiples of 16 bytes in length and may not be + * larger than the size of the Mailbox Data register array. + */ + if ((size % 16) != 0 || + size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4) + return -EINVAL; + + /* + * Queue ourselves onto the mailbox access list. When our entry is at + * the front of the list, we have rights to access the mailbox. So we + * wait [for a while] till we're at the front [or bail out with an + * EBUSY] ... + */ + t4_os_atomic_add_tail(&entry, &adapter->mbox_list, &adapter->mbox_lock); + + delay_idx = 0; + ms = delay[0]; + + for (i = 0; ; i += ms) { + /* + * If we've waited too long, return a busy indication. This + * really ought to be based on our initial position in the + * mailbox access list but this is a start. We very rarely + * contend on access to the mailbox ... + */ + if (i > (2 * FW_CMD_MAX_TIMEOUT)) { + t4_os_atomic_list_del(&entry, &adapter->mbox_list, + &adapter->mbox_lock); + ret = -EBUSY; + return ret; + } + + /* + * If we're at the head, break out and start the mailbox + * protocol. + */ + if (t4_os_list_first_entry(&adapter->mbox_list) == &entry) + break; + + /* + * Delay for a bit before checking again ... + */ + if (sleep_ok) { + ms = delay[delay_idx]; /* last element may repeat */ + if (delay_idx < ARRAY_SIZE(delay) - 1) + delay_idx++; + msleep(ms); + } else { + rte_delay_ms(ms); + } + } + + /* + * Loop trying to get ownership of the mailbox. Return an error + * if we can't gain ownership. + */ + v = G_MBOWNER(t4_read_reg(adapter, mbox_ctl)); + for (i = 0; v == X_MBOWNER_NONE && i < 3; i++) + v = G_MBOWNER(t4_read_reg(adapter, mbox_ctl)); + + if (v != X_MBOWNER_PL) { + t4_os_atomic_list_del(&entry, &adapter->mbox_list, + &adapter->mbox_lock); + ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT; + return ret; + } + + /* + * Write the command array into the Mailbox Data register array and + * transfer ownership of the mailbox to the firmware. + */ + for (i = 0, p = cmd; i < size; i += 8) + t4_write_reg64(adapter, mbox_data + i, be64_to_cpu(*p++)); + + t4_read_reg(adapter, mbox_data); /* flush write */ + t4_write_reg(adapter, mbox_ctl, + F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW)); + t4_read_reg(adapter, mbox_ctl); /* flush write */ + delay_idx = 0; + ms = delay[0]; + + /* + * Spin waiting for firmware to acknowledge processing our command. + */ + for (i = 0; i < FW_CMD_MAX_TIMEOUT; i++) { + if (sleep_ok) { + ms = delay[delay_idx]; /* last element may repeat */ + if (delay_idx < ARRAY_SIZE(delay) - 1) + delay_idx++; + msleep(ms); + } else { + rte_delay_ms(ms); + } + + /* + * If we're the owner, see if this is the reply we wanted. + */ + v = t4_read_reg(adapter, mbox_ctl); + if (G_MBOWNER(v) == X_MBOWNER_PL) { + /* + * If the Message Valid bit isn't on, revoke ownership + * of the mailbox and continue waiting for our reply. + */ + if ((v & F_MBMSGVALID) == 0) { + t4_write_reg(adapter, mbox_ctl, + V_MBOWNER(X_MBOWNER_NONE)); + continue; + } + + /* + * We now have our reply. Extract the command return + * value, copy the reply back to our caller's buffer + * (if specified) and revoke ownership of the mailbox. + * We return the (negated) firmware command return + * code (this depends on FW_SUCCESS == 0). (Again we + * avoid clogging the log with FW_VI_STATS_CMD + * reply results.) + */ + + /* + * Retrieve the command reply and release the mailbox. + */ + get_mbox_rpl(adapter, cmd_rpl, size / 8, mbox_data); + t4_write_reg(adapter, mbox_ctl, + V_MBOWNER(X_MBOWNER_NONE)); + t4_os_atomic_list_del(&entry, &adapter->mbox_list, + &adapter->mbox_lock); + + /* return value in high-order host-endian word */ + v = be64_to_cpu(cmd_rpl[0]); + + if (rpl) { + /* request bit in high-order BE word */ + WARN_ON((be32_to_cpu(*(const u32 *)cmd) + & F_FW_CMD_REQUEST) == 0); + memcpy(rpl, cmd_rpl, size); + } + return -((int)G_FW_CMD_RETVAL(v)); + } + } + + /* + * We timed out. Return the error ... + */ + dev_err(adapter, "command %#x timed out\n", + *(const u8 *)cmd); + dev_err(adapter, " Control = %#x\n", t4_read_reg(adapter, mbox_ctl)); + t4_os_atomic_list_del(&entry, &adapter->mbox_list, &adapter->mbox_lock); + ret = -ETIMEDOUT; + return ret; +} + +/** + * t4vf_fw_reset - issue a reset to FW + * @adapter: the adapter + * + * Issues a reset command to FW. For a Physical Function this would + * result in the Firmware resetting all of its state. For a Virtual + * Function this just resets the state associated with the VF. + */ +int t4vf_fw_reset(struct adapter *adapter) +{ + struct fw_reset_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) | + F_FW_CMD_WRITE); + cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd))); + return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); +} + +/** + * t4vf_prep_adapter - prepare SW and HW for operation + * @adapter: the adapter + * + * Initialize adapter SW state for the various HW modules, set initial + * values for some adapter tunables, take PHYs out of reset, and + * initialize the MDIO interface. + */ +int t4vf_prep_adapter(struct adapter *adapter) +{ + u32 pl_vf_rev; + int ret, ver; + + ret = t4vf_wait_dev_ready(adapter); + if (ret < 0) + return ret; + + /* + * Default port and clock for debugging in case we can't reach + * firmware. + */ + adapter->params.nports = 1; + adapter->params.vfres.pmask = 1; + adapter->params.vpd.cclk = 50000; + + pl_vf_rev = G_REV(t4_read_reg(adapter, A_PL_VF_REV)); + adapter->params.pci.device_id = adapter->pdev->id.device_id; + adapter->params.pci.vendor_id = adapter->pdev->id.vendor_id; + + /* + * WE DON'T NEED adapter->params.chip CODE ONCE PL_REV CONTAINS + * ADAPTER (VERSION << 4 | REVISION) + */ + ver = CHELSIO_PCI_ID_VER(adapter->params.pci.device_id); + adapter->params.chip = 0; + switch (ver) { + case CHELSIO_T5: + adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, + pl_vf_rev); + adapter->params.arch.sge_fl_db = F_DBPRIO | F_DBTYPE; + adapter->params.arch.mps_tcam_size = + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + break; + case CHELSIO_T6: + adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, + pl_vf_rev); + adapter->params.arch.sge_fl_db = 0; + adapter->params.arch.mps_tcam_size = + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + break; + default: + dev_err(adapter, "%s: Device %d is not supported\n", + __func__, adapter->params.pci.device_id); + return -EINVAL; + } + return 0; +} + +/** + * t4vf_query_params - query FW or device parameters + * @adapter: the adapter + * @nparams: the number of parameters + * @params: the parameter names + * @vals: the parameter values + * + * Reads the values of firmware or device parameters. Up to 7 parameters + * can be queried at once. + */ +int t4vf_query_params(struct adapter *adapter, unsigned int nparams, + const u32 *params, u32 *vals) +{ + struct fw_params_cmd cmd, rpl; + struct fw_params_param *p; + unsigned int i; + size_t len16; + int ret; + + if (nparams > 7) + return -EINVAL; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ); + len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd, + param[nparams]), 16); + cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16)); + for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) + p->mnem = cpu_to_be32(*params++); + ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); + if (ret == 0) + for (i = 0, p = &rpl.param[0]; i < nparams; i++, p++) + *vals++ = be32_to_cpu(p->val); + return ret; +} + +/** + * t4vf_get_vpd_params - retrieve device VPD paremeters + * @adapter: the adapter + * + * Retrives various device Vital Product Data parameters. The parameters + * are stored in @adapter->params.vpd. + */ +int t4vf_get_vpd_params(struct adapter *adapter) +{ + struct vpd_params *vpd_params = &adapter->params.vpd; + u32 params[7], vals[7]; + int v; + + params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | + V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); + v = t4vf_query_params(adapter, 1, params, vals); + if (v != FW_SUCCESS) + return v; + vpd_params->cclk = vals[0]; + dev_debug(adapter, "%s: vpd_params->cclk = %u\n", + __func__, vpd_params->cclk); + return 0; +} + +/** + * t4vf_get_dev_params - retrieve device paremeters + * @adapter: the adapter + * + * Retrives fw and tp version. + */ +int t4vf_get_dev_params(struct adapter *adapter) +{ + u32 params[7], vals[7]; + int v; + + params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | + V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWREV)); + params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | + V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_TPREV)); + v = t4vf_query_params(adapter, 2, params, vals); + if (v != FW_SUCCESS) + return v; + adapter->params.fw_vers = vals[0]; + adapter->params.tp_vers = vals[1]; + + dev_info(adapter, "Firmware version: %u.%u.%u.%u\n", + G_FW_HDR_FW_VER_MAJOR(adapter->params.fw_vers), + G_FW_HDR_FW_VER_MINOR(adapter->params.fw_vers), + G_FW_HDR_FW_VER_MICRO(adapter->params.fw_vers), + G_FW_HDR_FW_VER_BUILD(adapter->params.fw_vers)); + + dev_info(adapter, "TP Microcode version: %u.%u.%u.%u\n", + G_FW_HDR_FW_VER_MAJOR(adapter->params.tp_vers), + G_FW_HDR_FW_VER_MINOR(adapter->params.tp_vers), + G_FW_HDR_FW_VER_MICRO(adapter->params.tp_vers), + G_FW_HDR_FW_VER_BUILD(adapter->params.tp_vers)); + return 0; +} + +/** + * t4vf_set_params - sets FW or device parameters + * @adapter: the adapter + * @nparams: the number of parameters + * @params: the parameter names + * @vals: the parameter values + * + * Sets the values of firmware or device parameters. Up to 7 parameters + * can be specified at once. + */ +int t4vf_set_params(struct adapter *adapter, unsigned int nparams, + const u32 *params, const u32 *vals) +{ + struct fw_params_param *p; + struct fw_params_cmd cmd; + unsigned int i; + size_t len16; + + if (nparams > 7) + return -EINVAL; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_WRITE); + len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd, + param[nparams]), 16); + cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16)); + for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) { + p->mnem = cpu_to_be32(*params++); + p->val = cpu_to_be32(*vals++); + } + return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); +} + +/** + * t4vf_fl_pkt_align - return the fl packet alignment + * @adapter: the adapter + * + * T4 has a single field to specify the packing and padding boundary. + * T5 onwards has separate fields for this and hence the alignment for + * next packet offset is maximum of these two. + */ +int t4vf_fl_pkt_align(struct adapter *adapter, u32 sge_control, + u32 sge_control2) +{ + unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift; + + /* T4 uses a single control field to specify both the PCIe Padding and + * Packing Boundary. T5 introduced the ability to specify these + * separately. The actual Ingress Packet Data alignment boundary + * within Packed Buffer Mode is the maximum of these two + * specifications. + */ + if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) + ingpad_shift = X_INGPADBOUNDARY_SHIFT; + else + ingpad_shift = X_T6_INGPADBOUNDARY_SHIFT; + + ingpadboundary = 1 << (G_INGPADBOUNDARY(sge_control) + ingpad_shift); + + fl_align = ingpadboundary; + if (!is_t4(adapter->params.chip)) { + ingpackboundary = G_INGPACKBOUNDARY(sge_control2); + if (ingpackboundary == X_INGPACKBOUNDARY_16B) + ingpackboundary = 16; + else + ingpackboundary = 1 << (ingpackboundary + + X_INGPACKBOUNDARY_SHIFT); + + fl_align = max(ingpadboundary, ingpackboundary); + } + return fl_align; +} + +unsigned int t4vf_get_pf_from_vf(struct adapter *adapter) +{ + u32 whoami; + + whoami = t4_read_reg(adapter, T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI); + return (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + G_SOURCEPF(whoami) : G_T6_SOURCEPF(whoami)); +} + +/** + * t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration + * @adapter: the adapter + * + * Retrieves global RSS mode and parameters with which we have to live + * and stores them in the @adapter's RSS parameters. + */ +int t4vf_get_rss_glb_config(struct adapter *adapter) +{ + struct rss_params *rss = &adapter->params.rss; + struct fw_rss_glb_config_cmd cmd, rpl; + int v; + + /* + * Execute an RSS Global Configuration read command to retrieve + * our RSS configuration. + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ); + cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); + v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); + if (v != FW_SUCCESS) + return v; + + /* + * Translate the big-endian RSS Global Configuration into our + * cpu-endian format based on the RSS mode. We also do first level + * filtering at this point to weed out modes which don't support + * VF Drivers ... + */ + rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE + (be32_to_cpu(rpl.u.manual.mode_pkd)); + switch (rss->mode) { + case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: { + u32 word = be32_to_cpu + (rpl.u.basicvirtual.synmapen_to_hashtoeplitz); + + rss->u.basicvirtual.synmapen = + ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0); + rss->u.basicvirtual.syn4tupenipv6 = + ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0); + rss->u.basicvirtual.syn2tupenipv6 = + ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0); + rss->u.basicvirtual.syn4tupenipv4 = + ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0); + rss->u.basicvirtual.syn2tupenipv4 = + ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0); + rss->u.basicvirtual.ofdmapen = + ((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0); + rss->u.basicvirtual.tnlmapen = + ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0); + rss->u.basicvirtual.tnlalllookup = + ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0); + rss->u.basicvirtual.hashtoeplitz = + ((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0); + + /* we need at least Tunnel Map Enable to be set */ + if (!rss->u.basicvirtual.tnlmapen) + return -EINVAL; + break; + } + + default: + /* all unknown/unsupported RSS modes result in an error */ + return -EINVAL; + } + return 0; +} + +/** + * t4vf_get_vfres - retrieve VF resource limits + * @adapter: the adapter + * + * Retrieves configured resource limits and capabilities for a virtual + * function. The results are stored in @adapter->vfres. + */ +int t4vf_get_vfres(struct adapter *adapter) +{ + struct vf_resources *vfres = &adapter->params.vfres; + struct fw_pfvf_cmd cmd, rpl; + u32 word; + int v; + + /* + * Execute PFVF Read command to get VF resource limits; bail out early + * with error on command failure. + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ); + cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); + v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); + if (v != FW_SUCCESS) + return v; + + /* + * Extract VF resource limits and return success. + */ + word = be32_to_cpu(rpl.niqflint_niq); + vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word); + vfres->niq = G_FW_PFVF_CMD_NIQ(word); + + word = be32_to_cpu(rpl.type_to_neq); + vfres->neq = G_FW_PFVF_CMD_NEQ(word); + vfres->pmask = G_FW_PFVF_CMD_PMASK(word); + + word = be32_to_cpu(rpl.tc_to_nexactf); + vfres->tc = G_FW_PFVF_CMD_TC(word); + vfres->nvi = G_FW_PFVF_CMD_NVI(word); + vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word); + + word = be32_to_cpu(rpl.r_caps_to_nethctrl); + vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word); + vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word); + vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word); + return 0; +} + +/** + * t4vf_get_port_stats_fw - collect "port" statistics via Firmware + * @adapter: the adapter + * @pidx: the port index + * @s: the stats structure to fill + * + * Collect statistics for the "port"'s Virtual Interface via Firmware + * commands. + */ +static int t4vf_get_port_stats_fw(struct adapter *adapter, int pidx, + struct port_stats *p) +{ + struct port_info *pi = adap2pinfo(adapter, pidx); + unsigned int rem = VI_VF_NUM_STATS; + struct fw_vi_stats_vf fwstats; + __be64 *fwsp = (__be64 *)&fwstats; + + /* + * Grab the Virtual Interface statistics a chunk at a time via mailbox + * commands. We could use a Work Request and get all of them at once + * but that's an asynchronous interface which is awkward to use. + */ + while (rem) { + unsigned int ix = VI_VF_NUM_STATS - rem; + unsigned int nstats = min(6U, rem); + struct fw_vi_stats_cmd cmd, rpl; + size_t len = (offsetof(struct fw_vi_stats_cmd, u) + + sizeof(struct fw_vi_stats_ctl)); + size_t len16 = DIV_ROUND_UP(len, 16); + int ret; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_STATS_CMD) | + V_FW_VI_STATS_CMD_VIID(pi->viid) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ); + cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16)); + cmd.u.ctl.nstats_ix = + cpu_to_be16(V_FW_VI_STATS_CMD_IX(ix) | + V_FW_VI_STATS_CMD_NSTATS(nstats)); + ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl); + if (ret != FW_SUCCESS) + return ret; + + memcpy(fwsp, &rpl.u.ctl.stat0, sizeof(__be64) * nstats); + + rem -= nstats; + fwsp += nstats; + } + + /* + * Translate firmware statistics into host native statistics. + */ + p->tx_bcast_frames = be64_to_cpu(fwstats.tx_bcast_frames); + p->tx_mcast_frames = be64_to_cpu(fwstats.tx_mcast_frames); + p->tx_ucast_frames = be64_to_cpu(fwstats.tx_ucast_frames); + p->tx_drop = be64_to_cpu(fwstats.tx_drop_frames); + + p->rx_bcast_frames = be64_to_cpu(fwstats.rx_bcast_frames); + p->rx_mcast_frames = be64_to_cpu(fwstats.rx_mcast_frames); + p->rx_ucast_frames = be64_to_cpu(fwstats.rx_ucast_frames); + p->rx_len_err = be64_to_cpu(fwstats.rx_err_frames); + + return 0; +} + +/** + * t4vf_get_port_stats - collect "port" statistics + * @adapter: the adapter + * @pidx: the port index + * @s: the stats structure to fill + * + * Collect statistics for the "port"'s Virtual Interface. + */ +void t4vf_get_port_stats(struct adapter *adapter, int pidx, + struct port_stats *p) +{ + /* + * If this is not the first Virtual Interface for our Virtual + * Function, we need to use Firmware commands to retrieve its + * MPS statistics. + */ + if (pidx != 0) + t4vf_get_port_stats_fw(adapter, pidx, p); + + /* + * But for the first VI, we can grab its statistics via the MPS + * register mapped into the VF register space. + */ +#define GET_STAT(name) \ + t4_read_reg64(adapter, \ + T4VF_MPS_BASE_ADDR + A_MPS_VF_STAT_##name##_L) + p->tx_bcast_frames = GET_STAT(TX_VF_BCAST_FRAMES); + p->tx_mcast_frames = GET_STAT(TX_VF_MCAST_FRAMES); + p->tx_ucast_frames = GET_STAT(TX_VF_UCAST_FRAMES); + p->tx_drop = GET_STAT(TX_VF_DROP_FRAMES); + + p->rx_bcast_frames = GET_STAT(RX_VF_BCAST_FRAMES); + p->rx_mcast_frames = GET_STAT(RX_VF_MCAST_FRAMES); + p->rx_ucast_frames = GET_STAT(RX_VF_UCAST_FRAMES); + + p->rx_len_err = GET_STAT(RX_VF_ERR_FRAMES); +#undef GET_STAT +} + +static int t4vf_alloc_vi(struct adapter *adapter, int port_id) +{ + struct fw_vi_cmd cmd, rpl; + int v; + + /* + * Execute a VI command to allocate Virtual Interface and return its + * VIID. + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_WRITE | + F_FW_CMD_EXEC); + cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) | + F_FW_VI_CMD_ALLOC); + cmd.portid_pkd = V_FW_VI_CMD_PORTID(port_id); + v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); + if (v != FW_SUCCESS) + return v; + return G_FW_VI_CMD_VIID(be16_to_cpu(rpl.type_to_viid)); +} + +int t4vf_port_init(struct adapter *adapter) +{ + unsigned int fw_caps = adapter->params.fw_caps_support; + struct fw_port_cmd port_cmd, port_rpl; + struct fw_vi_cmd vi_cmd, vi_rpl; + fw_port_cap32_t pcaps, acaps; + enum fw_port_type port_type; + int mdio_addr; + int ret, i; + + for_each_port(adapter, i) { + struct port_info *p = adap2pinfo(adapter, i); + + /* + * If we haven't yet determined if we're talking to Firmware + * which knows the new 32-bit Port Caps, it's time to find + * out now. This will also tell new Firmware to send us Port + * Status Updates using the new 32-bit Port Capabilities + * version of the Port Information message. + */ + if (fw_caps == FW_CAPS_UNKNOWN) { + u32 param, val; + + param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | + V_FW_PARAMS_PARAM_X + (FW_PARAMS_PARAM_PFVF_PORT_CAPS32)); + val = 1; + ret = t4vf_set_params(adapter, 1, ¶m, &val); + fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16); + adapter->params.fw_caps_support = fw_caps; + } + + ret = t4vf_alloc_vi(adapter, p->port_id); + if (ret < 0) { + dev_err(&pdev->dev, "cannot allocate VI for port %d:" + " err=%d\n", p->port_id, ret); + return ret; + } + p->viid = ret; + + /* + * Execute a VI Read command to get our Virtual Interface + * information like MAC address, etc. + */ + memset(&vi_cmd, 0, sizeof(vi_cmd)); + vi_cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ); + vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd)); + vi_cmd.type_to_viid = cpu_to_be16(V_FW_VI_CMD_VIID(p->viid)); + ret = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl); + if (ret != FW_SUCCESS) + return ret; + + p->rss_size = G_FW_VI_CMD_RSSSIZE + (be16_to_cpu(vi_rpl.norss_rsssize)); + t4_os_set_hw_addr(adapter, i, vi_rpl.mac); + + /* + * If we don't have read access to our port information, we're + * done now. Else, execute a PORT Read command to get it ... + */ + if (!(adapter->params.vfres.r_caps & FW_CMD_CAP_PORT)) + return 0; + + memset(&port_cmd, 0, sizeof(port_cmd)); + port_cmd.op_to_portid = cpu_to_be32 + (V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST | + F_FW_CMD_READ | + V_FW_PORT_CMD_PORTID(p->port_id)); + port_cmd.action_to_len16 = cpu_to_be32 + (V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ? + FW_PORT_ACTION_GET_PORT_INFO : + FW_PORT_ACTION_GET_PORT_INFO32) | + FW_LEN16(port_cmd)); + ret = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), + &port_rpl); + if (ret != FW_SUCCESS) + return ret; + + /* + * Extract the various fields from the Port Information message. + */ + if (fw_caps == FW_CAPS16) { + u32 lstatus = be32_to_cpu + (port_rpl.u.info.lstatus_to_modtype); + + port_type = G_FW_PORT_CMD_PTYPE(lstatus); + mdio_addr = ((lstatus & F_FW_PORT_CMD_MDIOCAP) ? + (int)G_FW_PORT_CMD_MDIOADDR(lstatus) : + -1); + pcaps = fwcaps16_to_caps32 + (be16_to_cpu(port_rpl.u.info.pcap)); + acaps = fwcaps16_to_caps32 + (be16_to_cpu(port_rpl.u.info.acap)); + } else { + u32 lstatus32 = be32_to_cpu + (port_rpl.u.info32.lstatus32_to_cbllen32); + + port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32); + mdio_addr = ((lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ? + (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) : + -1); + pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32); + acaps = be32_to_cpu(port_rpl.u.info32.acaps32); + } + + p->port_type = port_type; + p->mdio_addr = mdio_addr; + p->mod_type = FW_PORT_MOD_TYPE_NA; + init_link_config(&p->link_cfg, pcaps, acaps); + } + return 0; +} diff --git a/drivers/net/cxgbe/base/t4vf_hw.h b/drivers/net/cxgbe/base/t4vf_hw.h new file mode 100644 index 00000000..55e436e7 --- /dev/null +++ b/drivers/net/cxgbe/base/t4vf_hw.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Chelsio Communications. + * All rights reserved. + */ + +#ifndef __T4VF_HW_H +#define __T4VF_HW_H + +#define T4VF_PL_BASE_ADDR 0x0200 +#define T4VF_CIM_BASE_ADDR 0x0300 +#define T4VF_MBDATA_BASE_ADDR 0x0240 +#define T6VF_MBDATA_BASE_ADDR 0x0280 + +#define NUM_CIM_VF_MAILBOX_DATA_INSTANCES NUM_CIM_PF_MAILBOX_DATA_INSTANCES +#endif /* __T4VF_HW_H */ |