Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8caa1e84 authored by Vipul Pandya's avatar Vipul Pandya Committed by Roland Dreier
Browse files

cxgb4: Common platform specific changes for DB Drop Recovery



Add platform-specific callback functions for interrupts.  This is
needed to do a single read-clear of the CAUSE register and then call
out to platform specific functions for DB threshold interrupts and DB
drop interrupts.

Add t4_mem_win_read_len() - mem-window reads for arbitrary lengths.
This is used to read the CIDX/PIDX values from EC contexts during DB
drop recovery.

Add t4_fwaddrspace_write() - sends addrspace write cmds to the fw.
Needed to flush the sge eq context cache.

Signed-off-by: default avatarVipul Pandya <vipul@chelsio.com>
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 881806bc
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -723,4 +723,7 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter);
void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len);
int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
			 u32 addr, u32 val);
#endif /* __CXGB4_H__ */
#endif /* __CXGB4_H__ */
+58 −11
Original line number Original line Diff line number Diff line
@@ -868,11 +868,14 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
}
}


typedef void (*int_handler_t)(struct adapter *adap);

struct intr_info {
struct intr_info {
	unsigned int mask;       /* bits to check in interrupt status */
	unsigned int mask;       /* bits to check in interrupt status */
	const char *msg;         /* message to print or NULL */
	const char *msg;         /* message to print or NULL */
	short stat_idx;          /* stat counter to increment or -1 */
	short stat_idx;          /* stat counter to increment or -1 */
	unsigned short fatal;    /* whether the condition reported is fatal */
	unsigned short fatal;    /* whether the condition reported is fatal */
	int_handler_t int_handler; /* platform-specific int handler */
};
};


/**
/**
@@ -905,6 +908,8 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
		} else if (acts->msg && printk_ratelimit())
		} else if (acts->msg && printk_ratelimit())
			dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
			dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
				 status & acts->mask);
				 status & acts->mask);
		if (acts->int_handler)
			acts->int_handler(adapter);
		mask |= acts->mask;
		mask |= acts->mask;
	}
	}
	status &= mask;
	status &= mask;
@@ -1013,9 +1018,9 @@ static void sge_intr_handler(struct adapter *adapter)
		{ ERR_INVALID_CIDX_INC,
		{ ERR_INVALID_CIDX_INC,
		  "SGE GTS CIDX increment too large", -1, 0 },
		  "SGE GTS CIDX increment too large", -1, 0 },
		{ ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
		{ ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
		{ F_DBFIFO_LP_INT, NULL, -1, 0 },
		{ F_DBFIFO_LP_INT, NULL, -1, 0, t4_db_full },
		{ F_DBFIFO_HP_INT, NULL, -1, 0 },
		{ F_DBFIFO_HP_INT, NULL, -1, 0, t4_db_full },
		{ ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
		{ F_ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped },
		{ ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
		{ ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
		  "SGE IQID > 1023 received CPL for FL", -1, 0 },
		  "SGE IQID > 1023 received CPL for FL", -1, 0 },
		{ ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
		{ ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
@@ -1044,12 +1049,6 @@ static void sge_intr_handler(struct adapter *adapter)
		t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
		t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
	}
	}


	err = t4_read_reg(adapter, A_SGE_INT_CAUSE3);
	if (err & (F_DBFIFO_HP_INT|F_DBFIFO_LP_INT))
		t4_db_full(adapter);
	if (err & F_ERR_DROPPED_DB)
		t4_db_dropped(adapter);

	if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
	if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
	    v != 0)
	    v != 0)
		t4_fatal_err(adapter);
		t4_fatal_err(adapter);
@@ -1995,6 +1994,54 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
	(var).retval_len16 = htonl(FW_LEN16(var)); \
	(var).retval_len16 = htonl(FW_LEN16(var)); \
} while (0)
} while (0)


int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
			  u32 addr, u32 val)
{
	struct fw_ldst_cmd c;

	memset(&c, 0, sizeof(c));
	c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST |
			    F_FW_CMD_WRITE |
			    V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE));
	c.cycles_to_len16 = htonl(FW_LEN16(c));
	c.u.addrval.addr = htonl(addr);
	c.u.addrval.val = htonl(val);

	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
}

/*
 *     t4_mem_win_read_len - read memory through PCIE memory window
 *     @adap: the adapter
 *     @addr: address of first byte requested aligned on 32b.
 *     @data: len bytes to hold the data read
 *     @len: amount of data to read from window.  Must be <=
 *            MEMWIN0_APERATURE after adjusting for 16B alignment
 *            requirements of the the memory window.
 *
 *     Read len bytes of data from MC starting at @addr.
 */
int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
{
	int i;
	int off;

	/*
	 * Align on a 16B boundary.
	 */
	off = addr & 15;
	if ((addr & 3) || (len + off) > MEMWIN0_APERTURE)
		return -EINVAL;

	t4_write_reg(adap, A_PCIE_MEM_ACCESS_OFFSET, addr & ~15);
	t4_read_reg(adap, A_PCIE_MEM_ACCESS_OFFSET);

	for (i = 0; i < len; i += 4)
		*data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));

	return 0;
}

/**
/**
 *	t4_mdio_rd - read a PHY register through MDIO
 *	t4_mdio_rd - read a PHY register through MDIO
 *	@adap: the adapter
 *	@adap: the adapter