Netdev List
 help / color / mirror / Atom feed
From: Potnuri Bharat Teja <bharat@chelsio.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com,
	pabeni@redhat.com, andrew+netdev@lunn.ch, bharat@chelsio.com
Subject: [PATCH net-next v1 07/10] cxgb4: Extend hardware abstraction layer for T7 logs
Date: Sat,  6 Jun 2026 23:52:17 -0400	[thread overview]
Message-ID: <20260607035220.528439-8-bharat@chelsio.com> (raw)
In-Reply-To: <20260607035220.528439-1-bharat@chelsio.com>

Update the core hardware abstraction layer within t4_hw.c to implement
full register dispatching, multi-core memory mapping, and interface
diagnostics for T7 adapters.

Expand the driver low-level access routines to support T7 layouts:
 - Implement 64-bit PCIe memory window address tracking using offset
   shifts, and route flash geometry queries via a dynamic per-adapter
   mapping table.
 - Update chip identification logic to decode T7 silicon revisions using
   the PL_REV register, sizing structural limits to accommodate 256
   VFs and wider TCAM layouts.
 - Upgrade the firmware developer log parser devlog to automatically
   shard tracking buffers across the expanded microprocessor cores.
 - Introduce multi-core debugging interfaces for CIM, enabling explicit
   host-group and host-core target reads and writes for internal queues
   and LA buffers.
 - Integrate TP channel routing, SGE queues-per-page QPP mappings, PM
   RX cache metrics, and interrupt handler pathways unique to T7.

Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2484 ++++++++++++++++----
 1 file changed, 2048 insertions(+), 436 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 171750fad44f..d161bc56f2eb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -234,9 +234,8 @@ static void fw_asrt(struct adapter *adap, u32 mbox_addr)
  *	@access: the time (ms) needed to access the Firmware Mailbox
  *	@execute: the time (ms) the command spent being executed
  */
-static void t4_record_mbox(struct adapter *adapter,
-			   const __be64 *cmd, unsigned int size,
-			   int access, int execute)
+void t4_record_mbox(struct adapter *adapter, const __be64 *cmd,
+		    unsigned int size, int access, int execute)
 {
 	struct mbox_cmd_log *log = adapter->mbox_log;
 	struct mbox_cmd *entry;
@@ -305,7 +304,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
 	 * If the device is off-line, as in EEH, commands will time out.
 	 * Fail them early so we don't waste time waiting.
 	 */
-	if (adap->pdev->error_state != pci_channel_io_normal)
+	struct pci_dev *pdev = adap->pdev;
+
+	if (pdev->error_state != pci_channel_io_normal)
 		return -EIO;
 
 	/* If we have a negative timeout, that implies that we can't sleep. */
@@ -483,6 +484,39 @@ static int t4_edc_err_read(struct adapter *adap, int idx)
 	return 0;
 }
 
+unsigned int t4_pcie_mem_access_base_win_reg(struct adapter *adap, int win)
+{
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		return T7_PCIE_MEM_ACCESS_REG(T7_PCIE_MEM_ACCESS_BASE_WIN_A,
+				win);
+	return PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win);
+}
+
+unsigned int t4_pcie_mem_access_offset_reg(struct adapter *adap, int win)
+{
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		return T7_PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET0_A,
+				win);
+
+	return PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win);
+}
+
+void t4_pcie_mem_access_offset_write(struct adapter *adap, u32 off, int win,
+				     u32 pf)
+{
+	u32 reg = t4_pcie_mem_access_offset_reg(adap, win);
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		off >>= T7_MEMOFST_SHIFT_X;
+		t4_write_reg64(adap, reg, off | pf);
+		t4_read_reg64(adap, reg); /* Flush */
+		return;
+	}
+
+	t4_write_reg(adap, reg, off | pf);
+	t4_read_reg(adap, reg); /* Flush */
+}
+
 /**
  * t4_memory_rw_init - Get memory window relative offset, base, and size.
  * @adap: the adapter
@@ -497,7 +531,7 @@ static int t4_edc_err_read(struct adapter *adap, int idx)
 int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
 		      u32 *mem_base, u32 *mem_aperture)
 {
-	u32 edc_size, mc_size, mem_reg;
+	u64 edc_size, mc_size, mem_reg;
 
 	/* Offset into the region of memory which is being accessed
 	 * MEM_EDC0 = 0
@@ -506,15 +540,14 @@ int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
 	 * MEM_MC1  = 3 -- for chips with 2 memory controllers (e.g. T5)
 	 * MEM_HMA  = 4
 	 */
-	edc_size  = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
+	edc_size  = T7_EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
 	if (mtype == MEM_HMA) {
 		*mem_off = 2 * (edc_size * 1024 * 1024);
 	} else if (mtype != MEM_MC1) {
 		*mem_off = (mtype * (edc_size * 1024 * 1024));
 	} else {
-		mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap,
-						      MA_EXT_MEMORY0_BAR_A));
-		*mem_off = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
+		mc_size = T7_EXT_MEM0_SIZE_G(t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A));
+		*mem_off = ((u64)(MEM_MC0 * edc_size + mc_size)) * 1024 * 1024;
 	}
 
 	/* Each PCI-E Memory Window is programmed with a window size -- or
@@ -525,14 +558,13 @@ int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
 	 * space.  For T4 this is an absolute PCI-E Bus Address.  For T5
 	 * the address is relative to BAR0.
 	 */
-	mem_reg = t4_read_reg(adap,
-			      PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A,
-						  win));
+	mem_reg = t4_read_reg(adap, t4_pcie_mem_access_base_win_reg(adap, win));
+
 	/* a dead adapter will return 0xffffffff for PIO reads */
 	if (mem_reg == 0xffffffff)
 		return -ENXIO;
 
-	*mem_aperture = 1 << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
+	*mem_aperture = 1ULL << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
 	*mem_base = PCIEOFST_G(mem_reg) << PCIEOFST_SHIFT_X;
 	if (is_t4(adap->params.chip))
 		*mem_base -= adap->t4_bar0;
@@ -540,26 +572,6 @@ int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
 	return 0;
 }
 
-/**
- * t4_memory_update_win - Move memory window to specified address.
- * @adap: the adapter
- * @win: PCI-E Memory Window to use
- * @addr: location to move.
- *
- * Move memory window to specified address.
- */
-void t4_memory_update_win(struct adapter *adap, int win, u32 addr)
-{
-	t4_write_reg(adap,
-		     PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win),
-		     addr);
-	/* Read it back to ensure that changes propagate before we
-	 * attempt to use the new value.
-	 */
-	t4_read_reg(adap,
-		    PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
-}
-
 /**
  * t4_memory_rw_residual - Read/Write residual data.
  * @adap: the adapter
@@ -652,7 +664,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
 	/* Set up initial PCI-E Memory Window to cover the start of our
 	 * transfer.
 	 */
-	t4_memory_update_win(adap, win, pos | win_pf);
+	t4_pcie_mem_access_offset_write(adap, pos, win, win_pf);
 
 	/* Transfer data to/from the adapter as long as there's an integral
 	 * number of 32-bit transfers to complete.
@@ -707,7 +719,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
 		if (offset == mem_aperture) {
 			pos += mem_aperture;
 			offset = 0;
-			t4_memory_update_win(adap, win, pos | win_pf);
+			t4_pcie_mem_access_offset_write(adap, pos, win, win_pf);
 		}
 	}
 
@@ -811,12 +823,10 @@ u32 t4_get_util_window(struct adapter *adap)
  */
 void t4_setup_memwin(struct adapter *adap, u32 memwin_base, u32 window)
 {
-	t4_write_reg(adap,
-		     PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window),
+	t4_write_reg(adap, t4_pcie_mem_access_base_win_reg(adap, window),
 		     memwin_base | BIR_V(0) |
 		     WINDOW_V(ilog2(MEMWIN0_APERTURE) - WINDOW_SHIFT_X));
-	t4_read_reg(adap,
-		    PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window));
+	t4_read_reg(adap, t4_pcie_mem_access_base_win_reg(adap, window));
 }
 
 /**
@@ -835,6 +845,7 @@ unsigned int t4_get_regs_len(struct adapter *adapter)
 
 	case CHELSIO_T5:
 	case CHELSIO_T6:
+	case CHELSIO_T7:
 		return T5_REGMAP_SIZE;
 	}
 
@@ -2637,6 +2648,648 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
 		0x51300, 0x51324,
 	};
 
+	static const unsigned int t7_reg_ranges[] = {
+		0x1008, 0x101c,
+		0x1024, 0x10a8,
+		0x10b4, 0x10f8,
+		0x1100, 0x1114,
+		0x111c, 0x112c,
+		0x1138, 0x113c,
+		0x1144, 0x115c,
+		0x1180, 0x1184,
+		0x1190, 0x1194,
+		0x11a0, 0x11a4,
+		0x11b0, 0x11d0,
+		0x11fc, 0x1278,
+		0x1280, 0x1368,
+		0x1700, 0x172c,
+		0x173c, 0x1760,
+		0x1800, 0x18fc,
+		0x3000, 0x3044,
+		0x30a4, 0x30b0,
+		0x30b8, 0x30d8,
+		0x30e0, 0x30e8,
+		0x3140, 0x357c,
+		0x35a8, 0x35cc,
+		0x35e0, 0x35ec,
+		0x3600, 0x37fc,
+		0x3804, 0x3818,
+		0x3880, 0x388c,
+		0x3900, 0x3904,
+		0x3910, 0x3978,
+		0x3980, 0x399c,
+		0x4700, 0x4720,
+		0x4728, 0x475c,
+		0x480c, 0x4814,
+		0x4890, 0x489c,
+		0x48a4, 0x48ac,
+		0x48b8, 0x48bc,
+		0x4900, 0x4924,
+		0x4ffc, 0x4ffc,
+		0x5500, 0x5624,
+		0x56c4, 0x56ec,
+		0x56f4, 0x5720,
+		0x5728, 0x575c,
+		0x580c, 0x5814,
+		0x5890, 0x589c,
+		0x58a4, 0x58ac,
+		0x58b8, 0x58bc,
+		0x5940, 0x598c,
+		0x59b0, 0x59c8,
+		0x59d0, 0x59dc,
+		0x59fc, 0x5a18,
+		0x5a60, 0x5a6c,
+		0x5a80, 0x5a8c,
+		0x5a94, 0x5a9c,
+		0x5b94, 0x5bec,
+		0x5bf8, 0x5bfc,
+		0x5c10, 0x5c40,
+		0x5c4c, 0x5e48,
+		0x5e50, 0x5e94,
+		0x5ea0, 0x5eb0,
+		0x5ec0, 0x5ec0,
+		0x5ec8, 0x5ed0,
+		0x5ee0, 0x5ee0,
+		0x5ef0, 0x5ef0,
+		0x5f00, 0x5f04,
+		0x5f0c, 0x5f10,
+		0x5f20, 0x5f78,
+		0x5f84, 0x5f88,
+		0x5f90, 0x5fd8,
+		0x6000, 0x6020,
+		0x6028, 0x6030,
+		0x6044, 0x609c,
+		0x60a8, 0x60ac,
+		0x60b8, 0x60ec,
+		0x6100, 0x6104,
+		0x6118, 0x611c,
+		0x6150, 0x6150,
+		0x6180, 0x61b8,
+		0x7700, 0x77a8,
+		0x77b0, 0x7888,
+		0x78cc, 0x7970,
+		0x7b00, 0x7b00,
+		0x7b08, 0x7b0c,
+		0x7b24, 0x7b84,
+		0x7b8c, 0x7c2c,
+		0x7c34, 0x7c40,
+		0x7c48, 0x7c68,
+		0x7c70, 0x7c7c,
+		0x7d00, 0x7ddc,
+		0x7de4, 0x7e38,
+		0x7e40, 0x7e44,
+		0x7e4c, 0x7e74,
+		0x7e80, 0x7ee0,
+		0x7ee8, 0x7f0c,
+		0x7f20, 0x7f5c,
+		0x8dc0, 0x8de8,
+		0x8df8, 0x8e04,
+		0x8e10, 0x8e30,
+		0x8e7c, 0x8ee8,
+		0x8f88, 0x8f88,
+		0x8f90, 0x8fb0,
+		0x8fb8, 0x9058,
+		0x9074, 0x90f8,
+		0x9100, 0x912c,
+		0x9138, 0x9188,
+		0x9400, 0x9414,
+		0x9430, 0x9440,
+		0x9454, 0x9454,
+		0x945c, 0x947c,
+		0x9498, 0x94b8,
+		0x9600, 0x9600,
+		0x9608, 0x9638,
+		0x9640, 0x9704,
+		0x9710, 0x971c,
+		0x9800, 0x9804,
+		0x9854, 0x9854,
+		0x9c00, 0x9c6c,
+		0x9c80, 0x9cec,
+		0x9d00, 0x9d6c,
+		0x9d80, 0x9dec,
+		0x9e00, 0x9e6c,
+		0x9e80, 0x9eec,
+		0x9f00, 0x9f6c,
+		0x9f80, 0x9fec,
+		0xa000, 0xa06c,
+		0xa080, 0xa0ec,
+		0xa100, 0xa16c,
+		0xa180, 0xa1ec,
+		0xa200, 0xa26c,
+		0xa280, 0xa2ec,
+		0xa300, 0xa36c,
+		0xa380, 0xa458,
+		0xa460, 0xa4f8,
+		0xd000, 0xd03c,
+		0xd100, 0xd134,
+		0xd200, 0xd214,
+		0xd220, 0xd234,
+		0xd240, 0xd254,
+		0xd260, 0xd274,
+		0xd280, 0xd294,
+		0xd2a0, 0xd2b4,
+		0xd2c0, 0xd2d4,
+		0xd2e0, 0xd2f4,
+		0xd300, 0xd31c,
+		0xdfc0, 0xdfe0,
+		0xe000, 0xe00c,
+		0xf000, 0xf008,
+		0xf010, 0xf06c,
+		0x11000, 0x11014,
+		0x11048, 0x11120,
+		0x11130, 0x11144,
+		0x11174, 0x11178,
+		0x11190, 0x111a0,
+		0x111e4, 0x112f0,
+		0x11300, 0x1133c,
+		0x11408, 0x1146c,
+		0x12000, 0x12004,
+		0x12060, 0x122c4,
+		0x19040, 0x1906c,
+		0x19078, 0x19080,
+		0x1908c, 0x190e8,
+		0x190f0, 0x190f8,
+		0x19100, 0x19110,
+		0x19120, 0x19124,
+		0x19150, 0x19194,
+		0x1919c, 0x191a0,
+		0x191ac, 0x191c8,
+		0x191d0, 0x191e4,
+		0x19250, 0x19250,
+		0x19258, 0x19268,
+		0x19278, 0x19278,
+		0x19280, 0x192b0,
+		0x192bc, 0x192f0,
+		0x19300, 0x19308,
+		0x19310, 0x19318,
+		0x19320, 0x19328,
+		0x19330, 0x19330,
+		0x19348, 0x1934c,
+		0x193f8, 0x19428,
+		0x19430, 0x19444,
+		0x1944c, 0x1946c,
+		0x19474, 0x1947c,
+		0x19488, 0x194cc,
+		0x194f0, 0x194f8,
+		0x19c00, 0x19c48,
+		0x19c50, 0x19c80,
+		0x19c94, 0x19c98,
+		0x19ca0, 0x19cdc,
+		0x19ce4, 0x19cf8,
+		0x19d00, 0x19d30,
+		0x19d50, 0x19d80,
+		0x19d94, 0x19d98,
+		0x19da0, 0x19de0,
+		0x19df0, 0x19e10,
+		0x19e50, 0x19e6c,
+		0x19ea0, 0x19ebc,
+		0x19ec4, 0x19ef4,
+		0x19f04, 0x19f2c,
+		0x19f34, 0x19f34,
+		0x19f40, 0x19f50,
+		0x19f90, 0x19fb4,
+		0x19fbc, 0x19fbc,
+		0x19fc4, 0x19fc8,
+		0x19fd0, 0x19fe4,
+		0x1a000, 0x1a004,
+		0x1a010, 0x1a06c,
+		0x1a0b0, 0x1a0e4,
+		0x1a0ec, 0x1a108,
+		0x1a114, 0x1a130,
+		0x1a138, 0x1a1c4,
+		0x1a1fc, 0x1a29c,
+		0x1a2a8, 0x1a2b8,
+		0x1a2c0, 0x1a388,
+		0x1a398, 0x1a3ac,
+		0x1e008, 0x1e00c,
+		0x1e040, 0x1e044,
+		0x1e04c, 0x1e04c,
+		0x1e284, 0x1e290,
+		0x1e2c0, 0x1e2c0,
+		0x1e2e0, 0x1e2e4,
+		0x1e300, 0x1e384,
+		0x1e3c0, 0x1e3c8,
+		0x1e408, 0x1e40c,
+		0x1e440, 0x1e444,
+		0x1e44c, 0x1e44c,
+		0x1e684, 0x1e690,
+		0x1e6c0, 0x1e6c0,
+		0x1e6e0, 0x1e6e4,
+		0x1e700, 0x1e784,
+		0x1e7c0, 0x1e7c8,
+		0x1e808, 0x1e80c,
+		0x1e840, 0x1e844,
+		0x1e84c, 0x1e84c,
+		0x1ea84, 0x1ea90,
+		0x1eac0, 0x1eac0,
+		0x1eae0, 0x1eae4,
+		0x1eb00, 0x1eb84,
+		0x1ebc0, 0x1ebc8,
+		0x1ec08, 0x1ec0c,
+		0x1ec40, 0x1ec44,
+		0x1ec4c, 0x1ec4c,
+		0x1ee84, 0x1ee90,
+		0x1eec0, 0x1eec0,
+		0x1eee0, 0x1eee4,
+		0x1ef00, 0x1ef84,
+		0x1efc0, 0x1efc8,
+		0x1f008, 0x1f00c,
+		0x1f040, 0x1f044,
+		0x1f04c, 0x1f04c,
+		0x1f284, 0x1f290,
+		0x1f2c0, 0x1f2c0,
+		0x1f2e0, 0x1f2e4,
+		0x1f300, 0x1f384,
+		0x1f3c0, 0x1f3c8,
+		0x1f408, 0x1f40c,
+		0x1f440, 0x1f444,
+		0x1f44c, 0x1f44c,
+		0x1f684, 0x1f690,
+		0x1f6c0, 0x1f6c0,
+		0x1f6e0, 0x1f6e4,
+		0x1f700, 0x1f784,
+		0x1f7c0, 0x1f7c8,
+		0x1f808, 0x1f80c,
+		0x1f840, 0x1f844,
+		0x1f84c, 0x1f84c,
+		0x1fa84, 0x1fa90,
+		0x1fac0, 0x1fac0,
+		0x1fae0, 0x1fae4,
+		0x1fb00, 0x1fb84,
+		0x1fbc0, 0x1fbc8,
+		0x1fc08, 0x1fc0c,
+		0x1fc40, 0x1fc44,
+		0x1fc4c, 0x1fc4c,
+		0x1fe84, 0x1fe90,
+		0x1fec0, 0x1fec0,
+		0x1fee0, 0x1fee4,
+		0x1ff00, 0x1ff84,
+		0x1ffc0, 0x1ffc8,
+		0x30000, 0x30038,
+		0x30100, 0x3017c,
+		0x30190, 0x301a0,
+		0x301a8, 0x301b8,
+		0x301c4, 0x301c8,
+		0x301d0, 0x301e0,
+		0x30200, 0x30344,
+		0x30400, 0x304b4,
+		0x304c0, 0x3052c,
+		0x30540, 0x3065c,
+		0x30800, 0x30848,
+		0x30850, 0x308a8,
+		0x308b8, 0x308c0,
+		0x308cc, 0x308dc,
+		0x30900, 0x30904,
+		0x3090c, 0x30914,
+		0x3091c, 0x30928,
+		0x30930, 0x3093c,
+		0x30944, 0x30948,
+		0x30954, 0x30974,
+		0x3097c, 0x30980,
+		0x30a00, 0x30a20,
+		0x30a38, 0x30a3c,
+		0x30a50, 0x30a50,
+		0x30a80, 0x30a80,
+		0x30a88, 0x30aa8,
+		0x30ab0, 0x30ab4,
+		0x30ac8, 0x30ad4,
+		0x30b28, 0x30b84,
+		0x30b98, 0x30bb8,
+		0x30c98, 0x30d14,
+		0x31000, 0x31020,
+		0x31038, 0x3103c,
+		0x31050, 0x31050,
+		0x31080, 0x31080,
+		0x31088, 0x310a8,
+		0x310b0, 0x310b4,
+		0x310c8, 0x310d4,
+		0x31128, 0x31184,
+		0x31198, 0x311b8,
+		0x32000, 0x32038,
+		0x32100, 0x3217c,
+		0x32190, 0x321a0,
+		0x321a8, 0x321b8,
+		0x321c4, 0x321c8,
+		0x321d0, 0x321e0,
+		0x32200, 0x32344,
+		0x32400, 0x324b4,
+		0x324c0, 0x3252c,
+		0x32540, 0x3265c,
+		0x32800, 0x32848,
+		0x32850, 0x328a8,
+		0x328b8, 0x328c0,
+		0x328cc, 0x328dc,
+		0x32900, 0x32904,
+		0x3290c, 0x32914,
+		0x3291c, 0x32928,
+		0x32930, 0x3293c,
+		0x32944, 0x32948,
+		0x32954, 0x32974,
+		0x3297c, 0x32980,
+		0x32a00, 0x32a20,
+		0x32a38, 0x32a3c,
+		0x32a50, 0x32a50,
+		0x32a80, 0x32a80,
+		0x32a88, 0x32aa8,
+		0x32ab0, 0x32ab4,
+		0x32ac8, 0x32ad4,
+		0x32b28, 0x32b84,
+		0x32b98, 0x32bb8,
+		0x32c98, 0x32d14,
+		0x33000, 0x33020,
+		0x33038, 0x3303c,
+		0x33050, 0x33050,
+		0x33080, 0x33080,
+		0x33088, 0x330a8,
+		0x330b0, 0x330b4,
+		0x330c8, 0x330d4,
+		0x33128, 0x33184,
+		0x33198, 0x331b8,
+		0x34000, 0x34038,
+		0x34100, 0x3417c,
+		0x34190, 0x341a0,
+		0x341a8, 0x341b8,
+		0x341c4, 0x341c8,
+		0x341d0, 0x341e0,
+		0x34200, 0x34344,
+		0x34400, 0x344b4,
+		0x344c0, 0x3452c,
+		0x34540, 0x3465c,
+		0x34800, 0x34848,
+		0x34850, 0x348a8,
+		0x348b8, 0x348c0,
+		0x348cc, 0x348dc,
+		0x34900, 0x34904,
+		0x3490c, 0x34914,
+		0x3491c, 0x34928,
+		0x34930, 0x3493c,
+		0x34944, 0x34948,
+		0x34954, 0x34974,
+		0x3497c, 0x34980,
+		0x34a00, 0x34a20,
+		0x34a38, 0x34a3c,
+		0x34a50, 0x34a50,
+		0x34a80, 0x34a80,
+		0x34a88, 0x34aa8,
+		0x34ab0, 0x34ab4,
+		0x34ac8, 0x34ad4,
+		0x34b28, 0x34b84,
+		0x34b98, 0x34bb8,
+		0x34c98, 0x34d14,
+		0x35000, 0x35020,
+		0x35038, 0x3503c,
+		0x35050, 0x35050,
+		0x35080, 0x35080,
+		0x35088, 0x350a8,
+		0x350b0, 0x350b4,
+		0x350c8, 0x350d4,
+		0x35128, 0x35184,
+		0x35198, 0x351b8,
+		0x36000, 0x36038,
+		0x36100, 0x3617c,
+		0x36190, 0x361a0,
+		0x361a8, 0x361b8,
+		0x361c4, 0x361c8,
+		0x361d0, 0x361e0,
+		0x36200, 0x36344,
+		0x36400, 0x364b4,
+		0x364c0, 0x3652c,
+		0x36540, 0x3665c,
+		0x36800, 0x36848,
+		0x36850, 0x368a8,
+		0x368b8, 0x368c0,
+		0x368cc, 0x368dc,
+		0x36900, 0x36904,
+		0x3690c, 0x36914,
+		0x3691c, 0x36928,
+		0x36930, 0x3693c,
+		0x36944, 0x36948,
+		0x36954, 0x36974,
+		0x3697c, 0x36980,
+		0x36a00, 0x36a20,
+		0x36a38, 0x36a3c,
+		0x36a50, 0x36a50,
+		0x36a80, 0x36a80,
+		0x36a88, 0x36aa8,
+		0x36ab0, 0x36ab4,
+		0x36ac8, 0x36ad4,
+		0x36b28, 0x36b84,
+		0x36b98, 0x36bb8,
+		0x36c98, 0x36d14,
+		0x37000, 0x37020,
+		0x37038, 0x3703c,
+		0x37050, 0x37050,
+		0x37080, 0x37080,
+		0x37088, 0x370a8,
+		0x370b0, 0x370b4,
+		0x370c8, 0x370d4,
+		0x37128, 0x37184,
+		0x37198, 0x371b8,
+		0x38000, 0x380b0,
+		0x380b8, 0x38130,
+		0x38140, 0x38140,
+		0x38150, 0x38154,
+		0x38160, 0x381c4,
+		0x381d0, 0x38204,
+		0x3820c, 0x38214,
+		0x3821c, 0x3822c,
+		0x38244, 0x38244,
+		0x38254, 0x38274,
+		0x3827c, 0x38280,
+		0x38300, 0x38304,
+		0x3830c, 0x38314,
+		0x3831c, 0x3832c,
+		0x38344, 0x38344,
+		0x38354, 0x38374,
+		0x3837c, 0x38380,
+		0x38400, 0x38424,
+		0x38438, 0x3843c,
+		0x38480, 0x38480,
+		0x384a8, 0x384a8,
+		0x384b0, 0x384b4,
+		0x384c8, 0x38514,
+		0x38600, 0x3860c,
+		0x3861c, 0x38624,
+		0x38900, 0x38924,
+		0x38938, 0x3893c,
+		0x38980, 0x38980,
+		0x389a8, 0x389a8,
+		0x389b0, 0x389b4,
+		0x389c8, 0x38a14,
+		0x38b00, 0x38b0c,
+		0x38b1c, 0x38b24,
+		0x38e00, 0x38e00,
+		0x38e18, 0x38e20,
+		0x38e38, 0x38e40,
+		0x38e58, 0x38e60,
+		0x38e78, 0x38e80,
+		0x38e98, 0x38ea0,
+		0x38eb8, 0x38ec0,
+		0x38ed8, 0x38ee0,
+		0x38ef8, 0x38f08,
+		0x38f10, 0x38f2c,
+		0x38f80, 0x38ffc,
+		0x39080, 0x39080,
+		0x39088, 0x39090,
+		0x39100, 0x39108,
+		0x39120, 0x39128,
+		0x39140, 0x39148,
+		0x39160, 0x39168,
+		0x39180, 0x39188,
+		0x391a0, 0x391a8,
+		0x391c0, 0x391c8,
+		0x391e0, 0x391e8,
+		0x39200, 0x39200,
+		0x39208, 0x39240,
+		0x39300, 0x39300,
+		0x39308, 0x39340,
+		0x39400, 0x39400,
+		0x39408, 0x39440,
+		0x39500, 0x39500,
+		0x39508, 0x39540,
+		0x39600, 0x39600,
+		0x39608, 0x39640,
+		0x39700, 0x39700,
+		0x39708, 0x39740,
+		0x39800, 0x39800,
+		0x39808, 0x39840,
+		0x39900, 0x39900,
+		0x39908, 0x39940,
+		0x39a00, 0x39a04,
+		0x39a10, 0x39a14,
+		0x39a1c, 0x39aa8,
+		0x39b00, 0x39ecc,
+		0x3a000, 0x3a004,
+		0x3a050, 0x3a084,
+		0x3a090, 0x3a09c,
+		0x3a93c, 0x3a93c,
+		0x3b93c, 0x3b93c,
+		0x3c93c, 0x3c93c,
+		0x3d93c, 0x3d93c,
+		0x3e000, 0x3e020,
+		0x3e03c, 0x3e05c,
+		0x3e100, 0x3e120,
+		0x3e13c, 0x3e15c,
+		0x3e200, 0x3e220,
+		0x3e23c, 0x3e25c,
+		0x3e300, 0x3e320,
+		0x3e33c, 0x3e35c,
+		0x3f000, 0x3f034,
+		0x3f100, 0x3f130,
+		0x3f200, 0x3f218,
+		0x44000, 0x44014,
+		0x44020, 0x44028,
+		0x44030, 0x44030,
+		0x44100, 0x44114,
+		0x44120, 0x44128,
+		0x44130, 0x44130,
+		0x44200, 0x44214,
+		0x44220, 0x44228,
+		0x44230, 0x44230,
+		0x44300, 0x44314,
+		0x44320, 0x44328,
+		0x44330, 0x44330,
+		0x44400, 0x44414,
+		0x44420, 0x44428,
+		0x44430, 0x44430,
+		0x44500, 0x44514,
+		0x44520, 0x44528,
+		0x44530, 0x44530,
+		0x44714, 0x44718,
+		0x44730, 0x44730,
+		0x447c0, 0x447c0,
+		0x447f0, 0x447f0,
+		0x447f8, 0x447fc,
+		0x45000, 0x45014,
+		0x45020, 0x45028,
+		0x45030, 0x45030,
+		0x45100, 0x45114,
+		0x45120, 0x45128,
+		0x45130, 0x45130,
+		0x45200, 0x45214,
+		0x45220, 0x45228,
+		0x45230, 0x45230,
+		0x45300, 0x45314,
+		0x45320, 0x45328,
+		0x45330, 0x45330,
+		0x45400, 0x45414,
+		0x45420, 0x45428,
+		0x45430, 0x45430,
+		0x45500, 0x45514,
+		0x45520, 0x45528,
+		0x45530, 0x45530,
+		0x45714, 0x45718,
+		0x45730, 0x45730,
+		0x457c0, 0x457c0,
+		0x457f0, 0x457f0,
+		0x457f8, 0x457fc,
+		0x46000, 0x46010,
+		0x46020, 0x46034,
+		0x46040, 0x46050,
+		0x46060, 0x46088,
+		0x47000, 0x4709c,
+		0x470c0, 0x470d4,
+		0x47100, 0x471a8,
+		0x471b0, 0x471e8,
+		0x47200, 0x47210,
+		0x4721c, 0x47230,
+		0x47238, 0x47238,
+		0x47240, 0x472ac,
+		0x472d0, 0x472f4,
+		0x47300, 0x47310,
+		0x47318, 0x47348,
+		0x47350, 0x47354,
+		0x47380, 0x47388,
+		0x47390, 0x47394,
+		0x47400, 0x47448,
+		0x47450, 0x47458,
+		0x47500, 0x4751c,
+		0x47530, 0x4754c,
+		0x47560, 0x4757c,
+		0x47590, 0x475ac,
+		0x47600, 0x47630,
+		0x47640, 0x47644,
+		0x47660, 0x4769c,
+		0x47700, 0x47710,
+		0x47740, 0x47750,
+		0x4775c, 0x4779c,
+		0x477b0, 0x477bc,
+		0x477c4, 0x477c8,
+		0x477d4, 0x477fc,
+		0x48000, 0x48004,
+		0x48018, 0x4801c,
+		0x49304, 0x49320,
+		0x4932c, 0x4932c,
+		0x49334, 0x493f0,
+		0x49400, 0x49410,
+		0x49460, 0x494f4,
+		0x50000, 0x50084,
+		0x50090, 0x500cc,
+		0x50300, 0x50384,
+		0x50400, 0x50404,
+		0x50800, 0x50884,
+		0x50890, 0x508cc,
+		0x50b00, 0x50b84,
+		0x50c00, 0x50c04,
+		0x51000, 0x51020,
+		0x51028, 0x510c4,
+		0x51104, 0x51108,
+		0x51200, 0x51274,
+		0x51300, 0x51324,
+		0x51400, 0x51548,
+		0x51550, 0x51554,
+		0x5155c, 0x51584,
+		0x5158c, 0x515c8,
+		0x515f0, 0x515f4,
+		0x58000, 0x58004,
+		0x58018, 0x5801c,
+		0x59304, 0x59320,
+		0x5932c, 0x5932c,
+		0x59334, 0x593f0,
+		0x59400, 0x59410,
+		0x59460, 0x594f4,
+	};
+
 	u32 *buf_end = (u32 *)((char *)buf + buf_size);
 	const unsigned int *reg_ranges;
 	int reg_ranges_size, range;
@@ -2661,6 +3314,11 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
 		reg_ranges_size = ARRAY_SIZE(t6_reg_ranges);
 		break;
 
+	case CHELSIO_T7:
+		reg_ranges = t7_reg_ranges;
+		reg_ranges_size = ARRAY_SIZE(t7_reg_ranges);
+		break;
+
 	default:
 		dev_err(adap->pdev_dev,
 			"Unsupported chip version %d\n", chip_version);
@@ -2730,7 +3388,8 @@ int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
 int t4_seeprom_wp(struct adapter *adapter, bool enable)
 {
 	unsigned int v = enable ? 0xc : 0;
-	int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
+
+	int ret = cxgb4_pci_write_vpd(adapter, EEPROM_STAT_ADDR, 4, &v);
 	return ret < 0 ? ret : 0;
 }
 
@@ -2754,13 +3413,13 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
 	/* Card information normally starts at VPD_BASE but early cards had
 	 * it at 0.
 	 */
-	ret = pci_read_vpd(adapter->pdev, VPD_BASE, 1, &base_val);
+	ret = cxgb4_pci_read_vpd(adapter, VPD_BASE, 1, &base_val);
 	if (ret < 0)
 		goto out;
 
 	addr = base_val == PCI_VPD_LRDT_ID_STRING ? VPD_BASE : VPD_BASE_OLD;
 
-	ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
+	ret = cxgb4_pci_read_vpd(adapter, addr, VPD_LEN, vpd);
 	if (ret < 0)
 		goto out;
 
@@ -2898,6 +3557,121 @@ int t4_get_pfres(struct adapter *adapter)
 	return 0;
 }
 
+/* Flash Layout {start sector, # of sectors} for T4/T5/T6 adapters */
+static const struct t4_flash_loc_entry t4_flash_loc_arr[] = {
+	[FLASH_LOC_EXP_ROM] = { 0, 6 },
+	[FLASH_LOC_IBFT] = { 6, 1 },
+	[FLASH_LOC_BOOTCFG] = { 7, 1 },
+	[FLASH_LOC_FW] = { 8, 16 },
+	[FLASH_LOC_FWBOOTSTRAP] = { 27, 1 },
+	[FLASH_LOC_ISCSI_CRASH] = { 29, 1 },
+	[FLASH_LOC_FCOE_CRASH] = { 30, 1 },
+	[FLASH_LOC_CFG] = { 31, 1 },
+	[FLASH_LOC_CUDBG] = { 32, 32 },
+	[FLASH_LOC_BOOT_AREA] = { 0, 8 }, /* Spans complete Boot Area */
+	[FLASH_LOC_MIN_SIZE] = { 0, 32 }, /* Spans minimum required sections */
+	[FLASH_LOC_END] = { 0, 64 }, /* Spans the entire Serial Flash*/
+};
+
+/* Flash Layout {start sector, # of sectors} for T7 adapters */
+static const struct t4_flash_loc_entry t7_flash_loc_arr[] = {
+	[FLASH_LOC_VPD] = { 0, 1 },
+	[FLASH_LOC_FWBOOTSTRAP] = { 1, 1 },
+	[FLASH_LOC_FW] = { 2, 29 },
+	[FLASH_LOC_CFG] = { 31, 1 },
+	[FLASH_LOC_EXP_ROM] = { 32, 15 },
+	[FLASH_LOC_IBFT] = { 47, 1 },
+	[FLASH_LOC_BOOTCFG] = { 48, 1 },
+	[FLASH_LOC_ISCSI_CRASH] = { 62, 1 },
+	[FLASH_LOC_FCOE_CRASH] = { 63, 1 },
+	[FLASH_LOC_VPD_BACKUP] = { 64, 1 },
+	[FLASH_LOC_FWBOOTSTRAP_BACKUP] = { 65, 1 },
+	[FLASH_LOC_FW_BACKUP] = { 66, 29 },
+	[FLASH_LOC_CFG_BACK] = { 95, 1 },
+	[FLASH_LOC_CUDBG] = { 96, 48 },
+	[FLASH_LOC_CHIP_DUMP] = { 144, 48 },
+	[FLASH_LOC_BOOT_AREA] = { 32,
+				  17 }, /* Spans complete UEFI/PXE Boot Area */
+	[FLASH_LOC_MIN_SIZE] = { 0, 32 }, /* Spans minimum required sections */
+	[FLASH_LOC_END] = { 0, 256 }, /* Spans the entire Serial Flash*/
+};
+
+static const struct t4_flash_loc_entry *
+t4_flash_location_entry_get(struct adapter *adap, enum t4_flash_loc loc)
+{
+	const struct t4_flash_loc_entry *arr;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		arr = t7_flash_loc_arr;
+	else
+		arr = t4_flash_loc_arr;
+
+	return arr[loc].nsecs ? &arr[loc] : NULL;
+}
+
+int t4_flash_location_start_sec(struct adapter *adap, enum t4_flash_loc loc)
+{
+	const struct t4_flash_loc_entry *entry;
+
+	entry = t4_flash_location_entry_get(adap, loc);
+	if (!entry)
+		return -ENOENT;
+
+	return entry->start_sec;
+}
+
+int t4_flash_location_nsecs(struct adapter *adap, enum t4_flash_loc loc)
+{
+	const struct t4_flash_loc_entry *entry;
+
+	entry = t4_flash_location_entry_get(adap, loc);
+	if (!entry)
+		return -ENOENT;
+
+	return entry->nsecs;
+}
+
+int t4_flash_location_start(struct adapter *adap, enum t4_flash_loc loc)
+{
+	int ret = t4_flash_location_start_sec(adap, loc);
+
+	if (ret < 0)
+		return ret;
+
+	return FLASH_START(ret);
+}
+
+int t4_flash_location_size(struct adapter *adap, enum t4_flash_loc loc)
+{
+	int ret = t4_flash_location_nsecs(adap, loc);
+
+	if (ret < 0)
+		return ret;
+
+	return FLASH_MAX_SIZE(ret);
+}
+
+static int t4_flash_location_end(struct adapter *adap, enum t4_flash_loc loc)
+{
+	int ret = t4_flash_location_size(adap, loc);
+
+	if (ret < 0)
+		return ret;
+
+	return t4_flash_location_start(adap, loc) + ret;
+}
+
+static bool t4_flash_location_in_range(struct adapter *adap,
+				       enum t4_flash_loc loc, u32 addr)
+{
+	int ret = t4_flash_location_end(adap, loc);
+
+	if (ret < 0)
+		return false;
+
+	return addr >= t4_flash_location_start(adap, loc) && addr < ret;
+}
+
 /* serial flash and firmware constants */
 enum {
 	SF_ATTEMPTS = 10,             /* max retries for SF operations */
@@ -2933,8 +3707,15 @@ static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
 		return -EINVAL;
 	if (t4_read_reg(adapter, SF_OP_A) & SF_BUSY_F)
 		return -EBUSY;
-	t4_write_reg(adapter, SF_OP_A, SF_LOCK_V(lock) |
-		     SF_CONT_V(cont) | BYTECNT_V(byte_cnt - 1));
+	if (is_t7(adapter->params.chip))
+		t4_write_reg(adapter, SF_OP_A, QUADREADDISABLE_F |
+				SF_LOCK_V(lock) | SF_CONT_V(cont) |
+				BYTECNT_V(byte_cnt - 1));
+	else
+		t4_write_reg(adapter, SF_OP_A,
+			     SF_LOCK_V(lock) | SF_CONT_V(cont) |
+				     BYTECNT_V(byte_cnt - 1));
+
 	ret = t4_wait_op_done(adapter, SF_OP_A, SF_BUSY_F, 0, SF_ATTEMPTS, 5);
 	if (!ret)
 		*valp = t4_read_reg(adapter, SF_DATA_A);
@@ -3107,8 +3888,12 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
  */
 int t4_get_fw_version(struct adapter *adapter, u32 *vers)
 {
-	return t4_read_flash(adapter, FLASH_FW_START +
-			     offsetof(struct fw_hdr, fw_ver), 1,
+	int ret = t4_flash_location_start(adapter, FLASH_LOC_FW);
+
+	if (ret < 0)
+		return ret;
+
+	return t4_read_flash(adapter, ret + offsetof(struct fw_hdr, fw_ver), 1,
 			     vers, 0);
 }
 
@@ -3121,8 +3906,12 @@ int t4_get_fw_version(struct adapter *adapter, u32 *vers)
  */
 int t4_get_bs_version(struct adapter *adapter, u32 *vers)
 {
-	return t4_read_flash(adapter, FLASH_FWBOOTSTRAP_START +
-			     offsetof(struct fw_hdr, fw_ver), 1,
+	int ret = t4_flash_location_start(adapter, FLASH_LOC_FWBOOTSTRAP);
+
+	if (ret < 0)
+		return ret;
+
+	return t4_read_flash(adapter, ret + offsetof(struct fw_hdr, fw_ver), 1,
 			     vers, 0);
 }
 
@@ -3135,12 +3924,17 @@ int t4_get_bs_version(struct adapter *adapter, u32 *vers)
  */
 int t4_get_tp_version(struct adapter *adapter, u32 *vers)
 {
-	return t4_read_flash(adapter, FLASH_FW_START +
-			     offsetof(struct fw_hdr, tp_microcode_ver),
-			     1, vers, 0);
-}
+	int ret = t4_flash_location_start(adapter, FLASH_LOC_FW);
 
-/**
+	if (ret < 0)
+		return ret;
+
+	return t4_read_flash(adapter,
+			     ret + offsetof(struct fw_hdr, tp_microcode_ver), 1,
+			     vers, 0);
+}
+
+/**
  *	t4_get_exprom_version - return the Expansion ROM version (if any)
  *	@adap: the adapter
  *	@vers: where to place the version
@@ -3160,9 +3954,13 @@ int t4_get_exprom_version(struct adapter *adap, u32 *vers)
 					   sizeof(u32))];
 	int ret;
 
-	ret = t4_read_flash(adap, FLASH_EXP_ROM_START,
-			    ARRAY_SIZE(exprom_header_buf), exprom_header_buf,
-			    0);
+	ret = t4_flash_location_start(adap, FLASH_LOC_EXP_ROM);
+	if (ret < 0)
+		return ret;
+
+	ret = t4_read_flash(adap, ret, ARRAY_SIZE(exprom_header_buf),
+			    exprom_header_buf, 0);
+
 	if (ret)
 		return ret;
 
@@ -3360,9 +4158,9 @@ void t4_dump_version_info(struct adapter *adapter)
  */
 int t4_check_fw_version(struct adapter *adap)
 {
-	int i, ret, major, minor, micro;
-	int exp_major, exp_minor, exp_micro;
 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
+	int exp_major, exp_minor, exp_micro;
+	int i, ret, major, minor, micro;
 
 	ret = t4_get_fw_version(adap, &adap->params.fw_vers);
 	/* Try multiple times before returning error */
@@ -3392,6 +4190,11 @@ int t4_check_fw_version(struct adapter *adap)
 		exp_minor = T6FW_MIN_VERSION_MINOR;
 		exp_micro = T6FW_MIN_VERSION_MICRO;
 		break;
+	case CHELSIO_T7:
+		exp_major = T7FW_MIN_VERSION_MAJOR;
+		exp_minor = T7FW_MIN_VERSION_MINOR;
+		exp_micro = T7FW_MIN_VERSION_MICRO;
+		break;
 	default:
 		dev_err(adap->pdev_dev, "Unsupported chip type, %x\n",
 			adap->chip);
@@ -3470,10 +4273,12 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
 	const struct fw_hdr *drv_fw;
 
 	drv_fw = &fw_info->fw_hdr;
+	ret = t4_flash_location_start(adap, FLASH_LOC_FW);
+	if (ret < 0)
+		return ret;
 
 	/* Read the header of the firmware on the card */
-	ret = t4_read_flash(adap, FLASH_FW_START,
-			    sizeof(*card_fw) / sizeof(uint32_t),
+	ret = t4_read_flash(adap, ret, 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);
@@ -3585,10 +4390,16 @@ static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
  */
 unsigned int t4_flash_cfg_addr(struct adapter *adapter)
 {
-	if (adapter->params.sf_size == 0x100000)
-		return FLASH_FPGA_CFG_START;
+	int ret = t4_flash_location_end(adapter, FLASH_LOC_CFG);
+
+	/*
+	 * If the device FLASH isn't large enough to hold a Firmware
+	 * Configuration File, return an error.
+	 */
+	if (ret < 0 || adapter->params.sf_size < ret)
+		return -ENOSPC;
 	else
-		return FLASH_CFG_START;
+		return t4_flash_location_start(adapter, FLASH_LOC_CFG);
 }
 
 /* Return TRUE if the specified firmware matches the adapter.  I.e. T4
@@ -3604,7 +4415,9 @@ static bool t4_fw_matches_chip(const struct adapter *adap,
 	 */
 	if ((is_t4(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T4) ||
 	    (is_t5(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T5) ||
-	    (is_t6(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T6))
+	    (is_t6(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T6) ||
+	    (is_t7(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T7))
+
 		return true;
 
 	dev_err(adap->pdev_dev,
@@ -3623,16 +4436,17 @@ static bool t4_fw_matches_chip(const struct adapter *adap,
  */
 int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 {
-	u32 csum;
-	int ret, addr;
-	unsigned int i;
-	u8 first_page[SF_PAGE_SIZE];
-	const __be32 *p = (const __be32 *)fw_data;
-	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
-	unsigned int fw_start_sec = FLASH_FW_START_SEC;
-	unsigned int fw_size = FLASH_FW_MAX_SIZE;
-	unsigned int fw_start = FLASH_FW_START;
+	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
+	const __be32 *p = (const __be32 *)fw_data;
+	u8 first_page[SF_PAGE_SIZE];
+	unsigned int fw_start_sec;
+	enum t4_flash_loc loc;
+	unsigned int fw_start;
+	unsigned int fw_size;
+	unsigned int i;
+	int ret, addr;
+	u32 csum;
 
 	if (!size) {
 		dev_err(adap->pdev_dev, "FW image has no data\n");
@@ -3648,6 +4462,20 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
 			"FW image size differs from size in FW header\n");
 		return -EINVAL;
 	}
+
+	loc = FLASH_LOC_FW;
+	ret = t4_flash_location_size(adap, loc);
+	if (ret < 0) {
+		dev_err(adap->pdev_dev,
+			"Error finding Flash location (%u). ret: %d\n", loc,
+			ret);
+		return ret;
+	}
+
+	fw_size = ret;
+	fw_start_sec = t4_flash_location_start_sec(adap, loc);
+	fw_start = t4_flash_location_start(adap, loc);
+
 	if (size > fw_size) {
 		dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
 			fw_size);
@@ -4289,7 +5117,6 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
 	int fatal = 0;
 	unsigned int mask = 0;
 	unsigned int status = t4_read_reg(adapter, reg);
-
 	for ( ; acts->mask; ++acts) {
 		if (!(status & acts->mask))
 			continue;
@@ -4305,7 +5132,7 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
 		mask |= acts->mask;
 	}
 	status &= mask;
-	if (status)                           /* clear processed interrupts */
+	if (status)         /* clear processed interrupts */
 		t4_write_reg(adapter, reg, status);
 	return fatal;
 }
@@ -4440,7 +5267,17 @@ static void tp_intr_handler(struct adapter *adapter)
 		{ 0 }
 	};
 
-	if (t4_handle_intr_status(adapter, TP_INT_CAUSE_A, tp_intr_info))
+	static const struct intr_info t7_tp_intr_info[] = {
+		{ 0xbfffffff, "TP parity error", -1, 1 },
+		{ FLMTXFLSTEMPTY_F, "TP out of Tx pages", -1, 1 },
+		{ 0 }
+	};
+	u32 chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
+
+	if (t4_handle_intr_status(adapter, TP_INT_CAUSE_A,
+				  chip_ver >= CHELSIO_T7 ? t7_tp_intr_info :
+							   tp_intr_info))
+
 		t4_fatal_err(adapter);
 }
 
@@ -4484,6 +5321,53 @@ static void sge_intr_handler(struct adapter *adapter)
 		{ 0 }
 	};
 
+	static struct intr_info cause_sge_intr_info[] = {
+		{ ERR_FLM_DBP_F,
+		  "DBP pointer delivery for invalid context or QID", -1, 0, 0 },
+		{ ERR_FLM_IDMA1_F | ERR_FLM_IDMA0_F,
+		  "Invalid QID or header request by IDMA", -1, 0, 0 },
+		{ ERR_FLM_HINT_F, "FLM hint is for invalid context or QID", -1,
+		  0, 0 },
+		{ ERR_PCIE_ERROR3_F, "SGE PCIe error for DBP thread 3", -1, 0,
+		  0 },
+		{ ERR_PCIE_ERROR2_F, "SGE PCIe error for DBP thread 2", -1, 0,
+		  0 },
+		{ ERR_PCIE_ERROR1_F, "SGE PCIe error for DBP thread 1", -1, 0,
+		  0 },
+		{ ERR_PCIE_ERROR0_F, "SGE PCIe error for DBP thread 0", -1, 0,
+		  0 },
+		{ ERR_TIMER_ABOVE_MAX_QID_F,
+		  "SGE GTS with timer 0-5 for IQID > 1023", -1, 0, 0 },
+		{ ERR_CPL_EXCEED_IQE_SIZE_F,
+		  "SGE received CPL exceeding IQE size", -1, 0, 0 },
+		{ ERR_INVALID_CIDX_INC_F, "SGE GTS CIDX increment too large",
+		  -1, 0, 0 },
+		{ ERR_ITP_TIME_PAUSED_F, "SGE ITP error", -1, 0, 0 },
+		{ ERR_CPL_OPCODE_0_F, "SGE received 0-length CPL", -1, 0, 0 },
+		{ ERR_DROPPED_DB_F, "SGE DB dropped", -1, 0, 0 },
+		{ ERR_DATA_CPL_ON_HIGH_QID1_F | ERR_DATA_CPL_ON_HIGH_QID0_F,
+		  "SGE IQID > 1023 received CPL for FL", -1, 0, 0 },
+		{ ERR_BAD_DB_PIDX3_F | ERR_BAD_DB_PIDX2_F | ERR_BAD_DB_PIDX1_F |
+			  ERR_BAD_DB_PIDX0_F,
+		  "SGE DBP pidx increment too large", -1, 0, 0 },
+		{ ERR_ING_PCIE_CHAN_F, "SGE Ingress PCIe channel mismatch", -1,
+		  0, 0 },
+		{ ERR_ING_CTXT_PRIO_F,
+		  "Ingress context manager priority user error", -1, 0, 0 },
+		{ ERR_EGR_CTXT_PRIO_F,
+		  "Egress context manager priority user error", -1, 0, 0 },
+		{ DBP_TBUF_FULL_F, "SGE DBP tbuf full", -1, 0, 0 },
+		{ FATAL_WRE_LEN_F, "SGE WRE packet less than advertized length",
+		  -1, 0, 0 },
+		{ REG_ADDRESS_ERR_F, "Undefined SGE register accessed", -1, 0,
+		  0 },
+		{ INGRESS_SIZE_ERR_F, "SGE illegal ingress QID", -1, 0, 0 },
+		{ EGRESS_SIZE_ERR_F, "SGE illegal egress QID", -1, 0, 0 },
+		{ 0x0000000f, "SGE context access for invalid queue", -1, 0,
+		  0 },
+		{ 0 }
+	};
+
 	perr = t4_read_reg(adapter, SGE_INT_CAUSE1_A);
 	if (perr) {
 		v |= perr;
@@ -4498,6 +5382,18 @@ static void sge_intr_handler(struct adapter *adapter)
 			  perr);
 	}
 
+	perr = t4_read_reg(adapter, SGE_INT_CAUSE4_A);
+	if (perr) {
+		v |= perr;
+		dev_alert(adapter->pdev_dev, "SGE Cause4 Parity Error %#x\n",
+			  perr);
+	}
+
+	v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A, sge_intr_info);
+	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
+		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A,
+					   t4t5_sge_intr_info);
+
 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) >= CHELSIO_T5) {
 		perr = t4_read_reg(adapter, SGE_INT_CAUSE5_A);
 		/* Parity error (CRC) for err_T_RxCRC is trivial, ignore it */
@@ -4509,10 +5405,13 @@ static void sge_intr_handler(struct adapter *adapter)
 		}
 	}
 
-	v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A, sge_intr_info);
-	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
-		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A,
-					   t4t5_sge_intr_info);
+	if (CHELSIO_CHIP_VERSION(adapter->params.chip) >= CHELSIO_T6)
+		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE6_A, cause_sge_intr_info);
+
+	if (CHELSIO_CHIP_VERSION(adapter->params.chip) >= CHELSIO_T7) {
+		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE7_A, cause_sge_intr_info);
+		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE8_A, cause_sge_intr_info);
+	}
 
 	err = t4_read_reg(adapter, SGE_ERROR_STATS_A);
 	if (err & ERROR_QID_VALID_F) {
@@ -4710,6 +5609,11 @@ static void cplsw_intr_handler(struct adapter *adapter)
 		t4_fatal_err(adapter);
 }
 
+#define T6_LE_PERRCRC_MASK (PIPELINEERR_F | CLIPTCAMACCFAIL_F | \
+	SRVSRAMACCFAIL_F | CLCAMCRCPARERR_F | CLCAMINTPERR_F | SSRAMINTPERR_F | \
+	SRVSRAMPERR_F | VFSRAMPERR_F | TCAMINTPERR_F | TCAMCRCERR_F | \
+	HASHTBLMEMACCERR_F | MAIFWRINTPERR_F | HASHTBLMEMCRCERR_F)
+
 /*
  * LE interrupt handler.
  */
@@ -4725,20 +5629,33 @@ static void le_intr_handler(struct adapter *adap)
 		{ 0 }
 	};
 
-	static struct intr_info t6_le_intr_info[] = {
-		{ T6_LIPMISS_F, "LE LIP miss", -1, 0 },
-		{ T6_LIP0_F, "LE 0 LIP error", -1, 0 },
-		{ CMDTIDERR_F, "LE cmd tid error", -1, 1 },
-		{ TCAMINTPERR_F, "LE parity error", -1, 1 },
+	static const struct intr_info t6_le_intr_details[] = {
+		{ CACHEINTPERR_F, "Parity error in cache module", -1, 1 },
+		{ CACHESRAMPERR_F, "Parity error in data sram ", -1, 1 },
+		{ CLIPSUBERR_F, "LE CLIP CAM reverse substitution error", -1, 1 },
+		{ CLCAMFIFOERR_F, "LE CLIP CAM internal FIFO error", -1, 1 },
+		{ CTCAMINVLDENT_F, "Invalid IPv6 CLIP TCAM entry", -1, 0 },
+		{ TCAMINVLDENT_F, "Invalid IPv6 TCAM entry", -1, 0 },
+		{ TOTCNTERR_F, "LE total active < TCAM count", -1, 1 },
+		{ CMDPRSRINTERR_F, "LE internal error in parser", -1, 1 },
+		{ CMDTIDERR_F, "Incorrect tid in LE command", -1, 1 },
+		{ T6_ACTRGNFULL_F, "LE active region full", -1, 0 },
+		{ T6_ACTCNTIPV6TZERO_F, "LE IPv6 active open TCAM counter -ve", -1, 0 },
+		{ T6_ACTCNTIPV4TZERO_F, "LE IPv4 active open TCAM counter -ve", -1, 0 },
+		{ T6_ACTCNTIPV6ZERO_F, "LE IPv6 active open counter -ve", -1, 0 },
+		{ T6_ACTCNTIPV4ZERO_F, "LE IPv4 active open counter -ve", -1, 0 },
+		{ HASHTBLACCFAIL_F, "Hash table read error (proto conflict)", -1, 1 },
+		{ TCAMACCFAIL_F, "LE TCAM access failure", -1, 1 },
 		{ T6_UNKNOWNCMD_F, "LE unknown command", -1, 1 },
-		{ SSRAMINTPERR_F, "LE request queue parity error", -1, 1 },
-		{ HASHTBLMEMCRCERR_F, "LE hash table mem crc error", -1, 0 },
+		{ T6_LIP0_F, "LE found 0 LIP during CLIP substitution", -1, 0 },
+		{ T6_LIPMISS_F, "LE CLIP lookup miss", -1, 0 },
+		{ T6_LE_PERRCRC_MASK, "LE parity/CRC error", -1, 1 },
 		{ 0 }
 	};
 
 	if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE_A,
 				  (chip <= CHELSIO_T5) ?
-				  le_intr_info : t6_le_intr_info))
+				  le_intr_info : t6_le_intr_details))
 		t4_fatal_err(adap);
 }
 
@@ -4801,15 +5718,18 @@ static void mps_intr_handler(struct adapter *adapter)
 		{ 0 }
 	};
 
+	int chip = CHELSIO_CHIP_VERSION(adapter->params.chip);
 	int fat;
 
 	fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE_A,
 				    mps_rx_intr_info) +
 	      t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE_A,
-				    is_t6(adapter->params.chip)
-				    ? t6_mps_tx_intr_info
-				    : mps_tx_intr_info) +
-	      t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE_A,
+				    chip > CHELSIO_T5 ? t6_mps_tx_intr_info :
+							mps_tx_intr_info) +
+	      t4_handle_intr_status(adapter,
+				    chip >= CHELSIO_T7 ?
+					    T7_MPS_TRC_INT_CAUSE_A :
+					    MPS_TRC_INT_CAUSE_A,
 				    mps_trc_intr_info) +
 	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM_A,
 				    mps_stat_sram_intr_info) +
@@ -4845,13 +5765,21 @@ static void mem_intr_handler(struct adapter *adapter, int idx)
 		if (is_t4(adapter->params.chip)) {
 			addr = MC_INT_CAUSE_A;
 			cnt_addr = MC_ECC_STATUS_A;
+		} else if (is_t7(adapter->params.chip)) {
+			addr = T7_MC_P_INT_CAUSE_A;
+			cnt_addr = T7_MC_P_ECC_STATUS_A;
 		} else {
 			addr = MC_P_INT_CAUSE_A;
 			cnt_addr = MC_P_ECC_STATUS_A;
 		}
 	} else {
-		addr = MC_REG(MC_P_INT_CAUSE_A, 1);
-		cnt_addr = MC_REG(MC_P_ECC_STATUS_A, 1);
+		if (is_t7(adapter->params.chip)) {
+			addr = MC_REG(T7_MC_P_INT_CAUSE_A, 1);
+			cnt_addr = MC_REG(T7_MC_P_ECC_STATUS_A, 1);
+		} else {
+			addr = MC_REG(MC_P_INT_CAUSE_A, 1);
+			cnt_addr = MC_REG(MC_P_ECC_STATUS_A, 1);
+		}
 	}
 
 	v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
@@ -4939,6 +5867,17 @@ static void ncsi_intr_handler(struct adapter *adap)
 		t4_fatal_err(adap);
 }
 
+static u32 t4_port_reg(struct adapter *adap, u8 port, u32 reg)
+{
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		return T7_PORT_REG(port, reg);
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T4)
+		return T5_PORT_REG(port, reg);
+
+	return PORT_REG(port, reg);
+}
+
 /*
  * XGMAC interrupt handler.
  */
@@ -4946,10 +5885,13 @@ static void xgmac_intr_handler(struct adapter *adap, int port)
 {
 	u32 v, int_cause_reg;
 
-	if (is_t4(adap->params.chip))
-		int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE_A);
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		int_cause_reg =
+			t4_port_reg(adap, port, T7_MAC_PORT_INT_CAUSE_A);
+	else if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T4)
+		int_cause_reg = t4_port_reg(adap, port, MAC_PORT_INT_CAUSE_A);
 	else
-		int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A);
+		int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE_A);
 
 	v = t4_read_reg(adap, int_cause_reg);
 
@@ -4973,6 +5915,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port)
 static void pl_intr_handler(struct adapter *adap)
 {
 	static const struct intr_info pl_intr_info[] = {
+		{ INVALIDACCESS_F, "Invalid Access", -1, 0 },
 		{ FATALPERR_F, "T4 fatal parity error", -1, 1 },
 		{ PERRVFID_F, "PL VFID_MAP parity error", -1, 1 },
 		{ 0 }
@@ -4984,9 +5927,13 @@ static void pl_intr_handler(struct adapter *adap)
 
 #define PF_INTR_MASK (PFSW_F)
 #define GLBL_INTR_MASK (CIM_F | MPS_F | PL_F | PCIE_F | MC_F | EDC0_F | \
-		EDC1_F | LE_F | TP_F | MA_F | PM_TX_F | PM_RX_F | ULP_RX_F | \
-		CPL_SWITCH_F | SGE_F | ULP_TX_F | SF_F)
+			EDC1_F | LE_F | TP_F | MA_F | PM_TX_F | PM_RX_F | ULP_RX_F | \
+			CPL_SWITCH_F | SGE_F | ULP_TX_F | SF_F)
 
+#define GLBL_T7_INTR_MASK                                                      \
+	(CIM_F | MPS_F | PL_F | T7_PCIE_F | T7_MC0_F | T7_EDC0_F | T7_EDC1_F | \
+	 T7_LE_F | T7_TP_F | T7_MA_F | T7_PM_TX_F | T7_PM_RX_F | T7_ULP_RX_F | \
+	 T7_CPL_SWITCH_F | T7_SGE_F | T7_ULP_TX_F | SF_F)
 /**
  *	t4_slow_intr_handler - control path interrupt handler
  *	@adapter: the adapter
@@ -5001,12 +5948,17 @@ int t4_slow_intr_handler(struct adapter *adapter)
 	 * set when the corresponding PL_INT_ENABLE bit isn't set.  It's
 	 * easiest just to mask that case here.
 	 */
+	u32 chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 	u32 raw_cause = t4_read_reg(adapter, PL_INT_CAUSE_A);
 	u32 enable = t4_read_reg(adapter, PL_INT_ENABLE_A);
 	u32 cause = raw_cause & enable;
+	u32 mask;
+
+	mask = chip_ver >= CHELSIO_T7 ? GLBL_T7_INTR_MASK : GLBL_INTR_MASK;
 
-	if (!(cause & GLBL_INTR_MASK))
+	if (!(cause & mask))
 		return 0;
+
 	if (cause & CIM_F)
 		cim_intr_handler(adapter);
 	if (cause & MPS_F)
@@ -5025,37 +5977,67 @@ int t4_slow_intr_handler(struct adapter *adapter)
 		xgmac_intr_handler(adapter, 2);
 	if (cause & XGMAC_KR1_F)
 		xgmac_intr_handler(adapter, 3);
-	if (cause & PCIE_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_PCIE_F : PCIE_F;
+	if (cause & mask)
 		pcie_intr_handler(adapter);
-	if (cause & MC_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_MC0_F : MC_F;
+	if (cause & mask)
 		mem_intr_handler(adapter, MEM_MC);
-	if (is_t5(adapter->params.chip) && (cause & MC1_F))
-		mem_intr_handler(adapter, MEM_MC1);
-	if (cause & EDC0_F)
+	if (chip_ver != CHELSIO_T4 && chip_ver != CHELSIO_T6) {
+		mask = chip_ver >= CHELSIO_T7 ? T7_MC1_F : MC1_F;
+		if (cause & mask)
+			mem_intr_handler(adapter, MEM_MC1);
+	}
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_EDC0_F : EDC0_F;
+	if (cause & mask)
 		mem_intr_handler(adapter, MEM_EDC0);
-	if (cause & EDC1_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_EDC1_F : EDC1_F;
+	if (cause & mask)
 		mem_intr_handler(adapter, MEM_EDC1);
-	if (cause & LE_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_LE_F : LE_F;
+	if (cause & mask)
 		le_intr_handler(adapter);
-	if (cause & TP_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_TP_F : TP_F;
+	if (cause & mask)
 		tp_intr_handler(adapter);
-	if (cause & MA_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_MA_F : MA_F;
+	if (cause & mask)
 		ma_intr_handler(adapter);
-	if (cause & PM_TX_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_PM_TX_F : PM_TX_F;
+	if (cause & mask)
 		pmtx_intr_handler(adapter);
-	if (cause & PM_RX_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_PM_RX_F : PM_RX_F;
+	if (cause & mask)
 		pmrx_intr_handler(adapter);
-	if (cause & ULP_RX_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_ULP_RX_F : ULP_RX_F;
+	if (cause & mask)
 		ulprx_intr_handler(adapter);
-	if (cause & CPL_SWITCH_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_CPL_SWITCH_F : CPL_SWITCH_F;
+	if (cause & mask)
 		cplsw_intr_handler(adapter);
-	if (cause & SGE_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_SGE_F : SGE_F;
+	if (cause & mask)
 		sge_intr_handler(adapter);
-	if (cause & ULP_TX_F)
+
+	mask = chip_ver >= CHELSIO_T7 ? T7_ULP_TX_F : ULP_TX_F;
+	if (cause & mask)
 		ulptx_intr_handler(adapter);
 
 	/* Clear the interrupts just processed for which we are the master. */
-	t4_write_reg(adapter, PL_INT_CAUSE_A, raw_cause & GLBL_INTR_MASK);
+	mask = chip_ver >= CHELSIO_T7 ? GLBL_T7_INTR_MASK : GLBL_INTR_MASK;
+	t4_write_reg(adapter, PL_INT_CAUSE_A, raw_cause & mask);
 	(void)t4_read_reg(adapter, PL_INT_CAUSE_A); /* flush */
 	return 1;
 }
@@ -5082,6 +6064,8 @@ void t4_intr_enable(struct adapter *adapter)
 
 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
 		val = ERR_DROPPED_DB_F | ERR_EGR_CTXT_PRIO_F | DBFIFO_HP_INT_F;
+	else
+		val = ERR_PCIE_ERROR0_F | ERR_PCIE_ERROR1_F | FATAL_WRE_LEN_F;
 	t4_write_reg(adapter, SGE_INT_ENABLE3_A, ERR_CPL_EXCEED_IQE_SIZE_F |
 		     ERR_INVALID_CIDX_INC_F | ERR_CPL_OPCODE_0_F |
 		     ERR_DATA_CPL_ON_HIGH_QID1_F | INGRESS_SIZE_ERR_F |
@@ -5105,9 +6089,6 @@ void t4_intr_disable(struct adapter *adapter)
 {
 	u32 whoami, pf;
 
-	if (pci_channel_offline(adapter->pdev))
-		return;
-
 	whoami = t4_read_reg(adapter, PL_WHOAMI_A);
 	pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
 			SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
@@ -5245,12 +6226,55 @@ int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
 }
 
+/*
+ * t7_wait_sram_done - wait until an operation is completed
+ * @adapter: the adapter performing the operation
+ * @reg: the register to check for completion
+ * @result_reg: register that holds the result value
+ * @attempts: number of check iterations
+ * @delay: delay in usecs between iterations
+ * @valp: where to store the value of the result register at completion time
+ *
+ * Waits until a specific bit in @reg is cleared, checking up to
+ * @attempts times.Once the bit is cleared, reads from @result_reg
+ * and stores the value in @valp if it is not NULL. Returns 0 if the
+ * operation completes successfully and -EAGAIN if it times out.
+ */
+static int t7_wait_sram_done(struct adapter *adap, int reg, int result_reg,
+			     int attempts, int delay, u32 *valp)
+{
+	while (1) {
+		u32 val = t4_read_reg(adap, reg);
+
+		/* Check if SramStart (bit 19) is cleared */
+		if (!(val & (1 << 19))) {
+			if (valp)
+				*valp = t4_read_reg(adap, result_reg);
+			return 0;
+		}
+
+		if (--attempts == 0)
+			return -EAGAIN;
+
+		if (delay)
+			udelay(delay);
+	}
+}
+
 /* Read an RSS table row */
 static int rd_rss_row(struct adapter *adap, int row, u32 *val)
 {
-	t4_write_reg(adap, TP_RSS_LKP_TABLE_A, 0xfff00000 | row);
-	return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE_A, LKPTBLROWVLD_F, 1,
-				   5, 0, val);
+	int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
+
+	if (chip_ver < CHELSIO_T7) {
+		t4_write_reg(adap, TP_RSS_LKP_TABLE_A, 0xfff00000 | row);
+		return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE_A,
+				LKPTBLROWVLD_F, 1, 5, 0, val);
+	} else {
+		t4_write_reg(adap, TP_RSS_CONFIG_SRAM_A, 0xB0000 | row);
+		return t7_wait_sram_done(adap, TP_RSS_CONFIG_SRAM_A,
+				TP_RSS_LKP_TABLE_A, 5, 0, val);
+	}
 }
 
 /**
@@ -5680,6 +6704,7 @@ void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st,
 {
 	t4_tp_mib_read(adap, &st->rqe_dfr_pkt, 2, TP_MIB_RQE_DFR_PKT_A,
 		       sleep_ok);
+
 }
 
 /**
@@ -5939,11 +6964,21 @@ void t4_get_chan_txrate(struct adapter *adap, u64 *nic_rate, u64 *ofld_rate)
 int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
 			int idx, int enable)
 {
-	int i, ofst = idx * 4;
+	int chip = CHELSIO_CHIP_VERSION(adap->params.chip);
+	u32 match_ctl_a, match_ctl_b;
 	u32 data_reg, mask_reg, cfg;
+	int i, ofst = idx;
+
+	if (chip >= CHELSIO_T7) {
+		match_ctl_a = T7_MPS_TRC_FILTER_MATCH_CTL_A_A + ofst * 4;
+		match_ctl_b = T7_MPS_TRC_FILTER_MATCH_CTL_B_A + ofst * 4;
+	} else {
+		match_ctl_a = MPS_TRC_FILTER_MATCH_CTL_A_A + ofst * 4;
+		match_ctl_b = MPS_TRC_FILTER_MATCH_CTL_B_A + ofst * 4;
+	}
 
 	if (!enable) {
-		t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst, 0);
+		t4_write_reg(adap, match_ctl_a, 0);
 		return 0;
 	}
 
@@ -5970,20 +7005,20 @@ int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
 		return -EINVAL;
 
 	/* stop the tracer we'll be changing */
-	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst, 0);
+	t4_write_reg(adap, match_ctl_a, 0);
 
-	idx *= (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A);
-	data_reg = MPS_TRC_FILTER0_MATCH_A + idx;
-	mask_reg = MPS_TRC_FILTER0_DONT_CARE_A + idx;
+	ofst *= (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A);
+	data_reg = MPS_TRC_FILTER0_MATCH_A + ofst;
+	mask_reg = MPS_TRC_FILTER0_DONT_CARE_A + ofst;
 
 	for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
 		t4_write_reg(adap, data_reg, tp->data[i]);
 		t4_write_reg(adap, mask_reg, ~tp->mask[i]);
 	}
-	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B_A + ofst,
+	t4_write_reg(adap, match_ctl_b,
 		     TFCAPTUREMAX_V(tp->snap_len) |
 		     TFMINPKTSIZE_V(tp->min_len));
-	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst,
+	t4_write_reg(adap,  match_ctl_b,
 		     TFOFFSET_V(tp->skip_ofst) | TFLENGTH_V(tp->skip_len) |
 		     (is_t4(adap->params.chip) ?
 		     TFPORT_V(tp->port) | TFEN_F | TFINVERTMATCH_V(tp->invert) :
@@ -6005,12 +7040,21 @@ int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
 void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
 			 int *enabled)
 {
-	u32 ctla, ctlb;
-	int i, ofst = idx * 4;
+	int chip = CHELSIO_CHIP_VERSION(adap->params.chip);
+	u32 match_ctl_a, match_ctl_b, ctla, ctlb;
 	u32 data_reg, mask_reg;
+	int i, ofst = idx;
+
+	if (chip >= CHELSIO_T7) {
+		match_ctl_a = T7_MPS_TRC_FILTER_MATCH_CTL_A_A + ofst * 4;
+		match_ctl_b = T7_MPS_TRC_FILTER_MATCH_CTL_B_A + ofst * 4;
+	} else {
+		match_ctl_a = MPS_TRC_FILTER_MATCH_CTL_A_A + ofst * 4;
+		match_ctl_b = MPS_TRC_FILTER_MATCH_CTL_B_A + ofst * 4;
+	}
 
-	ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst);
-	ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B_A + ofst);
+	ctla = t4_read_reg(adap, match_ctl_a);
+	ctlb = t4_read_reg(adap, match_ctl_b);
 
 	if (is_t4(adap->params.chip)) {
 		*enabled = !!(ctla & TFEN_F);
@@ -6026,7 +7070,7 @@ void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
 	tp->skip_ofst = TFOFFSET_G(ctla);
 	tp->skip_len = TFLENGTH_G(ctla);
 
-	ofst = (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A) * idx;
+	ofst *= (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A);
 	data_reg = MPS_TRC_FILTER0_MATCH_A + ofst;
 	mask_reg = MPS_TRC_FILTER0_DONT_CARE_A + ofst;
 
@@ -6036,6 +7080,37 @@ void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
 	}
 }
 
+/**
+ *     t4_set_trace_rss_control - configure the trace rss control register
+ *     @adap: the adapter
+ *     @chan: the channel number for RSS control
+ *     @qid: queue number
+ *
+ *     Configures the MPS tracing RSS control parameter for specified
+ *     @chan channel and @qid queue number.
+ */
+void t4_set_trace_rss_control(struct adapter *adap, u8 chan, u16 qid)
+{
+	int chip = CHELSIO_CHIP_VERSION(adap->params.chip);
+	u32 mps_trc_rss_control;
+
+	switch (chip) {
+	case CHELSIO_T4:
+		mps_trc_rss_control = MPS_TRC_RSS_CONTROL_A;
+		break;
+	case CHELSIO_T5:
+	case CHELSIO_T6:
+		mps_trc_rss_control = MPS_T5_TRC_RSS_CONTROL_A;
+		break;
+	case CHELSIO_T7:
+		mps_trc_rss_control = T7_MPS_T5_TRC_RSS_CONTROL_A;
+		break;
+	}
+
+	t4_write_reg(adap, mps_trc_rss_control,
+		     RSSCONTROL_V(chan) | QUEUENUMBER_V(qid));
+}
+
 /**
  *	t4_pmtx_get_stats - returns the HW stats from PMTX
  *	@adap: the adapter
@@ -6046,8 +7121,9 @@ void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
  */
 void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
 {
-	int i;
+	int chip = CHELSIO_CHIP_VERSION(adap->params.chip);
 	u32 data[2];
+	int i;
 
 	for (i = 0; i < adap->params.arch.pm_stats_cnt; i++) {
 		t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1);
@@ -6057,7 +7133,9 @@ void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
 		} else {
 			t4_read_indirect(adap, PM_TX_DBG_CTRL_A,
 					 PM_TX_DBG_DATA_A, data, 2,
-					 PM_TX_DBG_STAT_MSB_A);
+					 chip >= CHELSIO_T7 ?
+						 T7_PM_TX_DBG_STAT_MSB_A :
+						 PM_TX_DBG_STAT_MSB_A);
 			cycles[i] = (((u64)data[0] << 32) | data[1]);
 		}
 	}
@@ -6090,6 +7168,25 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
 	}
 }
 
+/**
+ * t4_pmrx_cache_get_stats - returns the HW PMRX cache stats
+ * @adap: the adapter
+ * @stats: where to store the statistics
+ *
+ * Returns performance statistics of PMRX cache.
+ */
+void t4_pmrx_cache_get_stats(struct adapter *adap, u32 stats[])
+{
+	u8 i, j;
+
+	for (i = 0, j = 0; i < T7_PM_RX_CACHE_NSTATS / 3; i++, j += 3) {
+		t4_write_reg(adap, PM_RX_STAT_CONFIG_A, 0x100 + i);
+		stats[j] = t4_read_reg(adap, PM_RX_STAT_COUNT_A);
+		t4_read_indirect(adap, PM_RX_DBG_CTRL_A, PM_RX_DBG_DATA_A,
+				 &stats[j + 1], 2, PM_RX_DBG_STAT_MSB_A);
+	}
+}
+
 /**
  *	compute_mps_bg_map - compute the MPS Buffer Group Map for a Port
  *	@adapter: the adapter
@@ -6112,8 +7209,10 @@ static inline unsigned int compute_mps_bg_map(struct adapter *adapter,
 	case CHELSIO_T5:
 		switch (nports) {
 		case 1: return 0xf;
-		case 2: return 3 << (2 * pidx);
-		case 4: return 1 << pidx;
+		case 2:
+			return 3 << (2 * pidx);
+		case 4:
+			return 1 << pidx;
 		}
 		break;
 
@@ -6122,6 +7221,14 @@ static inline unsigned int compute_mps_bg_map(struct adapter *adapter,
 		case 2: return 1 << (2 * pidx);
 		}
 		break;
+	case CHELSIO_T7:
+		switch (nports) {
+		case 1:
+		case 2:
+		case 4:
+			return 1 << pidx;
+		}
+		break;
 	}
 
 	dev_err(adapter->pdev_dev, "Need MPS Buffer Group Map for Chip %0x, Nports %d\n",
@@ -6197,36 +7304,87 @@ unsigned int t4_get_mps_bg_map(struct adapter *adapter, int pidx)
 }
 
 /**
- *      t4_get_tp_e2c_map - return the E2C channel map associated with a port
- *      @adapter: the adapter
- *      @pidx: the port index
+* t4_get_num_ports - Save the FW initialized # of active ports from registers.
+* @adap: the adapter
+*
+* Save the number of FW initialized active ports from hardware registers.
+* For <= T6, the number of active ports is same as available from MPS.
+* For > T6, the number of active ports is based on configured TP Load
+* Balancer Mode. This function must be called after FW is initialized
+* to ensure the TP Load Balancer Mode had been configured for > T6.
+*/
+static void t4_get_tp_num_ports(struct adapter *adap)
+{
+	u32 val = 0;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		t4_tp_pio_read(adap, &val, 1, TP_CHANNEL_MAP_A, false);
+		adap->params.tp.lb_mode = T7_LB_MODE_G(val);
+
+		switch (adap->params.tp.lb_mode) {
+		case 0:
+			adap->params.tp.nports = 4;
+			break;
+		case 2:
+			adap->params.tp.nports = 2;
+			break;
+		default:
+			adap->params.tp.nports = 1;
+			break;
+		}
+	} else {
+		val = t4_read_reg(adap, MPS_CMN_CTL_A);
+		adap->params.tp.lb_mode = 0;
+		adap->params.tp.nports = 1 << NUMPORTS_G(val);
+	}
+}
+
+/*
+ * t4_get_tp_channel_map - fetch and save the configured TP Channel Map
+ * @adap: the adapter
+ *
+ * Fetch and save the configured TP Channel Map.
  */
-static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx)
+static void t4_get_tp_channel_map(struct adapter *adap)
 {
-	unsigned int nports;
 	u32 param, val = 0;
 	int ret;
+	u8 i;
 
-	nports = 1 << NUMPORTS_G(t4_read_reg(adapter, MPS_CMN_CTL_A));
-	if (pidx >= nports) {
-		CH_WARN(adapter, "TP E2C Channel Port Index %d >= Nports %d\n",
-			pidx, nports);
-		return 0;
-	}
-
-	/* FW version >= 1.16.44.0 can determine E2C channel map using
-	 * FW_PARAMS_PARAM_DEV_TPCHMAP API.
-	 */
-	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
-		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_TPCHMAP));
-	ret = t4_query_params_ns(adapter, adapter->mbox, adapter->pf,
-				 0, 1, &param, &val);
+	param = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
+		FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_TPCHMAP);
+	ret = t4_query_params_ns(adap, adap->mbox, adap->pf, 0, 1, &param,
+				 &val);
 	if (!ret)
-		return (val >> (8 * pidx)) & 0xff;
+		for (i = 0; i < NCHAN; i++)
+			adap->params.tp.channel_map[i] = (val >> (8 * i)) &
+							 0xff;
+}
 
-	return 0;
+/*
+ * t4_get_tp_port_chan - Get the associated TP channel for the port
+ * @adap: the adapter
+ * @pidx: the port ID for which to get the TP channel
+ *
+ * Get the associated TP channel for the port.
+ */
+u8 t4_get_tp_port_chan(struct adapter *adap, u8 pidx)
+{
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T6)
+		return pidx;
+
+	return adap->params.tp.channel_map[pidx];
 }
 
+/**
+ *      t4_get_tp_e2c_map - return the E2C channel map associated with a port
+ *      @adapter: the adapter
+ *      @pidx: the port index
+ */
+static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx)
+{
+	return adapter->params.tp.channel_map[pidx];
+}
 /**
  *	t4_get_tp_ch_map - return TP ingress channels associated with a port
  *	@adap: the adapter
@@ -6239,13 +7397,7 @@ static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx)
 unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
 {
 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
-	unsigned int nports = 1 << NUMPORTS_G(t4_read_reg(adap, MPS_CMN_CTL_A));
-
-	if (pidx >= nports) {
-		dev_warn(adap->pdev_dev, "TP Port Index %d >= Nports %d\n",
-			 pidx, nports);
-		return 0;
-	}
+	u8 nports = adap->params.tp.nports;
 
 	switch (chip_version) {
 	case CHELSIO_T4:
@@ -6256,8 +7408,10 @@ unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
 		 */
 		switch (nports) {
 		case 1: return 0xf;
-		case 2: return 3 << (2 * pidx);
-		case 4: return 1 << pidx;
+		case 2:
+			return 3 << (2 * pidx);
+		case 4:
+			return 1 << pidx;
 		}
 		break;
 
@@ -6267,6 +7421,14 @@ unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
 		case 2: return 1 << pidx;
 		}
 		break;
+	case CHELSIO_T7:
+		switch (nports) {
+		case 1:
+		case 2:
+		case 4:
+			return 1 << pidx;
+		}
+		break;
 	}
 
 	dev_err(adap->pdev_dev, "Need TP Channel Map for Chip %0x, Nports %d\n",
@@ -6280,37 +7442,76 @@ unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
  */
 const char *t4_get_port_type_description(enum fw_port_type port_type)
 {
-	static const char *const port_type_description[] = {
-		"Fiber_XFI",
-		"Fiber_XAUI",
-		"BT_SGMII",
-		"BT_XFI",
-		"BT_XAUI",
-		"KX4",
-		"CX4",
-		"KX",
-		"KR",
-		"SFP",
-		"BP_AP",
-		"BP4_AP",
-		"QSFP_10G",
-		"QSA",
-		"QSFP",
-		"BP40_BA",
-		"KR4_100G",
-		"CR4_QSFP",
-		"CR_QSFP",
-		"CR2_QSFP",
-		"SFP28",
-		"KR_SFP28",
-		"KR_XLAUI"
-	};
+	static const char *const port_type_description[] = { "Fiber_XFI",
+							     "Fiber_XAUI",
+							     "BT_SGMII",
+							     "BT_XFI",
+							     "BT_XAUI",
+							     "KX4",
+							     "CX4",
+							     "KX",
+							     "KR",
+							     "SFP",
+							     "BP_AP",
+							     "BP4_AP",
+							     "QSFP_10G",
+							     "QSA",
+							     "QSFP",
+							     "BP40_BA",
+							     "KR4_100G",
+							     "CR4_QSFP",
+							     "CR_QSFP",
+							     "CR2_QSFP",
+							     "SFP28",
+							     "KR_SFP28",
+							     "KR_XLAUI",
+							     "BARE_LINK_50G",
+							     "BARE_LINK_100G",
+							     "BARE_LINK_200G",
+							     "SFP56",
+							     "QSFP56",
+							     "QSFP56_4_50G",
+							     "KR_50G",
+							     "KR2_100G",
+							     "KR4_200G",
+							     "QSFP56_2_50G",
+							     "OSFP",
+							     "QSFPDD",
+							     "OSFP_2_200G",
+							     "QSFP_4_100G",
+							     "QSFPDD_2_200G",
+							     "KR8_400G" };
 
 	if (port_type < ARRAY_SIZE(port_type_description))
 		return port_type_description[port_type];
 	return "UNKNOWN";
 }
 
+static u64 t4_get_port_stats_lb_mode(struct adapter *adap, int idx, u32 reg)
+{
+	u8 i, n, start;
+	u64 s = 0;
+
+	start = t4_get_tp_port_chan(adap, idx);
+
+	switch (adap->params.tp.lb_mode) {
+	case 0:
+		n = 1;
+		break;
+	case 2:
+		n = 2;
+		break;
+	default:
+		n = 4;
+		break;
+	}
+
+	for (i = 0; i < n; i++)
+		s += t4_read_reg64(adap, t4_port_reg(adap, start + i, reg));
+
+	return s;
+}
+
 /**
  *      t4_get_port_stats_offset - collect port stats relative to a previous
  *                                 snapshot
@@ -6343,13 +7544,11 @@ void t4_get_port_stats_offset(struct adapter *adap, int idx,
  */
 void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
 {
-	u32 bgmap = t4_get_mps_bg_map(adap, idx);
 	u32 stat_ctl = t4_read_reg(adap, MPS_STAT_CTL_A);
+	u32 bgmap = t4_get_mps_bg_map(adap, idx);
 
 #define GET_STAT(name) \
-	t4_read_reg64(adap, \
-	(is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \
-	T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L)))
+	t4_get_port_stats_lb_mode(adap, idx, MPS_PORT_STAT_##name##_L);
 #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
 
 	p->tx_octets           = GET_STAT(TX_PORT_BYTES);
@@ -6443,10 +7642,7 @@ void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
 	u32 bgmap = t4_get_mps_bg_map(adap, idx);
 
 #define GET_STAT(name) \
-	t4_read_reg64(adap, \
-	(is_t4(adap->params.chip) ? \
-	PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L) : \
-	T5_PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)))
+	t4_get_port_stats_lb_mode(adap, idx, MPS_PORT_STAT_LB_PORT_##name##_L);
 #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
 
 	p->octets           = GET_STAT(BYTES);
@@ -6727,6 +7923,7 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state)
 		break;
 
 	case CHELSIO_T6:
+	case CHELSIO_T7:
 		sge_idma_decode = (const char **)t6_decode;
 		sge_idma_decode_nstates = ARRAY_SIZE(t6_decode);
 		break;
@@ -8054,18 +9251,23 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
  *
  *	Returns a negative error number or the number of filters freed.
  */
-int t4_free_mac_filt(struct adapter *adap, unsigned int mbox,
-		     unsigned int viid, unsigned int naddr,
-		     const u8 **addr, bool sleep_ok)
+int t4_free_mac_filt(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		     unsigned int naddr, const u8 **addr, bool sleep_ok)
 {
 	int offset, ret = 0;
 	struct fw_vi_mac_cmd c;
 	unsigned int nfilters = 0;
-	unsigned int max_naddr = is_t4(adap->params.chip) ?
-				       NUM_MPS_CLS_SRAM_L_INSTANCES :
-				       NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
+	unsigned int max_naddr = 0;
 	unsigned int rem = naddr;
 
+	if (is_t4(adap->params.chip))
+		max_naddr = NUM_MPS_CLS_SRAM_L_INSTANCES;
+	else if (is_t7(adap->params.chip))
+		/* In T7 there 3 TCAM each of 512 size*/
+		max_naddr = NUM_MPS_T5_CLS_SRAM_L_INSTANCES * 3;
+	else
+		max_naddr = NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
+
 	if (naddr > max_naddr)
 		return -EINVAL;
 
@@ -8681,7 +9883,7 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
 			lc->link_down_rc = linkdnrc;
 			dev_warn_ratelimited(adapter->pdev_dev,
 					     "Port %d link down, reason: %s\n",
-					     pi->tx_chan,
+					     pi->lport,
 					     t4_link_down_rc_str(linkdnrc));
 		}
 		lc->link_ok = link_ok;
@@ -8757,7 +9959,7 @@ int t4_update_port_info(struct port_info *pi)
 	memset(&port_cmd, 0, sizeof(port_cmd));
 	port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
 					    FW_CMD_REQUEST_F | FW_CMD_READ_F |
-					    FW_PORT_CMD_PORTID_V(pi->tx_chan));
+					    FW_PORT_CMD_PORTID_V(pi->lport));
 	port_cmd.action_to_len16 = cpu_to_be32(
 		FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
 				     ? FW_PORT_ACTION_GET_PORT_INFO
@@ -8795,7 +9997,7 @@ int t4_get_link_params(struct port_info *pi, unsigned int *link_okp,
 	memset(&port_cmd, 0, sizeof(port_cmd));
 	port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
 					    FW_CMD_REQUEST_F | FW_CMD_READ_F |
-					    FW_PORT_CMD_PORTID_V(pi->tx_chan));
+					    FW_PORT_CMD_PORTID_V(pi->lport));
 	action = (fw_caps == FW_CAPS16
 		  ? FW_PORT_ACTION_GET_PORT_INFO
 		  : FW_PORT_ACTION_GET_PORT_INFO32);
@@ -8955,14 +10157,17 @@ static int t4_get_flash_params(struct adapter *adap)
 	 * to the preexisting code.  All flash parts have 64KB sectors.
 	 */
 	static struct flash_desc supported_flash[] = {
-		{ 0x150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
+		{ 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */
 	};
 
 	unsigned int part, manufacturer;
 	unsigned int density, size = 0;
+	int ret, min_size;
 	u32 flashid = 0;
-	int ret;
 
+	min_size = t4_flash_location_end(adap, FLASH_LOC_MIN_SIZE);
+	if (min_size < 0)
+		return min_size;
 	/* Issue a Read ID Command to the Flash part.  We decode supported
 	 * Flash parts and their sizes from this.  There's a newer Query
 	 * Command which can retrieve detailed geometry information but many
@@ -9096,43 +10301,64 @@ static int t4_get_flash_params(struct adapter *adap)
 	adap->params.sf_nsec = size / SF_SEC_SIZE;
 
 found:
-	if (adap->params.sf_size < FLASH_MIN_SIZE)
+	if (adap->params.sf_size < min_size)
 		dev_warn(adap->pdev_dev, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
-			 flashid, adap->params.sf_size, FLASH_MIN_SIZE);
+			 flashid, adap->params.sf_size, min_size);
 	return 0;
 }
 
 /**
- *	t4_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.
+ *      t4_get_chip_type - Determine chip type from device ID
+ *      @adap: the adapter
+ *      @ver: adapter version
+ */
+enum chip_type t4_get_chip_type(struct adapter *adap, int ver)
+{
+	u32 pl_rev = REV_G(t4_read_reg(adap, PL_REV_A));
+
+	switch (ver) {
+	case CHELSIO_T4:
+		return CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev);
+	case CHELSIO_T5:
+		return CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev);
+	case CHELSIO_T6:
+		return CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev);
+	case CHELSIO_T7:
+		return CHELSIO_CHIP_CODE(CHELSIO_T7, pl_rev);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+/**
+ *	t4_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 t4_prep_adapter(struct adapter *adapter)
 {
 	int ret, ver;
-	uint16_t device_id;
-	u32 pl_rev;
+	u16 device_id;
 
 	get_pci_mode(adapter, &adapter->params.pci);
-	pl_rev = REV_G(t4_read_reg(adapter, PL_REV_A));
-
 	ret = t4_get_flash_params(adapter);
 	if (ret < 0) {
 		dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
 		return ret;
 	}
-
 	/* Retrieve adapter's device ID
 	 */
-	pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id);
-	ver = device_id >> 12;
-	adapter->params.chip = 0;
+	pci_read_config_word(adapter->pdev, PCI_DEVICE_ID,
+			     &adapter->params.pci.device_id);
+	pci_read_config_word(adapter->pdev, PCI_VENDOR_ID,
+			     &adapter->params.pci.vendor_id);
+	ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 	switch (ver) {
 	case CHELSIO_T4:
-		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev);
 		adapter->params.arch.sge_fl_db = DBPRIO_F;
 		adapter->params.arch.mps_tcam_size =
 				 NUM_MPS_CLS_SRAM_L_INSTANCES;
@@ -9144,9 +10370,9 @@ int t4_prep_adapter(struct adapter *adapter)
 		 * MPS can have 4 priority per port.
 		 */
 		adapter->params.arch.cng_ch_bits_log = 2;
+		adapter->params.cim_la_size = CIMLA_SIZE;
 		break;
 	case CHELSIO_T5:
-		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev);
 		adapter->params.arch.sge_fl_db = DBPRIO_F | DBTYPE_F;
 		adapter->params.arch.mps_tcam_size =
 				 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
@@ -9155,9 +10381,9 @@ int t4_prep_adapter(struct adapter *adapter)
 		adapter->params.arch.pm_stats_cnt = PM_NSTATS;
 		adapter->params.arch.vfcount = 128;
 		adapter->params.arch.cng_ch_bits_log = 2;
+		adapter->params.cim_la_size = CIMLA_SIZE;
 		break;
 	case CHELSIO_T6:
-		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev);
 		adapter->params.arch.sge_fl_db = 0;
 		adapter->params.arch.mps_tcam_size =
 				 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
@@ -9169,6 +10395,25 @@ int t4_prep_adapter(struct adapter *adapter)
 		 * MPS can have 8 priority per port.
 		 */
 		adapter->params.arch.cng_ch_bits_log = 3;
+		adapter->params.cim_la_size = CIMLA_SIZE_T6;
+		break;
+	case CHELSIO_T7:
+		adapter->params.arch.sge_fl_db = 0;
+		adapter->params.arch.mps_tcam_size =
+			is_t7(adapter->params.chip)
+				/* In T7 there 3 TCAM each of 512 size*/
+				?
+				NUM_MPS_T5_CLS_SRAM_L_INSTANCES * 3 :
+				NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
+		adapter->params.arch.mps_rplc_size = 256;
+		adapter->params.arch.nchan = NCHAN;
+		adapter->params.arch.pm_stats_cnt = T6_PM_NSTATS;
+		adapter->params.arch.vfcount = 256;
+		/* Congestion map will be for 4 channels so that
+		 * MPS can have 4 priority per port.
+		 */
+		adapter->params.arch.cng_ch_bits_log = 2;
+		adapter->params.cim_la_size = CIMLA_SIZE_T6;
 		break;
 	default:
 		dev_err(adapter->pdev_dev, "Device %d is not supported\n",
@@ -9186,9 +10431,11 @@ int t4_prep_adapter(struct adapter *adapter)
 	adapter->params.portvec = 1;
 	adapter->params.vpd.cclk = 50000;
 
-	/* Set PCIe completion timeout to 4 seconds. */
-	pcie_capability_clear_and_set_word(adapter->pdev, PCI_EXP_DEVCTL2,
-					   PCI_EXP_DEVCTL2_COMP_TIMEOUT, 0xd);
+	ret = t4_get_flash_params(adapter);
+	if (ret < 0) {
+		dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
+		return ret;
+	}
 	return 0;
 }
 
@@ -9211,9 +10458,12 @@ int t4_shutdown_adapter(struct adapter *adapter)
 	t4_intr_disable(adapter);
 	t4_write_reg(adapter, DBG_GPIO_EN_A, 0);
 	for_each_port(adapter, port) {
-		u32 a_port_cfg = is_t4(adapter->params.chip) ?
-				       PORT_REG(port, XGMAC_PORT_CFG_A) :
-				       T5_PORT_REG(port, MAC_PORT_CFG_A);
+		u32 a_port_cfg;
+
+		if (CHELSIO_CHIP_VERSION(adapter->params.chip) > CHELSIO_T4)
+			a_port_cfg = t4_port_reg(adapter, port, MAC_PORT_CFG_A);
+		else
+			a_port_cfg = PORT_REG(port, XGMAC_PORT_CFG_A);
 
 		t4_write_reg(adapter, a_port_cfg,
 			     t4_read_reg(adapter, a_port_cfg)
@@ -9323,10 +10573,10 @@ int t4_bar2_sge_qregs(struct adapter *adapter,
  */
 int t4_init_devlog_params(struct adapter *adap)
 {
-	struct devlog_params *dparams = &adap->params.devlog;
-	u32 pf_dparams;
-	unsigned int devlog_meminfo;
+	struct devlog_params *dparams = adap->params.devlog;
+	u32 nentries128, size, start, pf_dparams;
 	struct fw_devlog_cmd devlog_cmd;
+	u8 i, memtype, ncount;
 	int ret;
 
 	/* If we're dealing with newer firmware, the Device Log Parameters
@@ -9336,16 +10586,13 @@ int t4_init_devlog_params(struct adapter *adap)
 	pf_dparams =
 		t4_read_reg(adap, PCIE_FW_REG(PCIE_FW_PF_A, PCIE_FW_PF_DEVLOG));
 	if (pf_dparams) {
-		unsigned int nentries, nentries128;
-
-		dparams->memtype = PCIE_FW_PF_DEVLOG_MEMTYPE_G(pf_dparams);
-		dparams->start = PCIE_FW_PF_DEVLOG_ADDR16_G(pf_dparams) << 4;
-
+		ncount = ((PCIE_FW_PF_DEVLOG_COUNT_MSB_G(pf_dparams) << 1) |
+			   PCIE_FW_PF_DEVLOG_COUNT_LSB_G(pf_dparams));
+		memtype = PCIE_FW_PF_DEVLOG_MEMTYPE_G(pf_dparams);
+		start = PCIE_FW_PF_DEVLOG_ADDR16_G(pf_dparams) << 4;
 		nentries128 = PCIE_FW_PF_DEVLOG_NENTRIES128_G(pf_dparams);
-		nentries = (nentries128 + 1) * 128;
-		dparams->size = nentries * sizeof(struct fw_devlog_e);
-
-		return 0;
+		size = (nentries128 + 1) * 128 * sizeof(struct fw_devlog_e);
+		goto out_copy;
 	}
 
 	/* Otherwise, ask the firmware for its Device Log Parameters.
@@ -9359,15 +10606,41 @@ int t4_init_devlog_params(struct adapter *adap)
 	if (ret)
 		return ret;
 
-	devlog_meminfo =
-		be32_to_cpu(devlog_cmd.memtype_devlog_memaddr16_devlog);
-	dparams->memtype = FW_DEVLOG_CMD_MEMTYPE_DEVLOG_G(devlog_meminfo);
-	dparams->start = FW_DEVLOG_CMD_MEMADDR16_DEVLOG_G(devlog_meminfo) << 4;
-	dparams->size = be32_to_cpu(devlog_cmd.memsize_devlog);
+	pf_dparams = be32_to_cpu(devlog_cmd.memtype_devlog_memaddr16_devlog);
+	memtype = FW_DEVLOG_CMD_MEMTYPE_DEVLOG_G(pf_dparams);
+	start = FW_DEVLOG_CMD_MEMADDR16_DEVLOG_G(pf_dparams) << 4;
+	size = be32_to_cpu(devlog_cmd.memsize_devlog);
+	ncount = 0;
+
+out_copy:
+	adap->params.num_up_cores = 1 << ncount;
+	for (i = 0; i < adap->params.num_up_cores; i++) {
+		dparams[i].memtype = memtype;
+		dparams[i].start = start;
+		dparams[i].size = size / adap->params.num_up_cores;
+		start += dparams[i].size;
+	}
 
 	return 0;
 }
 
+/*
+ * t4_sge_get_qpp - get the number of Egress or Ingress queues per page
+ * @adap: the adapter
+ * @qtype: Egress or Ingress queue map register to read
+ *
+ * Fetches the number of Egress or Ingress queues per page.
+ */
+unsigned int t4_sge_get_qpp(struct adapter *adap, unsigned int qtype)
+{
+	unsigned int s_qpp, qpp;
+
+	s_qpp = (QUEUESPERPAGEPF0_S +
+		 (QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * adap->pf);
+	qpp = t4_read_reg(adap, qtype);
+	return ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
+}
+
 /**
  *	t4_init_sge_params - initialize adap->params.sge
  *	@adapter: the adapter
@@ -9377,8 +10650,7 @@ int t4_init_devlog_params(struct adapter *adap)
 int t4_init_sge_params(struct adapter *adapter)
 {
 	struct sge_params *sge_params = &adapter->params.sge;
-	u32 hps, qpp;
-	unsigned int s_hps, s_qpp;
+	u32 hps, s_hps;
 
 	/* Extract the SGE Page Size for our PF.
 	 */
@@ -9389,13 +10661,10 @@ int t4_init_sge_params(struct adapter *adapter)
 
 	/* Extract the SGE Egress and Ingess Queues Per Page for our PF.
 	 */
-	s_qpp = (QUEUESPERPAGEPF0_S +
-		(QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * adapter->pf);
-	qpp = t4_read_reg(adapter, SGE_EGRESS_QUEUES_PER_PAGE_PF_A);
-	sge_params->eq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
-	qpp = t4_read_reg(adapter, SGE_INGRESS_QUEUES_PER_PAGE_PF_A);
-	sge_params->iq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
-
+	sge_params->eq_qpp =
+		t4_sge_get_qpp(adapter, SGE_EGRESS_QUEUES_PER_PAGE_PF_A);
+	sge_params->iq_qpp =
+		t4_sge_get_qpp(adapter, SGE_INGRESS_QUEUES_PER_PAGE_PF_A);
 	return 0;
 }
 
@@ -9411,7 +10680,6 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
 	u32 param, val, v;
 	int chan, ret;
 
-
 	v = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
 	adap->params.tp.tre = TIMERRESOLUTION_G(v);
 	adap->params.tp.dack_re = DELAYEDACKRESOLUTION_G(v);
@@ -9420,6 +10688,12 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
 	for (chan = 0; chan < NCHAN; chan++)
 		adap->params.tp.tx_modq[chan] = chan;
 
+	/* Save the number of ports activated by FW */
+	t4_get_tp_num_ports(adap);
+
+	/* Save the TP Channel Map from FW */
+	t4_get_tp_channel_map(adap);
+
 	/* Cache the adapter's Compressed Filter Mode/Mask and global Ingress
 	 * Configuration.
 	 */
@@ -9476,21 +10750,62 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
 	 * shift positions of several elements of the Compressed Filter Tuple
 	 * for this adapter which we need frequently ...
 	 */
-	adap->params.tp.fcoe_shift = t4_filter_field_shift(adap, FCOE_F);
-	adap->params.tp.port_shift = t4_filter_field_shift(adap, PORT_F);
-	adap->params.tp.vnic_shift = t4_filter_field_shift(adap, VNIC_ID_F);
-	adap->params.tp.vlan_shift = t4_filter_field_shift(adap, VLAN_F);
-	adap->params.tp.tos_shift = t4_filter_field_shift(adap, TOS_F);
-	adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
-							       PROTOCOL_F);
-	adap->params.tp.ethertype_shift = t4_filter_field_shift(adap,
-								ETHERTYPE_F);
-	adap->params.tp.macmatch_shift = t4_filter_field_shift(adap,
-							       MACMATCH_F);
-	adap->params.tp.matchtype_shift = t4_filter_field_shift(adap,
-								MPSHITTYPE_F);
-	adap->params.tp.frag_shift = t4_filter_field_shift(adap,
-							   FRAGMENTATION_F);
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		adap->params.tp.ipsecidx_shift =
+			t4_filter_field_shift(adap, IPSECIDX_F);
+		adap->params.tp.fcoe_shift =
+			t4_filter_field_shift(adap, T7_FCOE_F);
+		adap->params.tp.port_shift =
+			t4_filter_field_shift(adap, T7_PORT_F);
+		adap->params.tp.vnic_shift =
+			t4_filter_field_shift(adap, T7_VNIC_ID_F);
+		adap->params.tp.vlan_shift =
+			t4_filter_field_shift(adap, T7_VLAN_F);
+		adap->params.tp.tos_shift =
+			t4_filter_field_shift(adap, T7_TOS_F);
+		adap->params.tp.protocol_shift =
+			t4_filter_field_shift(adap, T7_PROTOCOL_F);
+		adap->params.tp.ethertype_shift =
+			t4_filter_field_shift(adap, T7_ETHERTYPE_F);
+		adap->params.tp.macmatch_shift =
+			t4_filter_field_shift(adap, T7_MACMATCH_F);
+		adap->params.tp.matchtype_shift =
+			t4_filter_field_shift(adap, T7_MPSHITTYPE_F);
+		adap->params.tp.frag_shift =
+			t4_filter_field_shift(adap, T7_FRAGMENTATION_F);
+		adap->params.tp.synonly_shift =
+			t4_filter_field_shift(adap, SYNONLY_F);
+		adap->params.tp.tcpflags_shift =
+			t4_filter_field_shift(adap, TCPFLAGS_F);
+	} else {
+		adap->params.tp.fcoe_shift =
+			t4_filter_field_shift(adap, FCOE_F);
+		adap->params.tp.port_shift =
+			t4_filter_field_shift(adap, PORT_F);
+		adap->params.tp.vnic_shift =
+			t4_filter_field_shift(adap, VNIC_ID_F);
+		adap->params.tp.vlan_shift =
+			t4_filter_field_shift(adap, VLAN_F);
+		adap->params.tp.tos_shift = t4_filter_field_shift(adap, TOS_F);
+		adap->params.tp.protocol_shift =
+			t4_filter_field_shift(adap, PROTOCOL_F);
+		adap->params.tp.ethertype_shift =
+			t4_filter_field_shift(adap, ETHERTYPE_F);
+		adap->params.tp.macmatch_shift =
+			t4_filter_field_shift(adap, MACMATCH_F);
+		adap->params.tp.matchtype_shift =
+			t4_filter_field_shift(adap, MPSHITTYPE_F);
+		adap->params.tp.frag_shift =
+			t4_filter_field_shift(adap, FRAGMENTATION_F);
+
+		/* Following fields are not supported in T6 and older
+		 * NICs.
+		 */
+		adap->params.tp.ipsecidx_shift = -1;
+		adap->params.tp.roce_shift = -1;
+		adap->params.tp.synonly_shift = -1;
+		adap->params.tp.tcpflags_shift = -1;
+	}
 
 	/* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
 	 * represents the presence of an Outer VLAN instead of a VNIC ID.
@@ -9512,7 +10827,7 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
  *
  *      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.
+ *      within TP_VLAN_PRI_MAL (filter mode).  E.g. VLAN_F.
  */
 int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
 {
@@ -9523,6 +10838,54 @@ int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
 	if ((filter_mode & filter_sel) == 0)
 		return -1;
 
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
+			switch (filter_mode & sel) {
+			case IPSECIDX_F:
+				field_shift += FT_IPSECIDX_W;
+				break;
+			case T7_FCOE_F:
+				field_shift += FT_FCOE_W;
+				break;
+			case T7_PORT_F:
+				field_shift += FT_PORT_W;
+				break;
+			case T7_VNIC_ID_F:
+				field_shift += FT_VNIC_ID_W;
+				break;
+			case T7_VLAN_F:
+				field_shift += FT_VLAN_W;
+				break;
+			case T7_TOS_F:
+				field_shift += FT_TOS_W;
+				break;
+			case T7_PROTOCOL_F:
+				field_shift += FT_PROTOCOL_W;
+				break;
+			case T7_ETHERTYPE_F:
+				field_shift += FT_ETHERTYPE_W;
+				break;
+			case T7_MACMATCH_F:
+				field_shift += FT_MACMATCH_W;
+				break;
+			case T7_MPSHITTYPE_F:
+				field_shift += FT_MPSHITTYPE_W;
+				break;
+			case T7_FRAGMENTATION_F:
+				field_shift += FT_FRAGMENTATION_W;
+				break;
+			case SYNONLY_F:
+				field_shift += FT_SYNONLY_W;
+				break;
+			case TCPFLAGS_F:
+				field_shift += FT_TCPFLAGS_W;
+				break;
+			}
+		}
+
+		goto out;
+	}
+
 	for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
 		switch (filter_mode & sel) {
 		case FCOE_F:
@@ -9557,6 +10920,8 @@ int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
 			break;
 		}
 	}
+
+out:
 	return field_shift;
 }
 
@@ -9668,7 +11033,7 @@ int t4_init_portinfo(struct port_info *pi, int mbox,
 		return ret;
 
 	pi->viid = ret;
-	pi->tx_chan = port;
+	pi->tx_chan = t4_get_tp_port_chan(pi->adapter, port);
 	pi->lport = port;
 	pi->rss_size = rss_size;
 	pi->rx_cchan = t4_get_tp_e2c_map(pi->adapter, port);
@@ -9714,6 +11079,101 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 	return 0;
 }
 
+u8 t4_cim_num_ibq(struct adapter *adap)
+{
+	unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
+
+	return chip_ver >= CHELSIO_T7 ? CIM_NUM_IBQ_T7 : CIM_NUM_IBQ;
+}
+
+u8 t4_cim_num_obq(struct adapter *adap)
+{
+	unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
+
+	if (chip_ver >= CHELSIO_T7)
+		return CIM_NUM_OBQ_T7;
+
+	if (chip_ver > CHELSIO_T4)
+		return CIM_NUM_OBQ_T5;
+
+	return CIM_NUM_OBQ;
+}
+
+static void t4_read_cimq_cfg_ibq_core(struct adapter *adap, u8 coreid, u32 qid,
+				      u16 *base, u16 *size, u16 *thres)
+{
+	unsigned int v, m;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		v = T7_IBQSELECT_F | T7_QUENUMSELECT_V(qid) |
+		    CORESELECT_V(coreid);
+		/* value is in 512-byte units */
+		m = 512;
+	} else {
+		v = IBQSELECT_F | QUENUMSELECT_V(qid);
+		/* value is in 256-byte units */
+		m = 256;
+	}
+
+	t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, v);
+	v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
+	if (base)
+		*base = CIMQBASE_G(v) * m;
+	if (size)
+		*size = CIMQSIZE_G(v) * m;
+	if (thres)
+		*thres = QUEFULLTHRSH_G(v) * 8; /* 8-byte unit */
+}
+
+static void t4_read_cimq_cfg_obq_core(struct adapter *adap, u8 coreid, u32 qid,
+				      u16 *base, u16 *size)
+{
+	unsigned int v, m;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		v = T7_OBQSELECT_F | T7_QUENUMSELECT_V(qid) |
+		    CORESELECT_V(coreid);
+		/* value is in 512-byte units */
+		m = 512;
+	} else {
+		v = OBQSELECT_F | QUENUMSELECT_V(qid);
+		/* value is in 256-byte units */
+		m = 256;
+	}
+
+	t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, v);
+	v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
+	if (base)
+		*base = CIMQBASE_G(v) * m;
+	if (size)
+		*size = CIMQSIZE_G(v) * m;
+}
+
+/**
+ *     t4_read_cimq_cfg_core - read CIM queue configuration on specific core
+ *     @adap: the adapter
+ *     @coreid: the uP coreid
+ *     @base: holds the queue base addresses in bytes
+ *     @size: holds the queue sizes in bytes
+ *     @thres: holds the queue full thresholds in bytes
+ *
+ *     Returns the current configuration of the CIM queues, starting with
+ *     the IBQs, then the OBQs, on a specific @coreid.
+ */
+void t4_read_cimq_cfg_core(struct adapter *adap, u8 coreid, u16 *base,
+			   u16 *size, u16 *thres)
+{
+	unsigned int cim_num_ibq = t4_cim_num_ibq(adap);
+	unsigned int cim_num_obq = t4_cim_num_obq(adap);
+	unsigned int i;
+
+	for (i = 0; i < cim_num_ibq; i++, base++, size++, thres++)
+		t4_read_cimq_cfg_ibq_core(adap, coreid, i, base, size, thres);
+
+	for (i = 0; i < cim_num_obq; i++, base++, size++)
+		t4_read_cimq_cfg_obq_core(adap, coreid, i, base, size);
+}
+
 int t4_init_port_mirror(struct port_info *pi, u8 mbox, u8 port, u8 pf, u8 vf,
 			u16 *mirror_viid)
 {
@@ -9742,114 +11202,206 @@ int t4_init_port_mirror(struct port_info *pi, u8 mbox, u8 port, u8 pf, u8 vf,
  */
 void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres)
 {
-	unsigned int i, v;
-	int cim_num_obq = is_t4(adap->params.chip) ?
-				CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
+	t4_read_cimq_cfg_core(adap, 0, base, size, thres);
+}
 
-	for (i = 0; i < CIM_NUM_IBQ; i++) {
-		t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, IBQSELECT_F |
-			     QUENUMSELECT_V(i));
-		v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
-		/* value is in 256-byte units */
-		*base++ = CIMQBASE_G(v) * 256;
-		*size++ = CIMQSIZE_G(v) * 256;
-		*thres++ = QUEFULLTHRSH_G(v) * 8; /* 8-byte unit */
-	}
-	for (i = 0; i < cim_num_obq; i++) {
-		t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
-			     QUENUMSELECT_V(i));
-		v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
-		/* value is in 256-byte units */
-		*base++ = CIMQBASE_G(v) * 256;
-		*size++ = CIMQSIZE_G(v) * 256;
-	}
+static int t4_read_cim_ibq_data_core(struct adapter *adap, u8 coreid, u32 addr,
+				     u32 *data)
+{
+	int ret, attempts;
+	unsigned int v;
+
+	/* It might take 3-10ms before the IBQ debug read access is allowed.
+	 * Wait for 1 Sec with a delay of 1 usec.
+	 */
+	attempts = 1000000;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		v = T7_IBQDBGADDR_V(addr) | IBQDBGCORE_V(coreid);
+	else
+		v = IBQDBGADDR_V(addr);
+
+	t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, v | IBQDBGEN_F);
+	ret = t4_wait_op_done(adap, CIM_IBQ_DBG_CFG_A, IBQDBGBUSY_F, 0,
+			      attempts, 1);
+	if (ret)
+		return ret;
+
+	*data = t4_read_reg(adap, CIM_IBQ_DBG_DATA_A);
+	return 0;
 }
 
 /**
- *	t4_read_cim_ibq - read the contents of a CIM inbound queue
- *	@adap: the adapter
- *	@qid: the queue index
- *	@data: where to store the queue contents
- *	@n: capacity of @data in 32-bit words
+ *     t4_read_cim_ibq_core - read the contents of a CIM inbound queue on
+ *     specific core
+ *     @adap: the adapter
+ *     @coreid: the uP coreid
+ *     @qid: the queue index
+ *     @data: where to store the queue contents
+ *     @n: capacity of @data in 32-bit words
  *
- *	Reads the contents of the selected CIM queue starting at address 0 up
- *	to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
- *	error and the number of 32-bit words actually read on success.
+ *     Reads the contents of the selected CIM queue starting at address 0 up
+ *     to the capacity of @data on a specific @coreid.  @n must be a multiple
+ *     of 4.  Returns < 0 on error and the number of 32-bit words actually
+ *     read on success.
  */
-int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
+int t4_read_cim_ibq_core(struct adapter *adap, u8 coreid, u32 qid, u32 *data,
+			 size_t n)
 {
-	int i, err, attempts;
-	unsigned int addr;
-	const unsigned int nwords = CIM_IBQ_SIZE * 4;
+	unsigned int cim_num_ibq = t4_cim_num_ibq(adap);
+	u16 i, addr, nwords;
+	int ret;
 
-	if (qid > 5 || (n & 3))
+	if (qid > (cim_num_ibq - 1) || (n & 3))
 		return -EINVAL;
 
-	addr = qid * nwords;
+	t4_read_cimq_cfg_ibq_core(adap, coreid, qid, &addr, &nwords, NULL);
+	addr >>= sizeof(u16);
+	nwords >>= sizeof(u16);
 	if (n > nwords)
 		n = nwords;
 
-	/* It might take 3-10ms before the IBQ debug read access is allowed.
-	 * Wait for 1 Sec with a delay of 1 usec.
-	 */
-	attempts = 1000000;
-
-	for (i = 0; i < n; i++, addr++) {
-		t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, IBQDBGADDR_V(addr) |
-			     IBQDBGEN_F);
-		err = t4_wait_op_done(adap, CIM_IBQ_DBG_CFG_A, IBQDBGBUSY_F, 0,
-				      attempts, 1);
-		if (err)
-			return err;
-		*data++ = t4_read_reg(adap, CIM_IBQ_DBG_DATA_A);
+	for (i = 0; i < n; i++, addr++, data++) {
+		ret = t4_read_cim_ibq_data_core(adap, coreid, addr, data);
+		if (ret < 0)
+			return ret;
 	}
+
 	t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, 0);
 	return i;
 }
 
-/**
- *	t4_read_cim_obq - read the contents of a CIM outbound queue
- *	@adap: the adapter
- *	@qid: the queue index
- *	@data: where to store the queue contents
- *	@n: capacity of @data in 32-bit words
+/*
+ * t4_read_cim_ibq - read the contents of a CIM inbound queue
+ * @adap: the adapter
+ * @qid: the queue index
+ * @data: where to store the queue contents
+ * @n: capacity of @data in 32-bit words
  *
- *	Reads the contents of the selected CIM queue starting at address 0 up
- *	to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
- *	error and the number of 32-bit words actually read on success.
+ * Reads the contents of the selected CIM queue starting at address 0 up
+ * to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
+ * error and the number of 32-bit words actually read on success.
  */
-int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
+int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
+{
+	return t4_read_cim_ibq_core(adap, 0, qid, data, n);
+}
+
+static int t4_read_cim_obq_data_core(struct adapter *adap, u8 coreid, u32 addr,
+				     u32 *data)
+{
+	unsigned int v;
+	int ret;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+		v = T7_OBQDBGADDR_V(addr) | OBQDBGCORE_V(coreid);
+	else
+		v = OBQDBGADDR_V(addr);
+
+	t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, v | OBQDBGEN_F);
+	ret = t4_wait_op_done(adap, CIM_OBQ_DBG_CFG_A, OBQDBGBUSY_F, 0, 2, 1);
+	if (ret)
+		return ret;
+
+	*data = t4_read_reg(adap, CIM_OBQ_DBG_DATA_A);
+	return 0;
+}
+
+/*
+ * t4_read_cim_obq_core - read the contents of a CIM outbound queue on
+ * specific core
+ * @adap: the adapter
+ * @coreid: the uP coreid
+ * @qid: the queue index
+ * @data: where to store the queue contents
+ * @n: capacity of @data in 32-bit words
+ *
+ * Reads the contents of the selected CIM queue starting at address 0 up
+ * to the capacity of @data on specific @coreid.  @n must be a multiple
+ * of 4.  Returns < 0 on error and the number of 32-bit words actually
+ * read on success.
+ */
+int t4_read_cim_obq_core(struct adapter *adap, u8 coreid, u32 qid, u32 *data,
+			 size_t n)
 {
-	int i, err;
-	unsigned int addr, v, nwords;
-	int cim_num_obq = is_t4(adap->params.chip) ?
-				CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
+	unsigned int cim_num_obq = t4_cim_num_obq(adap);
+	u16 i, addr, nwords;
+	int ret;
 
 	if ((qid > (cim_num_obq - 1)) || (n & 3))
 		return -EINVAL;
 
-	t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
-		     QUENUMSELECT_V(qid));
-	v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
-
-	addr = CIMQBASE_G(v) * 64;    /* muliple of 256 -> muliple of 4 */
-	nwords = CIMQSIZE_G(v) * 64;  /* same */
+	t4_read_cimq_cfg_obq_core(adap, coreid, qid, &addr, &nwords);
+	addr >>= sizeof(u16);
+	nwords >>= sizeof(u16);
 	if (n > nwords)
 		n = nwords;
-
-	for (i = 0; i < n; i++, addr++) {
-		t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, OBQDBGADDR_V(addr) |
-			     OBQDBGEN_F);
-		err = t4_wait_op_done(adap, CIM_OBQ_DBG_CFG_A, OBQDBGBUSY_F, 0,
-				      2, 1);
-		if (err)
-			return err;
-		*data++ = t4_read_reg(adap, CIM_OBQ_DBG_DATA_A);
+	for (i = 0; i < n; i++, addr++, data++) {
+		ret = t4_read_cim_obq_data_core(adap, coreid, addr, data);
+		if (ret < 0)
+			return ret;
 	}
+
 	t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, 0);
 	return i;
 }
 
+/*
+ * t4_read_cim_obq - read the contents of a CIM outbound queue
+ * @adap: the adapter
+ * @qid: the queue index
+ * @data: where to store the queue contents
+ * @n: capacity of @data in 32-bit words
+ *
+ * Reads the contents of the selected CIM queue starting at address 0 up
+ * to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
+ * error and the number of 32-bit words actually read on success.
+ */
+int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
+{
+	return t4_read_cim_obq_core(adap, 0, qid, data, n);
+}
+
+/*
+ * t4_cim_read_core - read a block from CIM internal address space
+ * of a control register group on specific core.
+ * @adap: the adapter
+ * @group: the control register group to select for read
+ * @coreid: the uP coreid
+ * @addr: the start address within the CIM address space
+ * @n: number of words to read
+ * @valp: where to store the result
+ *
+ * Reads a block of 4-byte words from the CIM intenal address space
+ * of a control register @group on a specific @coreid.
+ */
+int t4_cim_read_core(struct adapter *adap, u8 group, u8 coreid,
+		     unsigned int addr, unsigned int n, unsigned int *valp)
+{
+	unsigned int hostbusy, v = 0;
+	int ret = 0;
+
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		hostbusy = T7_HOSTBUSY_F;
+		v = HOSTGRPSEL_V(group) | HOSTCORESEL_V(coreid);
+	} else {
+		hostbusy = HOSTBUSY_F;
+	}
+
+	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & hostbusy)
+		return -EBUSY;
+
+	for (; !ret && n--; addr += 4) {
+		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | v);
+		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, hostbusy, 0, 5,
+				      2);
+		if (!ret)
+			*valp++ = t4_read_reg(adap, CIM_HOST_ACC_DATA_A);
+	}
+
+	return ret;
+}
+
 /**
  *	t4_cim_read - read a block from CIM internal address space
  *	@adap: the adapter
@@ -9862,18 +11414,48 @@ int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
 int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
 		unsigned int *valp)
 {
+	return t4_cim_read_core(adap, 0, 0, addr, n, valp);
+}
+
+/**
+ *      t4_cim_write_core - write a block into CIM internal address space
+ *      of a control register group on specific core.
+ *      @adap: the adapter
+ *      @group: the control register group to select for write
+ *      @coreid: the uP coreid
+ *      @addr: the start address within the CIM address space
+ *      @n: number of words to write
+ *      @valp: set of values to write
+ *
+ *      Writes a block of 4-byte words into the CIM intenal address space
+ *      of a control register @group on a specific @coreid.
+ */
+int t4_cim_write_core(struct adapter *adap, u8 group, u8 coreid,
+		      unsigned int addr, unsigned int n,
+		      const unsigned int *valp)
+{
+	unsigned int hostbusy, v;
 	int ret = 0;
 
-	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
+	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7) {
+		hostbusy = T7_HOSTBUSY_F;
+		v = T7_HOSTWRITE_F | HOSTGRPSEL_V(group) |
+		    HOSTCORESEL_V(coreid);
+	} else {
+		hostbusy = HOSTBUSY_F;
+		v = HOSTWRITE_F;
+	}
+
+	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & hostbusy)
 		return -EBUSY;
 
 	for ( ; !ret && n--; addr += 4) {
-		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr);
-		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
-				      0, 5, 2);
-		if (!ret)
-			*valp++ = t4_read_reg(adap, CIM_HOST_ACC_DATA_A);
+		t4_write_reg(adap, CIM_HOST_ACC_DATA_A, *valp++);
+		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | v);
+		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, hostbusy, 0, 5,
+				      2);
 	}
+
 	return ret;
 }
 
@@ -9889,52 +11471,40 @@ int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
 int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
 		 const unsigned int *valp)
 {
-	int ret = 0;
-
-	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
-		return -EBUSY;
-
-	for ( ; !ret && n--; addr += 4) {
-		t4_write_reg(adap, CIM_HOST_ACC_DATA_A, *valp++);
-		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | HOSTWRITE_F);
-		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
-				      0, 5, 2);
-	}
-	return ret;
-}
-
-static int t4_cim_write1(struct adapter *adap, unsigned int addr,
-			 unsigned int val)
-{
-	return t4_cim_write(adap, addr, 1, &val);
+	return t4_cim_write_core(adap, 0, 0, addr, n, valp);
 }
 
 /**
- *	t4_cim_read_la - read CIM LA capture buffer
- *	@adap: the adapter
- *	@la_buf: where to store the LA data
- *	@wrptr: the HW write pointer within the capture buffer
+ *      t4_cim_read_la_core - read CIM LA capture buffer on specific core
+ *      @adap: the adapter
+ *      @coreid: uP coreid
+ *      @la_buf: where to store the LA data
+ *      @wrptr: the HW write pointer within the capture buffet4_init_portinfor
  *
- *	Reads the contents of the CIM LA buffer with the most recent entry at
- *	the end	of the returned data and with the entry at @wrptr first.
- *	We try to leave the LA in the running state we find it in.
+ *      Reads the contents of the CIM LA buffer on a specific @coreid
+ *      with the most recent entry at the end of the returned data
+ *      and with the entry at @wrptr first. We try to leave the LA
+ *      in the running state we find it in.
  */
-int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
+int t4_cim_read_la_core(struct adapter *adap, u8 coreid, u32 *la_buf,
+			u32 *wrptr)
 {
-	int i, ret;
 	unsigned int cfg, val, idx;
+	int i, ret;
 
-	ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
+	ret = t4_cim_read_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1, &cfg);
 	if (ret)
 		return ret;
 
-	if (cfg & UPDBGLAEN_F) {	/* LA is running, freeze it */
-		ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A, 0);
+	if (cfg & UPDBGLAEN_F) { /* LA is running, freeze it */
+		val = 0;
+		ret = t4_cim_write_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1,
+					&val);
 		if (ret)
 			return ret;
 	}
 
-	ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
+	ret = t4_cim_read_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1, &val);
 	if (ret)
 		goto restart;
 
@@ -9943,25 +11513,29 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
 		*wrptr = idx;
 
 	for (i = 0; i < adap->params.cim_la_size; i++) {
-		ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
-				    UPDBGLARDPTR_V(idx) | UPDBGLARDEN_F);
+		val = UPDBGLARDPTR_V(idx) | UPDBGLARDEN_F;
+		ret = t4_cim_write_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1,
+					&val);
 		if (ret)
 			break;
-		ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
+		ret = t4_cim_read_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1,
+				       &val);
 		if (ret)
 			break;
 		if (val & UPDBGLARDEN_F) {
 			ret = -ETIMEDOUT;
 			break;
 		}
-		ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]);
+		ret = t4_cim_read_core(adap, 1, coreid, UP_UP_DBG_LA_DATA_A, 1,
+				       &la_buf[i]);
 		if (ret)
 			break;
 
 		/* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to
 		 * identify the 32-bit portion of the full 312-bit data
 		 */
-		if (is_t6(adap->params.chip) && (idx & 0xf) >= 9)
+		if ((CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) &&
+		    (idx & 0xf) >= 9)
 			idx = (idx & 0xff0) + 0x10;
 		else
 			idx++;
@@ -9970,14 +11544,33 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
 	}
 restart:
 	if (cfg & UPDBGLAEN_F) {
-		int r = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
-				      cfg & ~UPDBGLARDEN_F);
+		int r;
+
+		val = cfg & ~UPDBGLARDEN_F;
+		r = t4_cim_write_core(adap, 1, coreid, UP_UP_DBG_LA_CFG_A, 1,
+				      &val);
 		if (!ret)
 			ret = r;
 	}
+
 	return ret;
 }
 
+/**
+ *	t4_cim_read_la - read CIM LA capture buffer
+ *	@adap: the adapter
+ *	@la_buf: where to store the LA data
+ *	@wrptr: the HW write pointer within the capture buffer
+ *
+ *	Reads the contents of the CIM LA buffer with the most recent entry at
+ *	the end	of the returned data and with the entry at @wrptr first.
+ *	We try to leave the LA in the running state we find it in.
+ */
+int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
+{
+	return t4_cim_read_la_core(adap, 0, la_buf, wrptr);
+}
+
 /**
  *	t4_tp_read_la - read TP LA capture buffer
  *	@adap: the adapter
@@ -10162,10 +11755,10 @@ void t4_idma_monitor(struct adapter *adapter,
  */
 int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
 {
+	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+	unsigned int flash_cfg_start_sec, flash_cfg_size;
 	int ret, i, n, cfg_addr;
 	unsigned int addr;
-	unsigned int flash_cfg_start_sec;
-	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
 
 	cfg_addr = t4_flash_cfg_addr(adap);
 	if (cfg_addr < 0)
@@ -10174,14 +11767,15 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
 	addr = cfg_addr;
 	flash_cfg_start_sec = addr / SF_SEC_SIZE;
 
-	if (size > FLASH_CFG_MAX_SIZE) {
+	flash_cfg_size = t4_flash_location_size(adap, FLASH_LOC_CFG);
+
+	if (size > flash_cfg_size) {
 		dev_err(adap->pdev_dev, "cfg file too large, max is %u bytes\n",
-			FLASH_CFG_MAX_SIZE);
+			flash_cfg_size);
 		return -EFBIG;
 	}
 
-	i = DIV_ROUND_UP(FLASH_CFG_MAX_SIZE,	/* # of sectors spanned */
-			 sf_sec_size);
+	i = DIV_ROUND_UP(flash_cfg_size, sf_sec_size);	/* # of sectors spanned */
 	ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
 				     flash_cfg_start_sec + i - 1);
 	/* If size == 0 then we're simply erasing the FLASH sectors associated
@@ -10345,6 +11939,8 @@ int t4_sge_ctxt_rd(struct adapter *adap, unsigned int mbox, unsigned int cid,
 		data[3] = be32_to_cpu(c.u.idctxt.ctxt_data3);
 		data[4] = be32_to_cpu(c.u.idctxt.ctxt_data4);
 		data[5] = be32_to_cpu(c.u.idctxt.ctxt_data5);
+		if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+			data[6] = be32_to_cpu(c.u.idctxt.ctxt_data6);
 	}
 	return ret;
 }
@@ -10363,13 +11959,21 @@ int t4_sge_ctxt_rd_bd(struct adapter *adap, unsigned int cid,
 		      enum ctxt_type ctype, u32 *data)
 {
 	int i, ret;
+	u32 end;
 
 	t4_write_reg(adap, SGE_CTXT_CMD_A, CTXTQID_V(cid) | CTXTTYPE_V(ctype));
 	ret = t4_wait_op_done(adap, SGE_CTXT_CMD_A, BUSY_F, 0, 3, 1);
-	if (!ret)
-		for (i = SGE_CTXT_DATA0_A; i <= SGE_CTXT_DATA5_A; i += 4)
-			*data++ = t4_read_reg(adap, i);
-	return ret;
+	if (ret)
+		return ret;
+
+	end = CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7 ?
+		      SGE_CTXT_DATA6_A :
+		      SGE_CTXT_DATA5_A;
+
+	for (i = SGE_CTXT_DATA0_A; i <= end; i += 4)
+		*data++ = t4_read_reg(adap, i);
+
+	return 0;
 }
 
 int t4_sched_params(struct adapter *adapter, u8 type, u8 level, u8 mode,
@@ -10416,19 +12020,23 @@ int t4_sched_params(struct adapter *adapter, u8 type, u8 level, u8 mode,
  *	Reads the I2C data from the indicated device and location.
  */
 int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
-	      unsigned int devid, unsigned int offset,
-	      unsigned int len, u8 *buf)
+	      unsigned int devid, unsigned int offset, unsigned int len,
+	      u8 *buf)
 {
 	struct fw_ldst_cmd ldst_cmd, ldst_rpl;
 	unsigned int i2c_max = sizeof(ldst_cmd.u.i2c.data);
 	int ret = 0;
 
-	if (len > I2C_PAGE_SIZE)
+	if (len > I2C_PAGE_SIZE) {
+		dev_err(adap->pdev_dev, "Incorrect page size len %d\n", len);
 		return -EINVAL;
+	}
 
 	/* Dont allow reads that spans multiple pages */
-	if (offset < I2C_PAGE_SIZE && offset + len > I2C_PAGE_SIZE)
+	if (offset < I2C_PAGE_SIZE && offset + len > I2C_PAGE_SIZE) {
+		dev_err(adap->pdev_dev, "Read across the page\n");
 		return -EINVAL;
+	}
 
 	memset(&ldst_cmd, 0, sizeof(ldst_cmd));
 	ldst_cmd.op_to_addrspace =
@@ -10581,16 +12189,17 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
 	unsigned int boot_sector = (boot_addr * 1024);
 	struct cxgb4_pci_exp_rom_header *header;
 	struct cxgb4_pcir_data *pcir_header;
-	int pcir_offset;
+	int pcir_offset, ret, addr;
 	unsigned int i;
 	u16 device_id;
-	int ret, addr;
 
-	/**
-	 * Make sure the boot image does not encroach on the firmware region
+	/*
+	 * Make sure the boot image does not exceed its available space.
 	 */
-	if ((boot_sector + size) >> 16 > FLASH_FW_START_SEC) {
-		dev_err(adap->pdev_dev, "boot image encroaching on firmware region\n");
+	if (!t4_flash_location_in_range(adap, FLASH_LOC_BOOT_AREA,
+					boot_sector + size)) {
+		dev_err(adap->pdev_dev,
+			"boot data is larger than available BOOT area\n");
 		return -EFBIG;
 	}
 
@@ -10632,7 +12241,9 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
 	 * and Boot configuration data sections. These 3 boot sections span
 	 * sectors 0 to 7 in flash and live right before the FW image location.
 	 */
-	i = DIV_ROUND_UP(size ? size : FLASH_FW_START,  sf_sec_size);
+	i = DIV_ROUND_UP(size ? size :
+			 t4_flash_location_size(adap, FLASH_LOC_BOOT_AREA),
+			 sf_sec_size);
 	ret = t4_flash_erase_sectors(adap, boot_sector >> 16,
 				     (boot_sector >> 16) + i - 1);
 
@@ -10693,35 +12304,37 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
  */
 static int t4_flash_bootcfg_addr(struct adapter *adapter)
 {
+	int ret = t4_flash_location_end(adapter, FLASH_LOC_BOOTCFG);
 	/**
 	 * If the device FLASH isn't large enough to hold a Firmware
 	 * Configuration File, return an error.
 	 */
-	if (adapter->params.sf_size <
-	    FLASH_BOOTCFG_START + FLASH_BOOTCFG_MAX_SIZE)
+	if (ret < 0 || adapter->params.sf_size < ret)
 		return -ENOSPC;
 
-	return FLASH_BOOTCFG_START;
+	return t4_flash_location_start(adapter, FLASH_LOC_BOOTCFG);
 }
 
 int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
 {
 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+	unsigned int boot_cfg_start_sec, boot_cfg_size;
 	struct cxgb4_bootcfg_data *header;
-	unsigned int flash_cfg_start_sec;
-	unsigned int addr, npad;
 	int ret, i, n, cfg_addr;
+	unsigned int addr, npad;
 
 	cfg_addr = t4_flash_bootcfg_addr(adap);
 	if (cfg_addr < 0)
 		return cfg_addr;
 
 	addr = cfg_addr;
-	flash_cfg_start_sec = addr / SF_SEC_SIZE;
+	boot_cfg_start_sec = addr / SF_SEC_SIZE;
+	boot_cfg_size = t4_flash_location_size(adap, FLASH_LOC_BOOTCFG);
 
-	if (size > FLASH_BOOTCFG_MAX_SIZE) {
-		dev_err(adap->pdev_dev, "bootcfg file too large, max is %u bytes\n",
-			FLASH_BOOTCFG_MAX_SIZE);
+	if (size > boot_cfg_size) {
+		dev_err(adap->pdev_dev,
+			"bootcfg file too large, max is %u bytes\n",
+			boot_cfg_size);
 		return -EFBIG;
 	}
 
@@ -10732,10 +12345,9 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
 		goto out;
 	}
 
-	i = DIV_ROUND_UP(FLASH_BOOTCFG_MAX_SIZE,
-			 sf_sec_size);
-	ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
-				     flash_cfg_start_sec + i - 1);
+	i = DIV_ROUND_UP(boot_cfg_size, sf_sec_size); /* # of sectors spanned */
+	ret = t4_flash_erase_sectors(adap, boot_cfg_start_sec,
+				     boot_cfg_start_sec + i - 1);
 
 	/**
 	 * If size == 0 then we're simply erasing the FLASH sectors associated
-- 
2.39.1


  parent reply	other threads:[~2026-06-06 18:21 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-07  3:52 [PATCH net-next v1 0/10] cxgb4: Add Chelsio T7 support Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 01/10] cxgb4: Add T7 register definitions and core structures Potnuri Bharat Teja
2026-06-07  7:02   ` Andrew Lunn
2026-06-07  3:52 ` [PATCH net-next v1 02/10] cxgb4: Add T7 chip type identification and HW constants Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 03/10] cxgb4: Add T7 CPL messages, FW constants, and PCI IDs Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 04/10] cxgb4: Add versioned structures and scratch buffs Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 05/10] cxgb4: Add T7 indirect regs and update library Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 06/10] cxgb4: Move PCI initialization logic to cxgb4_pci.c Potnuri Bharat Teja
2026-06-07  3:52 ` Potnuri Bharat Teja [this message]
2026-06-07  3:52 ` [PATCH net-next v1 08/10] cxgb4: Update driver lifecycle and peripherals for T7 Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 09/10] cxgb4: Update debugfs interface for T7 versioned structures Potnuri Bharat Teja
2026-06-07  3:52 ` [PATCH net-next v1 10/10] cxgb4: Update SGE path and filtering logic for T7 Potnuri Bharat Teja
2026-06-08 21:13 ` [PATCH net-next v1 0/10] cxgb4: Add Chelsio T7 support Jakub Kicinski
2026-06-09 10:50   ` Potnuri Bharat Teja
2026-06-09 22:36     ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260607035220.528439-8-bharat@chelsio.com \
    --to=bharat@chelsio.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox