From a18011ea41c7f3cd2f711556eb8c4c241983da9d Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Wed, 25 Dec 2013 00:12:01 +0530 Subject: [PATCH] linux-next-cherry-picks: Misc fixes for Chelsio T4/T5 This patch brings-in the following linux-next commits: d14807d cxgb4: Much cleaner implementation of is_t4()/is_t5() 16e4762 cxgb4: Add new scheme to update T4/T5 firmware b6f8eae cxgb4: Reserve stid 0 for T4/T5 adapters 7c89e55 cxgb4: Include TCP as protocol when creating server filters 470c60c cxgb4: Assign filter server TIDs properly 15f63b7 cxgb4: Account for stid entries properly in case of IPv6 dcf7b6f cxgb4: Add API to correctly calculate tuple fields a4ea025 RDMA/cxgb4: Calculate the filter server TID properly 8c04469 RDMA/cxgb4: Server filters are supported only for IPv4 41b4f86 RDMA/cxgb4: Use cxgb4_select_ntuple to correctly calculate ntuple fields Signed-off-by: Kumar Sanghvi --- ...leaner-implementation-of-is_t4-is_t5.patch | 524 +++++++++++++ ...-new-scheme-to-update-T4-T5-firmware.patch | 690 ++++++++++++++++++ ...b4-Reserve-stid-0-for-T4-T5-adapters.patch | 49 ++ ...P-as-protocol-when-creating-server-f.patch | 55 ++ ...-filter-server-TIDS-Account-for-stid.patch | 95 +++ ...-to-correctly-calculate-tuple-fields.patch | 405 ++++++++++ ...ulate-the-filter-server-TID-properly.patch | 32 + ...r-filters-are-supported-only-for-IPv.patch | 29 + ...xgb4_select_ntuple-to-correctly-calc.patch | 139 ++++ 9 files changed, 2018 insertions(+) create mode 100644 linux-next-cherry-picks/0001-cxgb4-Much-cleaner-implementation-of-is_t4-is_t5.patch create mode 100644 linux-next-cherry-picks/0002-cxgb4-Add-new-scheme-to-update-T4-T5-firmware.patch create mode 100644 linux-next-cherry-picks/0003-cxgb4-Reserve-stid-0-for-T4-T5-adapters.patch create mode 100644 linux-next-cherry-picks/0004-cxgb4-Include-TCP-as-protocol-when-creating-server-f.patch create mode 100644 linux-next-cherry-picks/0005-cxgb4-Assign-filter-server-TIDS-Account-for-stid.patch create mode 100644 linux-next-cherry-picks/0006-cxgb4-Add-API-to-correctly-calculate-tuple-fields.patch create mode 100644 linux-next-cherry-picks/0007-RDMA-cxgb4-Calculate-the-filter-server-TID-properly.patch create mode 100644 linux-next-cherry-picks/0008-RDMA-cxgb4-Server-filters-are-supported-only-for-IPv.patch create mode 100644 linux-next-cherry-picks/0009-RDMA-cxgb4-Use-cxgb4_select_ntuple-to-correctly-calc.patch diff --git a/linux-next-cherry-picks/0001-cxgb4-Much-cleaner-implementation-of-is_t4-is_t5.patch b/linux-next-cherry-picks/0001-cxgb4-Much-cleaner-implementation-of-is_t4-is_t5.patch new file mode 100644 index 0000000..89938d1 --- /dev/null +++ b/linux-next-cherry-picks/0001-cxgb4-Much-cleaner-implementation-of-is_t4-is_t5.patch @@ -0,0 +1,524 @@ +From d14807dd8e7eaa41a8fee5fc3acbdaf2a0258b76 Mon Sep 17 00:00:00 2001 +From: Hariprasad Shenai +Date: Tue, 3 Dec 2013 17:05:56 +0530 +Subject: [PATCH] cxgb4: Much cleaner implementation of is_t4()/is_t5() + +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 45 ++++++++++++----------- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 40 ++++++++++---------- + drivers/net/ethernet/chelsio/cxgb4/sge.c | 12 +++--- + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 41 ++++++++++----------- + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 5 +++ + 5 files changed, 73 insertions(+), 70 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index ecd2fb3..9710a16 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -240,6 +240,26 @@ struct pci_params { + unsigned char width; + }; + ++#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) ++#define CHELSIO_CHIP_FPGA 0x100 ++#define CHELSIO_CHIP_VERSION(code) (((code) >> 4) & 0xf) ++#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) ++ ++#define CHELSIO_T4 0x4 ++#define CHELSIO_T5 0x5 ++ ++enum chip_type { ++ T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), ++ T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), ++ T4_FIRST_REV = T4_A1, ++ T4_LAST_REV = T4_A2, ++ ++ T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), ++ T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1), ++ T5_FIRST_REV = T5_A0, ++ T5_LAST_REV = T5_A1, ++}; ++ + struct adapter_params { + struct tp_params tp; + struct vpd_params vpd; +@@ -259,7 +279,7 @@ struct adapter_params { + + unsigned char nports; /* # of ethernet ports */ + unsigned char portvec; +- unsigned char rev; /* chip revision */ ++ enum chip_type chip; /* chip code */ + unsigned char offload; + + unsigned char bypass; +@@ -512,25 +532,6 @@ struct sge { + + struct l2t_data; + +-#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) +-#define CHELSIO_CHIP_VERSION(code) ((code) >> 4) +-#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) +- +-#define CHELSIO_T4 0x4 +-#define CHELSIO_T5 0x5 +- +-enum chip_type { +- T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0), +- T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), +- T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), +- T4_FIRST_REV = T4_A1, +- T4_LAST_REV = T4_A3, +- +- T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), +- T5_FIRST_REV = T5_A1, +- T5_LAST_REV = T5_A1, +-}; +- + #ifdef CONFIG_PCI_IOV + + /* T4 supports SRIOV on PF0-3 and T5 on PF0-7. However, the Serial +@@ -715,12 +716,12 @@ enum { + + static inline int is_t5(enum chip_type chip) + { +- return (chip >= T5_FIRST_REV && chip <= T5_LAST_REV); ++ return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T5; + } + + static inline int is_t4(enum chip_type chip) + { +- return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV); ++ return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4; + } + + static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index 8b929ee..35933cd 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -1083,7 +1083,7 @@ static int upgrade_fw(struct adapter *adap) + struct device *dev = adap->pdev_dev; + char *fw_file_name; + +- switch (CHELSIO_CHIP_VERSION(adap->chip)) { ++ switch (CHELSIO_CHIP_VERSION(adap->params.chip)) { + case CHELSIO_T4: + fw_file_name = FW_FNAME; + exp_major = FW_VERSION_MAJOR; +@@ -1093,7 +1093,7 @@ static int upgrade_fw(struct adapter *adap) + exp_major = FW_VERSION_MAJOR_T5; + break; + default: +- dev_err(dev, "Unsupported chip type, %x\n", adap->chip); ++ dev_err(dev, "Unsupported chip type, %x\n", adap->params.chip); + return -EINVAL; + } + +@@ -1415,7 +1415,7 @@ static int get_sset_count(struct net_device *dev, int sset) + static int get_regs_len(struct net_device *dev) + { + struct adapter *adap = netdev2adap(dev); +- if (is_t4(adap->chip)) ++ if (is_t4(adap->params.chip)) + return T4_REGMAP_SIZE; + else + return T5_REGMAP_SIZE; +@@ -1499,7 +1499,7 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, + data += sizeof(struct port_stats) / sizeof(u64); + collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); + data += sizeof(struct queue_port_stats) / sizeof(u64); +- if (!is_t4(adapter->chip)) { ++ if (!is_t4(adapter->params.chip)) { + t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7)); + val1 = t4_read_reg(adapter, SGE_STAT_TOTAL); + val2 = t4_read_reg(adapter, SGE_STAT_MATCH); +@@ -1521,8 +1521,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, + */ + static inline unsigned int mk_adap_vers(const struct adapter *ap) + { +- return CHELSIO_CHIP_VERSION(ap->chip) | +- (CHELSIO_CHIP_RELEASE(ap->chip) << 10) | (1 << 16); ++ return CHELSIO_CHIP_VERSION(ap->params.chip) | ++ (CHELSIO_CHIP_RELEASE(ap->params.chip) << 10) | (1 << 16); + } + + static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, +@@ -2189,7 +2189,7 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, + static const unsigned int *reg_ranges; + int arr_size = 0, buf_size = 0; + +- if (is_t4(ap->chip)) { ++ if (is_t4(ap->params.chip)) { + reg_ranges = &t4_reg_ranges[0]; + arr_size = ARRAY_SIZE(t4_reg_ranges); + buf_size = T4_REGMAP_SIZE; +@@ -2967,7 +2967,7 @@ static int setup_debugfs(struct adapter *adap) + size = t4_read_reg(adap, MA_EDRAM1_BAR); + add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); + } +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + if (i & EXT_MEM_ENABLE) + add_debugfs_mem(adap, "mc", MEM_MC, +@@ -3419,7 +3419,7 @@ unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo) + + v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); + v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + lp_count = G_LP_COUNT(v1); + hp_count = G_HP_COUNT(v1); + } else { +@@ -3588,7 +3588,7 @@ static void drain_db_fifo(struct adapter *adap, int usecs) + do { + v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); + v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + lp_count = G_LP_COUNT(v1); + hp_count = G_HP_COUNT(v1); + } else { +@@ -3708,7 +3708,7 @@ static void process_db_drop(struct work_struct *work) + + adap = container_of(work, struct adapter, db_drop_task); + +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + disable_dbs(adap); + notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); + drain_db_fifo(adap, 1); +@@ -3753,7 +3753,7 @@ static void process_db_drop(struct work_struct *work) + + void t4_db_full(struct adapter *adap) + { +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + t4_set_reg_field(adap, SGE_INT_ENABLE3, + DBFIFO_HP_INT | DBFIFO_LP_INT, 0); + queue_work(workq, &adap->db_full_task); +@@ -3762,7 +3762,7 @@ void t4_db_full(struct adapter *adap) + + void t4_db_dropped(struct adapter *adap) + { +- if (is_t4(adap->chip)) ++ if (is_t4(adap->params.chip)) + queue_work(workq, &adap->db_drop_task); + } + +@@ -3789,7 +3789,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) + lli.nchan = adap->params.nports; + lli.nports = adap->params.nports; + lli.wr_cred = adap->params.ofldq_wr_cred; +- lli.adapter_type = adap->params.rev; ++ lli.adapter_type = adap->params.chip; + lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); + lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( + t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >> +@@ -4483,7 +4483,7 @@ static void setup_memwin(struct adapter *adap) + u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base; + + bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + mem_win0_base = bar0 + MEMWIN0_BASE; + mem_win1_base = bar0 + MEMWIN1_BASE; + mem_win2_base = bar0 + MEMWIN2_BASE; +@@ -4686,7 +4686,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) + * then use that. Otherwise, use the configuration file stored + * in the adapter flash ... + */ +- switch (CHELSIO_CHIP_VERSION(adapter->chip)) { ++ switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) { + case CHELSIO_T4: + fw_config_file = FW_CFNAME; + break; +@@ -5787,7 +5787,7 @@ static void print_port_info(const struct net_device *dev) + + netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", + adap->params.vpd.id, +- CHELSIO_CHIP_RELEASE(adap->params.rev), buf, ++ CHELSIO_CHIP_RELEASE(adap->params.chip), buf, + is_offload(adap) ? "R" : "", adap->params.pci.width, spd, + (adap->flags & USING_MSIX) ? " MSI-X" : + (adap->flags & USING_MSI) ? " MSI" : ""); +@@ -5910,7 +5910,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + if (err) + goto out_unmap_bar0; + +- if (!is_t4(adapter->chip)) { ++ if (!is_t4(adapter->params.chip)) { + s_qpp = QUEUESPERPAGEPF1 * adapter->fn; + qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter, + SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp); +@@ -6064,7 +6064,7 @@ sriov: + out_free_dev: + free_some_resources(adapter); + out_unmap_bar: +- if (!is_t4(adapter->chip)) ++ if (!is_t4(adapter->params.chip)) + iounmap(adapter->bar2); + out_unmap_bar0: + iounmap(adapter->regs); +@@ -6116,7 +6116,7 @@ static void remove_one(struct pci_dev *pdev) + + free_some_resources(adapter); + iounmap(adapter->regs); +- if (!is_t4(adapter->chip)) ++ if (!is_t4(adapter->params.chip)) + iounmap(adapter->bar2); + kfree(adapter); + pci_disable_pcie_error_reporting(pdev); +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index ac311f5..cc380c3 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -509,7 +509,7 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q) + u32 val; + if (q->pend_cred >= 8) { + val = PIDX(q->pend_cred / 8); +- if (!is_t4(adap->chip)) ++ if (!is_t4(adap->params.chip)) + val |= DBTYPE(1); + wmb(); + t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) | +@@ -847,7 +847,7 @@ static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n) + wmb(); /* write descriptors before telling HW */ + spin_lock(&q->db_lock); + if (!q->db_disabled) { +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), + QID(q->cntxt_id) | PIDX(n)); + } else { +@@ -1596,7 +1596,7 @@ static noinline int handle_trace_pkt(struct adapter *adap, + return 0; + } + +- if (is_t4(adap->chip)) ++ if (is_t4(adap->params.chip)) + __skb_pull(skb, sizeof(struct cpl_trace_pkt)); + else + __skb_pull(skb, sizeof(struct cpl_t5_trace_pkt)); +@@ -1661,7 +1661,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, + const struct cpl_rx_pkt *pkt; + struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); + struct sge *s = &q->adap->sge; +- int cpl_trace_pkt = is_t4(q->adap->chip) ? ++ int cpl_trace_pkt = is_t4(q->adap->params.chip) ? + CPL_TRACE_PKT : CPL_TRACE_PKT_T5; + + if (unlikely(*(u8 *)rsp == cpl_trace_pkt)) +@@ -2182,7 +2182,7 @@ err: + static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) + { + q->cntxt_id = id; +- if (!is_t4(adap->chip)) { ++ if (!is_t4(adap->params.chip)) { + unsigned int s_qpp; + unsigned short udb_density; + unsigned long qpshift; +@@ -2641,7 +2641,7 @@ static int t4_sge_init_hard(struct adapter *adap) + * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows + * and generate an interrupt when this occurs so we can recover. + */ +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, + V_HP_INT_THRESH(M_HP_INT_THRESH) | + V_LP_INT_THRESH(M_LP_INT_THRESH), +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index 4cbb2f9..83b5e42 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -296,7 +296,7 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) + u32 mc_bist_cmd, mc_bist_cmd_addr, mc_bist_cmd_len; + u32 mc_bist_status_rdata, mc_bist_data_pattern; + +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + mc_bist_cmd = MC_BIST_CMD; + mc_bist_cmd_addr = MC_BIST_CMD_ADDR; + mc_bist_cmd_len = MC_BIST_CMD_LEN; +@@ -349,7 +349,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) + u32 edc_bist_cmd, edc_bist_cmd_addr, edc_bist_cmd_len; + u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata; + +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + edc_bist_cmd = EDC_REG(EDC_BIST_CMD, idx); + edc_bist_cmd_addr = EDC_REG(EDC_BIST_CMD_ADDR, idx); + edc_bist_cmd_len = EDC_REG(EDC_BIST_CMD_LEN, idx); +@@ -402,7 +402,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) + static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir) + { + int i; +- u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); ++ u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn); + + /* + * Setup offset into PCIE memory window. Address must be a +@@ -918,7 +918,7 @@ int t4_check_fw_version(struct adapter *adapter) + minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers); + micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers); + +- switch (CHELSIO_CHIP_VERSION(adapter->chip)) { ++ switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) { + case CHELSIO_T4: + exp_major = FW_VERSION_MAJOR; + exp_minor = FW_VERSION_MINOR; +@@ -931,7 +931,7 @@ int t4_check_fw_version(struct adapter *adapter) + break; + default: + dev_err(adapter->pdev_dev, "Unsupported chip type, %x\n", +- adapter->chip); ++ adapter->params.chip); + return -EINVAL; + } + +@@ -1368,7 +1368,7 @@ static void pcie_intr_handler(struct adapter *adapter) + PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, + pcie_port_intr_info) + + t4_handle_intr_status(adapter, PCIE_INT_CAUSE, +- is_t4(adapter->chip) ? ++ is_t4(adapter->params.chip) ? + pcie_intr_info : t5_pcie_intr_info); + + if (fat) +@@ -1782,7 +1782,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port) + { + u32 v, int_cause_reg; + +- if (is_t4(adap->chip)) ++ if (is_t4(adap->params.chip)) + int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE); + else + int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE); +@@ -2250,7 +2250,7 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) + + #define GET_STAT(name) \ + t4_read_reg64(adap, \ +- (is_t4(adap->chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \ ++ (is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \ + T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L))) + #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) + +@@ -2332,7 +2332,7 @@ void t4_wol_magic_enable(struct adapter *adap, unsigned int port, + { + u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg; + +- if (is_t4(adap->chip)) { ++ if (is_t4(adap->params.chip)) { + mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO); + mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI); + port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); +@@ -2374,7 +2374,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, + int i; + u32 port_cfg_reg; + +- if (is_t4(adap->chip)) ++ if (is_t4(adap->params.chip)) + port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); + else + port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2); +@@ -2387,7 +2387,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, + return -EINVAL; + + #define EPIO_REG(name) \ +- (is_t4(adap->chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \ ++ (is_t4(adap->params.chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \ + T5_PORT_REG(port, MAC_PORT_EPIO_##name)) + + t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); +@@ -2474,7 +2474,7 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, + int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len) + { + int i, off; +- u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); ++ u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn); + + /* Align on a 2KB boundary. + */ +@@ -3306,7 +3306,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, + int i, ret; + struct fw_vi_mac_cmd c; + struct fw_vi_mac_exact *p; +- unsigned int max_naddr = is_t4(adap->chip) ? ++ unsigned int max_naddr = is_t4(adap->params.chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + +@@ -3368,7 +3368,7 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, + int ret, mode; + struct fw_vi_mac_cmd c; + struct fw_vi_mac_exact *p = c.u.exact; +- unsigned int max_mac_addr = is_t4(adap->chip) ? ++ unsigned int max_mac_addr = is_t4(adap->params.chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + +@@ -3699,13 +3699,14 @@ int t4_prep_adapter(struct adapter *adapter) + { + int ret, ver; + uint16_t device_id; ++ u32 pl_rev; + + ret = t4_wait_dev_ready(adapter); + if (ret < 0) + return ret; + + get_pci_mode(adapter, &adapter->params.pci); +- adapter->params.rev = t4_read_reg(adapter, PL_REV); ++ pl_rev = G_REV(t4_read_reg(adapter, PL_REV)); + + ret = get_flash_params(adapter); + if (ret < 0) { +@@ -3717,14 +3718,13 @@ int t4_prep_adapter(struct adapter *adapter) + */ + pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id); + ver = device_id >> 12; ++ adapter->params.chip = 0; + switch (ver) { + case CHELSIO_T4: +- adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, +- adapter->params.rev); ++ adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev); + break; + case CHELSIO_T5: +- adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, +- adapter->params.rev); ++ adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev); + break; + default: + dev_err(adapter->pdev_dev, "Device %d is not supported\n", +@@ -3732,9 +3732,6 @@ int t4_prep_adapter(struct adapter *adapter) + return -EINVAL; + } + +- /* Reassign the updated revision field */ +- adapter->params.rev = adapter->chip; +- + init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); + + /* +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +index ef146c0..a7d8189 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +@@ -1092,6 +1092,11 @@ + + #define PL_REV 0x1943c + ++#define S_REV 0 ++#define M_REV 0xfU ++#define V_REV(x) ((x) << S_REV) ++#define G_REV(x) (((x) >> S_REV) & M_REV) ++ + #define LE_DB_CONFIG 0x19c04 + #define HASHEN 0x00100000U + +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0002-cxgb4-Add-new-scheme-to-update-T4-T5-firmware.patch b/linux-next-cherry-picks/0002-cxgb4-Add-new-scheme-to-update-T4-T5-firmware.patch new file mode 100644 index 0000000..c2214ab --- /dev/null +++ b/linux-next-cherry-picks/0002-cxgb4-Add-new-scheme-to-update-T4-T5-firmware.patch @@ -0,0 +1,690 @@ +From 16e47624e76b43dbef5671af7b9e26589d7018b9 Mon Sep 17 00:00:00 2001 +From: Hariprasad Shenai +Date: Tue, 3 Dec 2013 17:05:58 +0530 +Subject: [PATCH] cxgb4: Add new scheme to update T4/T5 firmware + +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 37 +++- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 242 ++++++++++++----------- + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 195 ++++++++++++------ + drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 7 +- + 4 files changed, 290 insertions(+), 191 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 9710a16..6c93088 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -49,13 +49,15 @@ + #include + #include "cxgb4_uld.h" + +-#define FW_VERSION_MAJOR 1 +-#define FW_VERSION_MINOR 4 +-#define FW_VERSION_MICRO 0 ++#define T4FW_VERSION_MAJOR 0x01 ++#define T4FW_VERSION_MINOR 0x06 ++#define T4FW_VERSION_MICRO 0x18 ++#define T4FW_VERSION_BUILD 0x00 + +-#define FW_VERSION_MAJOR_T5 0 +-#define FW_VERSION_MINOR_T5 0 +-#define FW_VERSION_MICRO_T5 0 ++#define T5FW_VERSION_MAJOR 0x01 ++#define T5FW_VERSION_MINOR 0x08 ++#define T5FW_VERSION_MICRO 0x1C ++#define T5FW_VERSION_BUILD 0x00 + + #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) + +@@ -287,6 +289,23 @@ struct adapter_params { + unsigned int ofldq_wr_cred; + }; + ++#include "t4fw_api.h" ++ ++#define FW_VERSION(chip) ( \ ++ FW_HDR_FW_VER_MAJOR_GET(chip##FW_VERSION_MAJOR) | \ ++ FW_HDR_FW_VER_MINOR_GET(chip##FW_VERSION_MINOR) | \ ++ FW_HDR_FW_VER_MICRO_GET(chip##FW_VERSION_MICRO) | \ ++ FW_HDR_FW_VER_BUILD_GET(chip##FW_VERSION_BUILD)) ++#define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf) ++ ++struct fw_info { ++ u8 chip; ++ char *fs_name; ++ char *fw_mod_name; ++ struct fw_hdr fw_hdr; ++}; ++ ++ + struct trace_params { + u32 data[TRACE_LEN / 4]; + u32 mask[TRACE_LEN / 4]; +@@ -901,7 +920,11 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p); + int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); + unsigned int t4_flash_cfg_addr(struct adapter *adapter); + int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size); +-int t4_check_fw_version(struct adapter *adapter); ++int t4_get_fw_version(struct adapter *adapter, u32 *vers); ++int t4_get_tp_version(struct adapter *adapter, u32 *vers); ++int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, ++ const u8 *fw_data, unsigned int fw_size, ++ struct fw_hdr *card_fw, enum dev_state state, int *reset); + int t4_prep_adapter(struct adapter *adapter); + int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); + void t4_fatal_err(struct adapter *adapter); +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index 35933cd..d6b12e0 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -276,9 +276,9 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { + { 0, } + }; + +-#define FW_FNAME "cxgb4/t4fw.bin" ++#define FW4_FNAME "cxgb4/t4fw.bin" + #define FW5_FNAME "cxgb4/t5fw.bin" +-#define FW_CFNAME "cxgb4/t4-config.txt" ++#define FW4_CFNAME "cxgb4/t4-config.txt" + #define FW5_CFNAME "cxgb4/t5-config.txt" + + MODULE_DESCRIPTION(DRV_DESC); +@@ -286,7 +286,7 @@ MODULE_AUTHOR("Chelsio Communications"); + MODULE_LICENSE("Dual BSD/GPL"); + MODULE_VERSION(DRV_VERSION); + MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); +-MODULE_FIRMWARE(FW_FNAME); ++MODULE_FIRMWARE(FW4_FNAME); + MODULE_FIRMWARE(FW5_FNAME); + + /* +@@ -1071,72 +1071,6 @@ freeout: t4_free_sge_resources(adap); + } + + /* +- * Returns 0 if new FW was successfully loaded, a positive errno if a load was +- * started but failed, and a negative errno if flash load couldn't start. +- */ +-static int upgrade_fw(struct adapter *adap) +-{ +- int ret; +- u32 vers, exp_major; +- const struct fw_hdr *hdr; +- const struct firmware *fw; +- struct device *dev = adap->pdev_dev; +- char *fw_file_name; +- +- switch (CHELSIO_CHIP_VERSION(adap->params.chip)) { +- case CHELSIO_T4: +- fw_file_name = FW_FNAME; +- exp_major = FW_VERSION_MAJOR; +- break; +- case CHELSIO_T5: +- fw_file_name = FW5_FNAME; +- exp_major = FW_VERSION_MAJOR_T5; +- break; +- default: +- dev_err(dev, "Unsupported chip type, %x\n", adap->params.chip); +- return -EINVAL; +- } +- +- ret = request_firmware(&fw, fw_file_name, dev); +- if (ret < 0) { +- dev_err(dev, "unable to load firmware image %s, error %d\n", +- fw_file_name, ret); +- return ret; +- } +- +- hdr = (const struct fw_hdr *)fw->data; +- vers = ntohl(hdr->fw_ver); +- if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) { +- ret = -EINVAL; /* wrong major version, won't do */ +- goto out; +- } +- +- /* +- * If the flash FW is unusable or we found something newer, load it. +- */ +- if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major || +- vers > adap->params.fw_vers) { +- dev_info(dev, "upgrading firmware ...\n"); +- ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size, +- /*force=*/false); +- if (!ret) +- dev_info(dev, +- "firmware upgraded to version %pI4 from %s\n", +- &hdr->fw_ver, fw_file_name); +- else +- dev_err(dev, "firmware upgrade failed! err=%d\n", -ret); +- } else { +- /* +- * Tell our caller that we didn't upgrade the firmware. +- */ +- ret = -EINVAL; +- } +- +-out: release_firmware(fw); +- return ret; +-} +- +-/* + * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. + * The allocated memory is cleared. + */ +@@ -4668,8 +4602,10 @@ static int adap_init0_config(struct adapter *adapter, int reset) + const struct firmware *cf; + unsigned long mtype = 0, maddr = 0; + u32 finiver, finicsum, cfcsum; +- int ret, using_flash; ++ int ret; ++ int config_issued = 0; + char *fw_config_file, fw_config_file_path[256]; ++ char *config_name = NULL; + + /* + * Reset device if necessary. +@@ -4688,7 +4624,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) + */ + switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) { + case CHELSIO_T4: +- fw_config_file = FW_CFNAME; ++ fw_config_file = FW4_CFNAME; + break; + case CHELSIO_T5: + fw_config_file = FW5_CFNAME; +@@ -4702,13 +4638,16 @@ static int adap_init0_config(struct adapter *adapter, int reset) + + ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev); + if (ret < 0) { +- using_flash = 1; ++ config_name = "On FLASH"; + mtype = FW_MEMTYPE_CF_FLASH; + maddr = t4_flash_cfg_addr(adapter); + } else { + u32 params[7], val[7]; + +- using_flash = 0; ++ sprintf(fw_config_file_path, ++ "/lib/firmware/%s", fw_config_file); ++ config_name = fw_config_file_path; ++ + if (cf->size >= FLASH_CFG_MAX_SIZE) + ret = -ENOMEM; + else { +@@ -4776,6 +4715,26 @@ static int adap_init0_config(struct adapter *adapter, int reset) + FW_LEN16(caps_cmd)); + ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), + &caps_cmd); ++ ++ /* If the CAPS_CONFIG failed with an ENOENT (for a Firmware ++ * Configuration File in FLASH), our last gasp effort is to use the ++ * Firmware Configuration File which is embedded in the firmware. A ++ * very few early versions of the firmware didn't have one embedded ++ * but we can ignore those. ++ */ ++ if (ret == -ENOENT) { ++ memset(&caps_cmd, 0, sizeof(caps_cmd)); ++ caps_cmd.op_to_write = ++ htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | ++ FW_CMD_REQUEST | ++ FW_CMD_READ); ++ caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); ++ ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, ++ sizeof(caps_cmd), &caps_cmd); ++ config_name = "Firmware Default"; ++ } ++ ++ config_issued = 1; + if (ret < 0) + goto bye; + +@@ -4816,7 +4775,6 @@ static int adap_init0_config(struct adapter *adapter, int reset) + if (ret < 0) + goto bye; + +- sprintf(fw_config_file_path, "/lib/firmware/%s", fw_config_file); + /* + * Return successfully and note that we're operating with parameters + * not supplied by the driver, rather than from hard-wired +@@ -4824,11 +4782,8 @@ static int adap_init0_config(struct adapter *adapter, int reset) + */ + adapter->flags |= USING_SOFT_PARAMS; + dev_info(adapter->pdev_dev, "Successfully configured using Firmware "\ +- "Configuration File %s, version %#x, computed checksum %#x\n", +- (using_flash +- ? "in device FLASH" +- : fw_config_file_path), +- finiver, cfcsum); ++ "Configuration File \"%s\", version %#x, computed checksum %#x\n", ++ config_name, finiver, cfcsum); + return 0; + + /* +@@ -4837,9 +4792,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) + * want to issue a warning since this is fairly common.) + */ + bye: +- if (ret != -ENOENT) +- dev_warn(adapter->pdev_dev, "Configuration file error %d\n", +- -ret); ++ if (config_issued && ret != -ENOENT) ++ dev_warn(adapter->pdev_dev, "\"%s\" configuration file error %d\n", ++ config_name, -ret); + return ret; + } + +@@ -5086,6 +5041,47 @@ bye: + return ret; + } + ++static struct fw_info fw_info_array[] = { ++ { ++ .chip = CHELSIO_T4, ++ .fs_name = FW4_CFNAME, ++ .fw_mod_name = FW4_FNAME, ++ .fw_hdr = { ++ .chip = FW_HDR_CHIP_T4, ++ .fw_ver = __cpu_to_be32(FW_VERSION(T4)), ++ .intfver_nic = FW_INTFVER(T4, NIC), ++ .intfver_vnic = FW_INTFVER(T4, VNIC), ++ .intfver_ri = FW_INTFVER(T4, RI), ++ .intfver_iscsi = FW_INTFVER(T4, ISCSI), ++ .intfver_fcoe = FW_INTFVER(T4, FCOE), ++ }, ++ }, { ++ .chip = CHELSIO_T5, ++ .fs_name = FW5_CFNAME, ++ .fw_mod_name = FW5_FNAME, ++ .fw_hdr = { ++ .chip = FW_HDR_CHIP_T5, ++ .fw_ver = __cpu_to_be32(FW_VERSION(T5)), ++ .intfver_nic = FW_INTFVER(T5, NIC), ++ .intfver_vnic = FW_INTFVER(T5, VNIC), ++ .intfver_ri = FW_INTFVER(T5, RI), ++ .intfver_iscsi = FW_INTFVER(T5, ISCSI), ++ .intfver_fcoe = FW_INTFVER(T5, FCOE), ++ }, ++ } ++}; ++ ++static struct fw_info *find_fw_info(int chip) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(fw_info_array); i++) { ++ if (fw_info_array[i].chip == chip) ++ return &fw_info_array[i]; ++ } ++ return NULL; ++} ++ + /* + * Phase 0 of initialization: contact FW, obtain config, perform basic init. + */ +@@ -5123,44 +5119,54 @@ static int adap_init0(struct adapter *adap) + * later reporting and B. to warn if the currently loaded firmware + * is excessively mismatched relative to the driver.) + */ +- ret = t4_check_fw_version(adap); +- +- /* The error code -EFAULT is returned by t4_check_fw_version() if +- * firmware on adapter < supported firmware. If firmware on adapter +- * is too old (not supported by driver) and we're the MASTER_PF set +- * adapter state to DEV_STATE_UNINIT to force firmware upgrade +- * and reinitialization. +- */ +- if ((adap->flags & MASTER_PF) && ret == -EFAULT) +- state = DEV_STATE_UNINIT; ++ t4_get_fw_version(adap, &adap->params.fw_vers); ++ t4_get_tp_version(adap, &adap->params.tp_vers); + if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) { +- if (ret == -EINVAL || ret == -EFAULT || ret > 0) { +- if (upgrade_fw(adap) >= 0) { +- /* +- * Note that the chip was reset as part of the +- * firmware upgrade so we don't reset it again +- * below and grab the new firmware version. +- */ +- reset = 0; +- ret = t4_check_fw_version(adap); +- } else +- if (ret == -EFAULT) { +- /* +- * Firmware is old but still might +- * work if we force reinitialization +- * of the adapter. Ignoring FW upgrade +- * failure. +- */ +- dev_warn(adap->pdev_dev, +- "Ignoring firmware upgrade " +- "failure, and forcing driver " +- "to reinitialize the " +- "adapter.\n"); +- ret = 0; +- } ++ struct fw_info *fw_info; ++ struct fw_hdr *card_fw; ++ const struct firmware *fw; ++ const u8 *fw_data = NULL; ++ unsigned int fw_size = 0; ++ ++ /* This is the firmware whose headers the driver was compiled ++ * against ++ */ ++ fw_info = find_fw_info(CHELSIO_CHIP_VERSION(adap->params.chip)); ++ if (fw_info == NULL) { ++ dev_err(adap->pdev_dev, ++ "unable to get firmware info for chip %d.\n", ++ CHELSIO_CHIP_VERSION(adap->params.chip)); ++ return -EINVAL; + } ++ ++ /* allocate memory to read the header of the firmware on the ++ * card ++ */ ++ card_fw = t4_alloc_mem(sizeof(*card_fw)); ++ ++ /* Get FW from from /lib/firmware/ */ ++ ret = request_firmware(&fw, fw_info->fw_mod_name, ++ adap->pdev_dev); ++ if (ret < 0) { ++ dev_err(adap->pdev_dev, ++ "unable to load firmware image %s, error %d\n", ++ fw_info->fw_mod_name, ret); ++ } else { ++ fw_data = fw->data; ++ fw_size = fw->size; ++ } ++ ++ /* upgrade FW logic */ ++ ret = t4_prep_fw(adap, fw_info, fw_data, fw_size, card_fw, ++ state, &reset); ++ ++ /* Cleaning up */ ++ if (fw != NULL) ++ release_firmware(fw); ++ t4_free_mem(card_fw); ++ + if (ret < 0) +- return ret; ++ goto bye; + } + + /* +@@ -5245,7 +5251,7 @@ static int adap_init0(struct adapter *adap) + if (ret == -ENOENT) { + dev_info(adap->pdev_dev, + "No Configuration File present " +- "on adapter. Using hard-wired " ++ "on adapter. Using hard-wired " + "configuration parameters.\n"); + ret = adap_init0_no_config(adap, reset); + } +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index 83b5e42..74a6fce 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -863,104 +863,169 @@ unlock: + } + + /** +- * get_fw_version - read the firmware version ++ * t4_get_fw_version - read the firmware version + * @adapter: the adapter + * @vers: where to place the version + * + * Reads the FW version from flash. + */ +-static int get_fw_version(struct adapter *adapter, u32 *vers) ++int t4_get_fw_version(struct adapter *adapter, u32 *vers) + { +- return t4_read_flash(adapter, adapter->params.sf_fw_start + +- offsetof(struct fw_hdr, fw_ver), 1, vers, 0); ++ return t4_read_flash(adapter, FLASH_FW_START + ++ offsetof(struct fw_hdr, fw_ver), 1, ++ vers, 0); + } + + /** +- * get_tp_version - read the TP microcode version ++ * t4_get_tp_version - read the TP microcode version + * @adapter: the adapter + * @vers: where to place the version + * + * Reads the TP microcode version from flash. + */ +-static int get_tp_version(struct adapter *adapter, u32 *vers) ++int t4_get_tp_version(struct adapter *adapter, u32 *vers) + { +- return t4_read_flash(adapter, adapter->params.sf_fw_start + ++ return t4_read_flash(adapter, FLASH_FW_START + + offsetof(struct fw_hdr, tp_microcode_ver), + 1, vers, 0); + } + +-/** +- * t4_check_fw_version - check if the FW is compatible with this driver +- * @adapter: the adapter +- * +- * Checks if an adapter's FW is compatible with the driver. Returns 0 +- * if there's exact match, a negative error if the version could not be +- * read or there's a major version mismatch, and a positive value if the +- * expected major version is found but there's a minor version mismatch. ++/* Is the given firmware API compatible with the one the driver was compiled ++ * with? + */ +-int t4_check_fw_version(struct adapter *adapter) ++static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2) + { +- u32 api_vers[2]; +- int ret, major, minor, micro; +- int exp_major, exp_minor, exp_micro; + +- ret = get_fw_version(adapter, &adapter->params.fw_vers); +- if (!ret) +- ret = get_tp_version(adapter, &adapter->params.tp_vers); +- if (!ret) +- ret = t4_read_flash(adapter, adapter->params.sf_fw_start + +- offsetof(struct fw_hdr, intfver_nic), +- 2, api_vers, 1); +- if (ret) +- return ret; ++ /* short circuit if it's the exact same firmware version */ ++ if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver) ++ return 1; + +- major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers); +- minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers); +- micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers); ++#define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x) ++ if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) && ++ SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe)) ++ return 1; ++#undef SAME_INTF + +- switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) { +- case CHELSIO_T4: +- exp_major = FW_VERSION_MAJOR; +- exp_minor = FW_VERSION_MINOR; +- exp_micro = FW_VERSION_MICRO; +- break; +- case CHELSIO_T5: +- exp_major = FW_VERSION_MAJOR_T5; +- exp_minor = FW_VERSION_MINOR_T5; +- exp_micro = FW_VERSION_MICRO_T5; +- break; +- default: +- dev_err(adapter->pdev_dev, "Unsupported chip type, %x\n", +- adapter->params.chip); +- return -EINVAL; +- } ++ return 0; ++} + +- memcpy(adapter->params.api_vers, api_vers, +- sizeof(adapter->params.api_vers)); ++/* The firmware in the filesystem is usable, but should it be installed? ++ * This routine explains itself in detail if it indicates the filesystem ++ * firmware should be installed. ++ */ ++static int should_install_fs_fw(struct adapter *adap, int card_fw_usable, ++ int k, int c) ++{ ++ const char *reason; + +- if (major < exp_major || (major == exp_major && minor < exp_minor) || +- (major == exp_major && minor == exp_minor && micro < exp_micro)) { +- dev_err(adapter->pdev_dev, +- "Card has firmware version %u.%u.%u, minimum " +- "supported firmware is %u.%u.%u.\n", major, minor, +- micro, exp_major, exp_minor, exp_micro); +- return -EFAULT; ++ if (!card_fw_usable) { ++ reason = "incompatible or unusable"; ++ goto install; + } + +- if (major != exp_major) { /* major mismatch - fail */ +- dev_err(adapter->pdev_dev, +- "card FW has major version %u, driver wants %u\n", +- major, exp_major); +- return -EINVAL; ++ if (k > c) { ++ reason = "older than the version supported with this driver"; ++ goto install; + } + +- if (minor == exp_minor && micro == exp_micro) +- return 0; /* perfect match */ ++ return 0; ++ ++install: ++ dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, " ++ "installing firmware %u.%u.%u.%u on card.\n", ++ FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), ++ FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), reason, ++ FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), ++ FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); + +- /* Minor/micro version mismatch. Report it but often it's OK. */ + return 1; + } + ++int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, ++ const u8 *fw_data, unsigned int fw_size, ++ struct fw_hdr *card_fw, enum dev_state state, ++ int *reset) ++{ ++ int ret, card_fw_usable, fs_fw_usable; ++ const struct fw_hdr *fs_fw; ++ const struct fw_hdr *drv_fw; ++ ++ drv_fw = &fw_info->fw_hdr; ++ ++ /* Read the header of the firmware on the card */ ++ ret = -t4_read_flash(adap, FLASH_FW_START, ++ sizeof(*card_fw) / sizeof(uint32_t), ++ (uint32_t *)card_fw, 1); ++ if (ret == 0) { ++ card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw); ++ } else { ++ dev_err(adap->pdev_dev, ++ "Unable to read card's firmware header: %d\n", ret); ++ card_fw_usable = 0; ++ } ++ ++ if (fw_data != NULL) { ++ fs_fw = (const void *)fw_data; ++ fs_fw_usable = fw_compatible(drv_fw, fs_fw); ++ } else { ++ fs_fw = NULL; ++ fs_fw_usable = 0; ++ } ++ ++ if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver && ++ (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) { ++ /* Common case: the firmware on the card is an exact match and ++ * the filesystem one is an exact match too, or the filesystem ++ * one is absent/incompatible. ++ */ ++ } else if (fs_fw_usable && state == DEV_STATE_UNINIT && ++ should_install_fs_fw(adap, card_fw_usable, ++ be32_to_cpu(fs_fw->fw_ver), ++ be32_to_cpu(card_fw->fw_ver))) { ++ ret = -t4_fw_upgrade(adap, adap->mbox, fw_data, ++ fw_size, 0); ++ if (ret != 0) { ++ dev_err(adap->pdev_dev, ++ "failed to install firmware: %d\n", ret); ++ goto bye; ++ } ++ ++ /* Installed successfully, update the cached header too. */ ++ memcpy(card_fw, fs_fw, sizeof(*card_fw)); ++ card_fw_usable = 1; ++ *reset = 0; /* already reset as part of load_fw */ ++ } ++ ++ if (!card_fw_usable) { ++ uint32_t d, c, k; ++ ++ d = be32_to_cpu(drv_fw->fw_ver); ++ c = be32_to_cpu(card_fw->fw_ver); ++ k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0; ++ ++ dev_err(adap->pdev_dev, "Cannot find a usable firmware: " ++ "chip state %d, " ++ "driver compiled with %d.%d.%d.%d, " ++ "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n", ++ state, ++ FW_HDR_FW_VER_MAJOR_GET(d), FW_HDR_FW_VER_MINOR_GET(d), ++ FW_HDR_FW_VER_MICRO_GET(d), FW_HDR_FW_VER_BUILD_GET(d), ++ FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), ++ FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), ++ FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), ++ FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); ++ ret = EINVAL; ++ goto bye; ++ } ++ ++ /* We're using whatever's on the card and it's known to be good. */ ++ adap->params.fw_vers = be32_to_cpu(card_fw->fw_ver); ++ adap->params.tp_vers = be32_to_cpu(card_fw->tp_microcode_ver); ++ ++bye: ++ return ret; ++} ++ + /** + * t4_flash_erase_sectors - erase a range of flash sectors + * @adapter: the adapter +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +index 6f77ac4..74fea74 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +@@ -2157,7 +2157,7 @@ struct fw_debug_cmd { + + struct fw_hdr { + u8 ver; +- u8 reserved1; ++ u8 chip; /* terminator chip type */ + __be16 len512; /* bin length in units of 512-bytes */ + __be32 fw_ver; /* firmware version */ + __be32 tp_microcode_ver; +@@ -2176,6 +2176,11 @@ struct fw_hdr { + __be32 reserved6[23]; + }; + ++enum fw_hdr_chip { ++ FW_HDR_CHIP_T4, ++ FW_HDR_CHIP_T5 ++}; ++ + #define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff) + #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) + #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0003-cxgb4-Reserve-stid-0-for-T4-T5-adapters.patch b/linux-next-cherry-picks/0003-cxgb4-Reserve-stid-0-for-T4-T5-adapters.patch new file mode 100644 index 0000000..7899828 --- /dev/null +++ b/linux-next-cherry-picks/0003-cxgb4-Reserve-stid-0-for-T4-T5-adapters.patch @@ -0,0 +1,49 @@ +From b6f8eaece6d5f0247931b6dac140e6cf876f48de Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:19 +0530 +Subject: [PATCH] cxgb4: Reserve stid 0 for T4/T5 adapters + +When creating offload server entries, an IPv6 passive connection request +can trigger a reply with a null STID, whereas the driver would expect +the reply 'STID to match the value used for the request. +This happens due to h/w limitation on T4 and T5. + +This patch ensures that STID 0 is never used if the stid range starts +from zero. + +Based on original work by Santosh Rastapur + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index d6b12e0..f36f8e1 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -3134,6 +3134,7 @@ static int tid_init(struct tid_info *t) + size_t size; + unsigned int stid_bmap_size; + unsigned int natids = t->natids; ++ struct adapter *adap = container_of(t, struct adapter, tids); + + stid_bmap_size = BITS_TO_LONGS(t->nstids + t->nsftids); + size = t->ntids * sizeof(*t->tid_tab) + +@@ -3167,6 +3168,11 @@ static int tid_init(struct tid_info *t) + t->afree = t->atid_tab; + } + bitmap_zero(t->stid_bmap, t->nstids + t->nsftids); ++ /* Reserve stid 0 for T4/T5 adapters */ ++ if (!t->stid_base && ++ (is_t4(adap->params.chip) || is_t5(adap->params.chip))) ++ __set_bit(0, t->stid_bmap); ++ + return 0; + } + +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0004-cxgb4-Include-TCP-as-protocol-when-creating-server-f.patch b/linux-next-cherry-picks/0004-cxgb4-Include-TCP-as-protocol-when-creating-server-f.patch new file mode 100644 index 0000000..157f06f --- /dev/null +++ b/linux-next-cherry-picks/0004-cxgb4-Include-TCP-as-protocol-when-creating-server-f.patch @@ -0,0 +1,55 @@ +From 7c89e5550ccb2a3118854639d9525847e896c686 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:20 +0530 +Subject: [PATCH] cxgb4: Include TCP as protocol when creating server filters + +We were creating LE Workaround Server Filters without specifying +IPPROTO_TCP (6) in the filters (when F_PROTOCOL is set in TP_VLAN_PRI_MAP). +This meant that UDP packets with matching IP Addresses/Ports would get +caught up in the filter and be delivered to ULDs like iw_cxgb4. +So, include the protocol information in the server filter properly. + +Based on original work by Casey Leedom + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 5 +++++ + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 4 ++++ + 2 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index f36f8e1..df1d6b8 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -4217,6 +4217,11 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, + } + } + ++ if (adap->filter_mode & F_PROTOCOL) { ++ f->fs.val.proto = IPPROTO_TCP; ++ f->fs.mask.proto = ~0; ++ } ++ + f->fs.dirsteer = 1; + f->fs.iq = queue; + /* Mark filter as locked */ +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +index 0a8205d..d3dd218 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +@@ -1171,6 +1171,10 @@ + + #define A_TP_TX_SCHED_PCMD 0x25 + ++#define S_PROTOCOL 5 ++#define V_PROTOCOL(x) ((x) << S_PROTOCOL) ++#define F_PROTOCOL V_PROTOCOL(1U) ++ + #define S_PORT 1 + #define V_PORT(x) ((x) << S_PORT) + #define F_PORT V_PORT(1U) +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0005-cxgb4-Assign-filter-server-TIDS-Account-for-stid.patch b/linux-next-cherry-picks/0005-cxgb4-Assign-filter-server-TIDS-Account-for-stid.patch new file mode 100644 index 0000000..0878418 --- /dev/null +++ b/linux-next-cherry-picks/0005-cxgb4-Assign-filter-server-TIDS-Account-for-stid.patch @@ -0,0 +1,95 @@ +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index 951787f..94a6e62 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -3073,7 +3073,14 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data) + if (stid >= 0) { + t->stid_tab[stid].data = data; + stid += t->stid_base; +- t->stids_in_use++; ++ /* IPv6 requires max of 520 bits or 16 cells in TCAM ++ * This is equivalent to 4 TIDs. With CLIP enabled it ++ * needs 2 TIDs. ++ */ ++ if (family == PF_INET) ++ t->stids_in_use++; ++ else ++ t->stids_in_use += 4; + } + spin_unlock_bh(&t->stid_lock); + return stid; +@@ -3099,7 +3106,8 @@ int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data) + } + if (stid >= 0) { + t->stid_tab[stid].data = data; +- stid += t->stid_base; ++ stid -= t->nstids; ++ stid += t->sftid_base; + t->stids_in_use++; + } + spin_unlock_bh(&t->stid_lock); +@@ -3111,14 +3119,24 @@ EXPORT_SYMBOL(cxgb4_alloc_sftid); + */ + void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) + { +- stid -= t->stid_base; ++ /* Is it a server filter TID? */ ++ if (t->nsftids && (stid >= t->sftid_base)) { ++ stid -= t->sftid_base; ++ stid += t->nstids; ++ } else { ++ stid -= t->stid_base; ++ } ++ + spin_lock_bh(&t->stid_lock); + if (family == PF_INET) + __clear_bit(stid, t->stid_bmap); + else + bitmap_release_region(t->stid_bmap, stid, 2); + t->stid_tab[stid].data = NULL; +- t->stids_in_use--; ++ if (family == PF_INET) ++ t->stids_in_use--; ++ else ++ t->stids_in_use -= 4; + spin_unlock_bh(&t->stid_lock); + } + EXPORT_SYMBOL(cxgb4_free_stid); +@@ -4262,7 +4280,7 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, + adap = netdev2adap(dev); + + /* Adjust stid to correct filter index */ +- stid -= adap->tids.nstids; ++ stid -= adap->tids.sftid_base; + stid += adap->tids.nftids; + + /* Check to make sure the filter requested is writable ... +@@ -4325,7 +4343,7 @@ int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid, + adap = netdev2adap(dev); + + /* Adjust stid to correct filter index */ +- stid -= adap->tids.nstids; ++ stid -= adap->tids.sftid_base; + stid += adap->tids.nftids; + + f = &adap->tids.ftid_tab[stid]; +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +index 6f21f24..4dd0a82 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +@@ -131,7 +131,14 @@ static inline void *lookup_atid(const struct tid_info *t, unsigned int atid) + + static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) + { +- stid -= t->stid_base; ++ /* Is it a server filter TID? */ ++ if (t->nsftids && (stid >= t->sftid_base)) { ++ stid -= t->sftid_base; ++ stid += t->nstids; ++ } else { ++ stid -= t->stid_base; ++ } ++ + return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL; + } + diff --git a/linux-next-cherry-picks/0006-cxgb4-Add-API-to-correctly-calculate-tuple-fields.patch b/linux-next-cherry-picks/0006-cxgb4-Add-API-to-correctly-calculate-tuple-fields.patch new file mode 100644 index 0000000..cb647d0 --- /dev/null +++ b/linux-next-cherry-picks/0006-cxgb4-Add-API-to-correctly-calculate-tuple-fields.patch @@ -0,0 +1,405 @@ +From dcf7b6f5bdeaa13d5e465d8795d2e7d6d1e27b65 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:23 +0530 +Subject: [PATCH] cxgb4: Add API to correctly calculate tuple fields + +Adds API cxgb4_select_ntuple so as to enable Upper Level Drivers to correctly +calculate the tuple fields. + +Adds constant definitions for TP_VLAN_PRI_MAP for the Compressed +Filter Tuple field widths and structures and uses them. + +Also, the CPL Parameters field for T5 is 40 bits so we need to prototype +cxgb4_select_ntuple() to calculate and return u64 values. + +Based on original work by Casey Leedom + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 21 +++++ + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 20 +---- + drivers/net/ethernet/chelsio/cxgb4/l2t.c | 35 ++++++++ + drivers/net/ethernet/chelsio/cxgb4/l2t.h | 3 +- + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 103 +++++++++++++++++++++++ + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 69 +++++++++++++++ + 6 files changed, 235 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 6c93088..56e0415 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -228,6 +228,25 @@ struct tp_params { + + uint32_t dack_re; /* DACK timer resolution */ + unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ ++ ++ u32 vlan_pri_map; /* cached TP_VLAN_PRI_MAP */ ++ u32 ingress_config; /* cached TP_INGRESS_CONFIG */ ++ ++ /* TP_VLAN_PRI_MAP Compressed Filter Tuple field offsets. This is a ++ * subset of the set of fields which may be present in the Compressed ++ * Filter Tuple portion of filters and TCP TCB connections. The ++ * fields which are present are controlled by the TP_VLAN_PRI_MAP. ++ * Since a variable number of fields may or may not be present, their ++ * shifted field positions within the Compressed Filter Tuple may ++ * vary, or not even be present if the field isn't selected in ++ * TP_VLAN_PRI_MAP. Since some of these fields are needed in various ++ * places we store their offsets here, or a -1 if the field isn't ++ * present. ++ */ ++ int vlan_shift; ++ int vnic_shift; ++ int port_shift; ++ int protocol_shift; + }; + + struct vpd_params { +@@ -926,6 +945,8 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, + const u8 *fw_data, unsigned int fw_size, + struct fw_hdr *card_fw, enum dev_state state, int *reset); + int t4_prep_adapter(struct adapter *adapter); ++int t4_init_tp_params(struct adapter *adap); ++int t4_filter_field_shift(const struct adapter *adap, int filter_sel); + int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); + void t4_fatal_err(struct adapter *adapter); + int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index f9ca36c..fff02ed 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -3755,7 +3755,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) + lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( + t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> + (adap->fn * 4)); +- lli.filt_mode = adap->filter_mode; ++ lli.filt_mode = adap->params.tp.vlan_pri_map; + /* MODQ_REQ_MAP sets queues 0-3 to chan 0-3 */ + for (i = 0; i < NCHAN; i++) + lli.tx_modq[i] = i; +@@ -4229,13 +4229,13 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, + f->fs.val.lip[i] = val[i]; + f->fs.mask.lip[i] = ~0; + } +- if (adap->filter_mode & F_PORT) { ++ if (adap->params.tp.vlan_pri_map & F_PORT) { + f->fs.val.iport = port; + f->fs.mask.iport = mask; + } + } + +- if (adap->filter_mode & F_PROTOCOL) { ++ if (adap->params.tp.vlan_pri_map & F_PROTOCOL) { + f->fs.val.proto = IPPROTO_TCP; + f->fs.mask.proto = ~0; + } +@@ -5121,7 +5121,7 @@ static int adap_init0(struct adapter *adap) + enum dev_state state; + u32 params[7], val[7]; + struct fw_caps_config_cmd caps_cmd; +- int reset = 1, j; ++ int reset = 1; + + /* + * Contact FW, advertising Master capability (and potentially forcing +@@ -5463,21 +5463,11 @@ static int adap_init0(struct adapter *adap) + /* + * These are finalized by FW initialization, load their values now. + */ +- v = t4_read_reg(adap, TP_TIMER_RESOLUTION); +- adap->params.tp.tre = TIMERRESOLUTION_GET(v); +- adap->params.tp.dack_re = DELAYEDACKRESOLUTION_GET(v); + t4_read_mtu_tbl(adap, adap->params.mtus, NULL); + t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, + adap->params.b_wnd); + +- /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */ +- for (j = 0; j < NCHAN; j++) +- adap->params.tp.tx_modq[j] = j; +- +- t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, +- &adap->filter_mode, 1, +- TP_VLAN_PRI_MAP); +- ++ t4_init_tp_params(adap); + adap->flags |= FW_OK; + return 0; + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c +index 2987809..cb05be9 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c +@@ -45,6 +45,7 @@ + #include "l2t.h" + #include "t4_msg.h" + #include "t4fw_api.h" ++#include "t4_regs.h" + + #define VLAN_NONE 0xfff + +@@ -411,6 +412,40 @@ done: + } + EXPORT_SYMBOL(cxgb4_l2t_get); + ++u64 cxgb4_select_ntuple(struct net_device *dev, ++ const struct l2t_entry *l2t) ++{ ++ struct adapter *adap = netdev2adap(dev); ++ struct tp_params *tp = &adap->params.tp; ++ u64 ntuple = 0; ++ ++ /* Initialize each of the fields which we care about which are present ++ * in the Compressed Filter Tuple. ++ */ ++ if (tp->vlan_shift >= 0 && l2t->vlan != VLAN_NONE) ++ ntuple |= (F_FT_VLAN_VLD | l2t->vlan) << tp->vlan_shift; ++ ++ if (tp->port_shift >= 0) ++ ntuple |= (u64)l2t->lport << tp->port_shift; ++ ++ if (tp->protocol_shift >= 0) ++ ntuple |= (u64)IPPROTO_TCP << tp->protocol_shift; ++ ++ if (tp->vnic_shift >= 0) { ++ u32 viid = cxgb4_port_viid(dev); ++ u32 vf = FW_VIID_VIN_GET(viid); ++ u32 pf = FW_VIID_PFN_GET(viid); ++ u32 vld = FW_VIID_VIVLD_GET(viid); ++ ++ ntuple |= (u64)(V_FT_VNID_ID_VF(vf) | ++ V_FT_VNID_ID_PF(pf) | ++ V_FT_VNID_ID_VLD(vld)) << tp->vnic_shift; ++ } ++ ++ return ntuple; ++} ++EXPORT_SYMBOL(cxgb4_select_ntuple); ++ + /* + * Called when address resolution fails for an L2T entry to handle packets + * on the arpq head. If a packet specifies a failure handler it is invoked, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.h b/drivers/net/ethernet/chelsio/cxgb4/l2t.h +index 108c0f1..85eb5c7 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.h +@@ -98,7 +98,8 @@ int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb, + struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, + const struct net_device *physdev, + unsigned int priority); +- ++u64 cxgb4_select_ntuple(struct net_device *dev, ++ const struct l2t_entry *l2t); + void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); + struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d); + int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index 74a6fce..e1413ea 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -3808,6 +3808,109 @@ int t4_prep_adapter(struct adapter *adapter) + return 0; + } + ++/** ++ * t4_init_tp_params - initialize adap->params.tp ++ * @adap: the adapter ++ * ++ * Initialize various fields of the adapter's TP Parameters structure. ++ */ ++int t4_init_tp_params(struct adapter *adap) ++{ ++ int chan; ++ u32 v; ++ ++ v = t4_read_reg(adap, TP_TIMER_RESOLUTION); ++ adap->params.tp.tre = TIMERRESOLUTION_GET(v); ++ adap->params.tp.dack_re = DELAYEDACKRESOLUTION_GET(v); ++ ++ /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */ ++ for (chan = 0; chan < NCHAN; chan++) ++ adap->params.tp.tx_modq[chan] = chan; ++ ++ /* Cache the adapter's Compressed Filter Mode and global Incress ++ * Configuration. ++ */ ++ t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, ++ &adap->params.tp.vlan_pri_map, 1, ++ TP_VLAN_PRI_MAP); ++ t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA, ++ &adap->params.tp.ingress_config, 1, ++ TP_INGRESS_CONFIG); ++ ++ /* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field ++ * shift positions of several elements of the Compressed Filter Tuple ++ * for this adapter which we need frequently ... ++ */ ++ adap->params.tp.vlan_shift = t4_filter_field_shift(adap, F_VLAN); ++ adap->params.tp.vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID); ++ adap->params.tp.port_shift = t4_filter_field_shift(adap, F_PORT); ++ adap->params.tp.protocol_shift = t4_filter_field_shift(adap, ++ F_PROTOCOL); ++ ++ /* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID ++ * represents the presense of an Outer VLAN instead of a VNIC ID. ++ */ ++ if ((adap->params.tp.ingress_config & F_VNIC) == 0) ++ adap->params.tp.vnic_shift = -1; ++ ++ return 0; ++} ++ ++/** ++ * t4_filter_field_shift - calculate filter field shift ++ * @adap: the adapter ++ * @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits) ++ * ++ * Return the shift position of a filter field within the Compressed ++ * Filter Tuple. The filter field is specified via its selection bit ++ * within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN. ++ */ ++int t4_filter_field_shift(const struct adapter *adap, int filter_sel) ++{ ++ unsigned int filter_mode = adap->params.tp.vlan_pri_map; ++ unsigned int sel; ++ int field_shift; ++ ++ if ((filter_mode & filter_sel) == 0) ++ return -1; ++ ++ for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) { ++ switch (filter_mode & sel) { ++ case F_FCOE: ++ field_shift += W_FT_FCOE; ++ break; ++ case F_PORT: ++ field_shift += W_FT_PORT; ++ break; ++ case F_VNIC_ID: ++ field_shift += W_FT_VNIC_ID; ++ break; ++ case F_VLAN: ++ field_shift += W_FT_VLAN; ++ break; ++ case F_TOS: ++ field_shift += W_FT_TOS; ++ break; ++ case F_PROTOCOL: ++ field_shift += W_FT_PROTOCOL; ++ break; ++ case F_ETHERTYPE: ++ field_shift += W_FT_ETHERTYPE; ++ break; ++ case F_MACMATCH: ++ field_shift += W_FT_MACMATCH; ++ break; ++ case F_MPSHITTYPE: ++ field_shift += W_FT_MPSHITTYPE; ++ break; ++ case F_FRAGMENTATION: ++ field_shift += W_FT_FRAGMENTATION; ++ break; ++ } ++ } ++ return field_shift; ++} ++ + int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) + { + u8 addr[6]; +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +index d3dd218..4082522 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +@@ -1171,14 +1171,50 @@ + + #define A_TP_TX_SCHED_PCMD 0x25 + ++#define S_VNIC 11 ++#define V_VNIC(x) ((x) << S_VNIC) ++#define F_VNIC V_VNIC(1U) ++ ++#define S_FRAGMENTATION 9 ++#define V_FRAGMENTATION(x) ((x) << S_FRAGMENTATION) ++#define F_FRAGMENTATION V_FRAGMENTATION(1U) ++ ++#define S_MPSHITTYPE 8 ++#define V_MPSHITTYPE(x) ((x) << S_MPSHITTYPE) ++#define F_MPSHITTYPE V_MPSHITTYPE(1U) ++ ++#define S_MACMATCH 7 ++#define V_MACMATCH(x) ((x) << S_MACMATCH) ++#define F_MACMATCH V_MACMATCH(1U) ++ ++#define S_ETHERTYPE 6 ++#define V_ETHERTYPE(x) ((x) << S_ETHERTYPE) ++#define F_ETHERTYPE V_ETHERTYPE(1U) ++ + #define S_PROTOCOL 5 + #define V_PROTOCOL(x) ((x) << S_PROTOCOL) + #define F_PROTOCOL V_PROTOCOL(1U) + ++#define S_TOS 4 ++#define V_TOS(x) ((x) << S_TOS) ++#define F_TOS V_TOS(1U) ++ ++#define S_VLAN 3 ++#define V_VLAN(x) ((x) << S_VLAN) ++#define F_VLAN V_VLAN(1U) ++ ++#define S_VNIC_ID 2 ++#define V_VNIC_ID(x) ((x) << S_VNIC_ID) ++#define F_VNIC_ID V_VNIC_ID(1U) ++ + #define S_PORT 1 + #define V_PORT(x) ((x) << S_PORT) + #define F_PORT V_PORT(1U) + ++#define S_FCOE 0 ++#define V_FCOE(x) ((x) << S_FCOE) ++#define F_FCOE V_FCOE(1U) ++ + #define NUM_MPS_CLS_SRAM_L_INSTANCES 336 + #define NUM_MPS_T5_CLS_SRAM_L_INSTANCES 512 + +@@ -1217,4 +1253,37 @@ + #define V_CHIPID(x) ((x) << S_CHIPID) + #define G_CHIPID(x) (((x) >> S_CHIPID) & M_CHIPID) + ++/* TP_VLAN_PRI_MAP controls which subset of fields will be present in the ++ * Compressed Filter Tuple for LE filters. Each bit set in TP_VLAN_PRI_MAP ++ * selects for a particular field being present. These fields, when present ++ * in the Compressed Filter Tuple, have the following widths in bits. ++ */ ++#define W_FT_FCOE 1 ++#define W_FT_PORT 3 ++#define W_FT_VNIC_ID 17 ++#define W_FT_VLAN 17 ++#define W_FT_TOS 8 ++#define W_FT_PROTOCOL 8 ++#define W_FT_ETHERTYPE 16 ++#define W_FT_MACMATCH 9 ++#define W_FT_MPSHITTYPE 3 ++#define W_FT_FRAGMENTATION 1 ++ ++/* Some of the Compressed Filter Tuple fields have internal structure. These ++ * bit shifts/masks describe those structures. All shifts are relative to the ++ * base position of the fields within the Compressed Filter Tuple ++ */ ++#define S_FT_VLAN_VLD 16 ++#define V_FT_VLAN_VLD(x) ((x) << S_FT_VLAN_VLD) ++#define F_FT_VLAN_VLD V_FT_VLAN_VLD(1U) ++ ++#define S_FT_VNID_ID_VF 0 ++#define V_FT_VNID_ID_VF(x) ((x) << S_FT_VNID_ID_VF) ++ ++#define S_FT_VNID_ID_PF 7 ++#define V_FT_VNID_ID_PF(x) ((x) << S_FT_VNID_ID_PF) ++ ++#define S_FT_VNID_ID_VLD 16 ++#define V_FT_VNID_ID_VLD(x) ((x) << S_FT_VNID_ID_VLD) ++ + #endif /* __T4_REGS_H */ +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0007-RDMA-cxgb4-Calculate-the-filter-server-TID-properly.patch b/linux-next-cherry-picks/0007-RDMA-cxgb4-Calculate-the-filter-server-TID-properly.patch new file mode 100644 index 0000000..a6ef058 --- /dev/null +++ b/linux-next-cherry-picks/0007-RDMA-cxgb4-Calculate-the-filter-server-TID-properly.patch @@ -0,0 +1,32 @@ +From a4ea025fc24532bae8a038d038f8e0f15b8a7d98 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:24 +0530 +Subject: [PATCH] RDMA/cxgb4: Calculate the filter server TID properly + +Based on original work by Santosh Rastapur + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/infiniband/hw/cxgb4/cm.c | 4 +--- + 1 files changed, 1 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 12fef76..02c7515 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -3323,9 +3323,7 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) + /* + * Calculate the server tid from filter hit index from cpl_rx_pkt. + */ +- stid = (__force int) cpu_to_be32((__force u32) rss->hash_val) +- - dev->rdev.lldi.tids->sftid_base +- + dev->rdev.lldi.tids->nstids; ++ stid = (__force int) cpu_to_be32((__force u32) rss->hash_val); + + lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid); + if (!lep) { +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0008-RDMA-cxgb4-Server-filters-are-supported-only-for-IPv.patch b/linux-next-cherry-picks/0008-RDMA-cxgb4-Server-filters-are-supported-only-for-IPv.patch new file mode 100644 index 0000000..2591671 --- /dev/null +++ b/linux-next-cherry-picks/0008-RDMA-cxgb4-Server-filters-are-supported-only-for-IPv.patch @@ -0,0 +1,29 @@ +From 8c04469057c3307d92d2c7076edcf9eb8f752bca Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:25 +0530 +Subject: [PATCH] RDMA/cxgb4: Server filters are supported only for IPv4 + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/infiniband/hw/cxgb4/cm.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 02c7515..bfd4ed7 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -2938,7 +2938,8 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) + /* + * Allocate a server TID. + */ +- if (dev->rdev.lldi.enable_fw_ofld_conn) ++ if (dev->rdev.lldi.enable_fw_ofld_conn && ++ ep->com.local_addr.ss_family == AF_INET) + ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids, + cm_id->local_addr.ss_family, ep); + else +-- +1.7.1 + diff --git a/linux-next-cherry-picks/0009-RDMA-cxgb4-Use-cxgb4_select_ntuple-to-correctly-calc.patch b/linux-next-cherry-picks/0009-RDMA-cxgb4-Use-cxgb4_select_ntuple-to-correctly-calc.patch new file mode 100644 index 0000000..ba1a27b --- /dev/null +++ b/linux-next-cherry-picks/0009-RDMA-cxgb4-Use-cxgb4_select_ntuple-to-correctly-calc.patch @@ -0,0 +1,139 @@ +From 41b4f86c1368758a02129e0629a9cc7c2811fa32 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Wed, 18 Dec 2013 16:38:26 +0530 +Subject: [PATCH] RDMA/cxgb4: Use cxgb4_select_ntuple to correctly calculate ntuple fields + +Signed-off-by: Kumar Sanghvi +Signed-off-by: Hariprasad Shenai +Signed-off-by: David S. Miller +--- + drivers/infiniband/hw/cxgb4/cm.c | 71 +++++++++----------------------------- + 1 files changed, 17 insertions(+), 54 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index bfd4ed7..4512687 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -524,50 +524,6 @@ static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) + return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); + } + +-#define VLAN_NONE 0xfff +-#define FILTER_SEL_VLAN_NONE 0xffff +-#define FILTER_SEL_WIDTH_P_FC (3+1) /* port uses 3 bits, FCoE one bit */ +-#define FILTER_SEL_WIDTH_VIN_P_FC \ +- (6 + 7 + FILTER_SEL_WIDTH_P_FC) /* 6 bits are unused, VF uses 7 bits*/ +-#define FILTER_SEL_WIDTH_TAG_P_FC \ +- (3 + FILTER_SEL_WIDTH_VIN_P_FC) /* PF uses 3 bits */ +-#define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC) +- +-static unsigned int select_ntuple(struct c4iw_dev *dev, struct dst_entry *dst, +- struct l2t_entry *l2t) +-{ +- unsigned int ntuple = 0; +- u32 viid; +- +- switch (dev->rdev.lldi.filt_mode) { +- +- /* default filter mode */ +- case HW_TPL_FR_MT_PR_IV_P_FC: +- if (l2t->vlan == VLAN_NONE) +- ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC; +- else { +- ntuple |= l2t->vlan << FILTER_SEL_WIDTH_P_FC; +- ntuple |= 1 << FILTER_SEL_WIDTH_TAG_P_FC; +- } +- ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << +- FILTER_SEL_WIDTH_VLD_TAG_P_FC; +- break; +- case HW_TPL_FR_MT_PR_OV_P_FC: { +- viid = cxgb4_port_viid(l2t->neigh->dev); +- +- ntuple |= FW_VIID_VIN_GET(viid) << FILTER_SEL_WIDTH_P_FC; +- ntuple |= FW_VIID_PFN_GET(viid) << FILTER_SEL_WIDTH_VIN_P_FC; +- ntuple |= FW_VIID_VIVLD_GET(viid) << FILTER_SEL_WIDTH_TAG_P_FC; +- ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << +- FILTER_SEL_WIDTH_VLD_TAG_P_FC; +- break; +- } +- default: +- break; +- } +- return ntuple; +-} +- + static int send_connect(struct c4iw_ep *ep) + { + struct cpl_act_open_req *req; +@@ -641,8 +597,9 @@ static int send_connect(struct c4iw_ep *ep) + req->local_ip = la->sin_addr.s_addr; + req->peer_ip = ra->sin_addr.s_addr; + req->opt0 = cpu_to_be64(opt0); +- req->params = cpu_to_be32(select_ntuple(ep->com.dev, +- ep->dst, ep->l2t)); ++ req->params = cpu_to_be32(cxgb4_select_ntuple( ++ ep->com.dev->rdev.lldi.ports[0], ++ ep->l2t)); + req->opt2 = cpu_to_be32(opt2); + } else { + req6 = (struct cpl_act_open_req6 *)skb_put(skb, wrlen); +@@ -662,9 +619,9 @@ static int send_connect(struct c4iw_ep *ep) + req6->peer_ip_lo = *((__be64 *) + (ra6->sin6_addr.s6_addr + 8)); + req6->opt0 = cpu_to_be64(opt0); +- req6->params = cpu_to_be32( +- select_ntuple(ep->com.dev, ep->dst, +- ep->l2t)); ++ req6->params = cpu_to_be32(cxgb4_select_ntuple( ++ ep->com.dev->rdev.lldi.ports[0], ++ ep->l2t)); + req6->opt2 = cpu_to_be32(opt2); + } + } else { +@@ -681,8 +638,9 @@ static int send_connect(struct c4iw_ep *ep) + t5_req->peer_ip = ra->sin_addr.s_addr; + t5_req->opt0 = cpu_to_be64(opt0); + t5_req->params = cpu_to_be64(V_FILTER_TUPLE( +- select_ntuple(ep->com.dev, +- ep->dst, ep->l2t))); ++ cxgb4_select_ntuple( ++ ep->com.dev->rdev.lldi.ports[0], ++ ep->l2t))); + t5_req->opt2 = cpu_to_be32(opt2); + } else { + t5_req6 = (struct cpl_t5_act_open_req6 *) +@@ -703,7 +661,9 @@ static int send_connect(struct c4iw_ep *ep) + (ra6->sin6_addr.s6_addr + 8)); + t5_req6->opt0 = cpu_to_be64(opt0); + t5_req6->params = (__force __be64)cpu_to_be32( +- select_ntuple(ep->com.dev, ep->dst, ep->l2t)); ++ cxgb4_select_ntuple( ++ ep->com.dev->rdev.lldi.ports[0], ++ ep->l2t)); + t5_req6->opt2 = cpu_to_be32(opt2); + } + } +@@ -1630,7 +1590,8 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) + memset(req, 0, sizeof(*req)); + req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR)); + req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16))); +- req->le.filter = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, ++ req->le.filter = cpu_to_be32(cxgb4_select_ntuple( ++ ep->com.dev->rdev.lldi.ports[0], + ep->l2t)); + sin = (struct sockaddr_in *)&ep->com.local_addr; + req->le.lport = sin->sin_port; +@@ -3396,7 +3357,9 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) + window = (__force u16) htons((__force u16)tcph->window); + + /* Calcuate filter portion for LE region. */ +- filter = (__force unsigned int) cpu_to_be32(select_ntuple(dev, dst, e)); ++ filter = (__force unsigned int) cpu_to_be32(cxgb4_select_ntuple( ++ dev->rdev.lldi.ports[0], ++ e)); + + /* + * Synthesize the cpl_pass_accept_req. We have everything except the +-- +1.7.1 + -- 2.41.0