Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * QLogic Fibre Channel HBA Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (c)  2003-2014 QLogic Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include "qla_def.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include "qla_tmpl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #define ISPREG(vha)	(&(vha)->hw->iobase->isp24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #define IOBAR(reg)	offsetof(typeof(*(reg)), iobase_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #define IOBASE(vha)	IOBAR(ISPREG(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) qla27xx_insert16(uint16_t value, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 		buf += *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 		*(__le16 *)buf = cpu_to_le16(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 	*len += sizeof(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) qla27xx_insert32(uint32_t value, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 		buf += *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 		*(__le32 *)buf = cpu_to_le32(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	*len += sizeof(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	if (buf && mem && size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 		buf += *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 		memcpy(buf, mem, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	*len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) qla27xx_read8(void __iomem *window, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	uint8_t value = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 		value = rd_reg_byte(window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	qla27xx_insert32(value, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) qla27xx_read16(void __iomem *window, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	uint16_t value = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 		value = rd_reg_word(window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	qla27xx_insert32(value, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) qla27xx_read32(void __iomem *window, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	uint32_t value = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		value = rd_reg_dword(window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	qla27xx_insert32(value, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) static inline void (*qla27xx_read_vector(uint width))(void __iomem*, void *, ulong *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	    (width == 1) ? qla27xx_read8 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	    (width == 2) ? qla27xx_read16 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 			   qla27xx_read32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) qla27xx_read_reg(__iomem struct device_reg_24xx *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	uint offset, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	void __iomem *window = (void __iomem *)reg + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	qla27xx_read32(window, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) qla27xx_write_reg(__iomem struct device_reg_24xx *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	uint offset, uint32_t data, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		void __iomem *window = (void __iomem *)reg + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		wrt_reg_dword(window, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) qla27xx_read_window(__iomem struct device_reg_24xx *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	uint32_t addr, uint offset, uint count, uint width, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	void __iomem *window = (void __iomem *)reg + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	void (*readn)(void __iomem*, void *, ulong *) = qla27xx_read_vector(width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	qla27xx_write_reg(reg, IOBAR(reg), addr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	while (count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		qla27xx_insert32(addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		readn(window, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		window += width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		addr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) static inline struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) qla27xx_next_entry(struct qla27xx_fwdt_entry *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	return (void *)ent + le32_to_cpu(ent->hdr.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	ql_dbg(ql_dbg_misc, vha, 0xd100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	    "%s: nop [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	ql_dbg(ql_dbg_misc, vha, 0xd1ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	    "%s: end [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	/* terminate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	ulong addr = le32_to_cpu(ent->t256.base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	uint offset = ent->t256.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	ulong count = le16_to_cpu(ent->t256.reg_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	uint width = ent->t256.reg_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	ql_dbg(ql_dbg_misc, vha, 0xd200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	    "%s: rdio t1 [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	ulong addr = le32_to_cpu(ent->t257.base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	uint offset = ent->t257.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	ulong data = le32_to_cpu(ent->t257.write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	ql_dbg(ql_dbg_misc, vha, 0xd201,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	    "%s: wrio t1 [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	qla27xx_write_reg(ISPREG(vha), offset, data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	uint banksel = ent->t258.banksel_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	ulong bank = le32_to_cpu(ent->t258.bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	ulong addr = le32_to_cpu(ent->t258.base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	uint offset = ent->t258.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	uint count = le16_to_cpu(ent->t258.reg_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	uint width = ent->t258.reg_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	ql_dbg(ql_dbg_misc, vha, 0xd202,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	    "%s: rdio t2 [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	ulong addr = le32_to_cpu(ent->t259.base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	uint banksel = ent->t259.banksel_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	ulong bank = le32_to_cpu(ent->t259.bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	uint offset = ent->t259.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	ulong data = le32_to_cpu(ent->t259.write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	ql_dbg(ql_dbg_misc, vha, 0xd203,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	    "%s: wrio t2 [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	qla27xx_write_reg(ISPREG(vha), offset, data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	uint offset = ent->t260.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	ql_dbg(ql_dbg_misc, vha, 0xd204,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	    "%s: rdpci [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	qla27xx_insert32(offset, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	qla27xx_read_reg(ISPREG(vha), offset, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	uint offset = ent->t261.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	ulong data = le32_to_cpu(ent->t261.write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	ql_dbg(ql_dbg_misc, vha, 0xd205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	    "%s: wrpci [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	qla27xx_write_reg(ISPREG(vha), offset, data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	uint area = ent->t262.ram_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	ulong start = le32_to_cpu(ent->t262.start_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	ulong end = le32_to_cpu(ent->t262.end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	ulong dwords;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	ql_dbg(ql_dbg_misc, vha, 0xd206,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	    "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	if (area == T262_RAM_AREA_CRITICAL_RAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	} else if (area == T262_RAM_AREA_EXTERNAL_RAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		end = vha->hw->fw_memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			ent->t262.end_addr = cpu_to_le32(end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	} else if (area == T262_RAM_AREA_SHARED_RAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		start = vha->hw->fw_shared_ram_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		end = vha->hw->fw_shared_ram_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			ent->t262.start_addr = cpu_to_le32(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			ent->t262.end_addr = cpu_to_le32(end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	} else if (area == T262_RAM_AREA_DDR_RAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		start = vha->hw->fw_ddr_ram_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		end = vha->hw->fw_ddr_ram_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			ent->t262.start_addr = cpu_to_le32(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			ent->t262.end_addr = cpu_to_le32(end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	} else if (area == T262_RAM_AREA_MISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			ent->t262.start_addr = cpu_to_le32(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			ent->t262.end_addr = cpu_to_le32(end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		ql_dbg(ql_dbg_misc, vha, 0xd022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		    "%s: unknown area %x\n", __func__, area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	if (end < start || start == 0 || end == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		ql_dbg(ql_dbg_misc, vha, 0xd023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		    "%s: unusable range (start=%lx end=%lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		    __func__, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	dwords = end - start + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		buf += *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		rc = qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		if (rc != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 			ql_dbg(ql_dbg_async, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			    "%s: dump ram MB failed. Area %xh start %lxh end %lxh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			    __func__, area, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			return INVALID_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	*len += dwords * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	uint type = ent->t263.queue_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	uint count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	uint length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd207,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	    "%s: getq(%x) [%lx]\n", __func__, type, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	if (type == T263_QUEUE_TYPE_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		for (i = 0; i < vha->hw->max_req_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 			struct req_que *req = vha->hw->req_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			if (req || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 				length = req ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				    req->length : REQUEST_ENTRY_CNT_24XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 				qla27xx_insert16(i, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				qla27xx_insert16(length, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				qla27xx_insertbuf(req ? req->ring : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 				    length * sizeof(*req->ring), buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 				count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	} else if (type == T263_QUEUE_TYPE_RSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			if (rsp || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 				length = rsp ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 				    rsp->length : RESPONSE_ENTRY_CNT_MQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 				qla27xx_insert16(i, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 				qla27xx_insert16(length, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				qla27xx_insertbuf(rsp ? rsp->ring : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 				    length * sizeof(*rsp->ring), buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 				count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	} else if (QLA_TGT_MODE_ENABLED() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	    ent->t263.queue_type == T263_QUEUE_TYPE_ATIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		struct atio *atr = ha->tgt.atio_ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		if (atr || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			length = ha->tgt.atio_q_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			qla27xx_insert16(0, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			qla27xx_insert16(length, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			qla27xx_insertbuf(atr, length * sizeof(*atr), buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		ql_dbg(ql_dbg_misc, vha, 0xd026,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		    "%s: unknown queue %x\n", __func__, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		if (count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			ent->t263.num_queues = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	ql_dbg(ql_dbg_misc, vha, 0xd208,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	    "%s: getfce [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	if (vha->hw->fce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			ent->t264.fce_trace_size = FCE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			ent->t264.write_pointer = vha->hw->fce_wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			ent->t264.base_pointer = vha->hw->fce_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			ent->t264.fce_enable_mb0 = vha->hw->fce_mb[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			ent->t264.fce_enable_mb2 = vha->hw->fce_mb[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			ent->t264.fce_enable_mb3 = vha->hw->fce_mb[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			ent->t264.fce_enable_mb4 = vha->hw->fce_mb[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			ent->t264.fce_enable_mb5 = vha->hw->fce_mb[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			ent->t264.fce_enable_mb6 = vha->hw->fce_mb[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		qla27xx_insertbuf(vha->hw->fce, FCE_SIZE, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		ql_dbg(ql_dbg_misc, vha, 0xd027,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		    "%s: missing fce\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd209,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	    "%s: pause risc [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		qla24xx_pause_risc(ISPREG(vha), vha->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	ql_dbg(ql_dbg_misc, vha, 0xd20a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	    "%s: reset risc [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		WARN_ON_ONCE(qla24xx_soft_reset(vha->hw) != QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	uint offset = ent->t267.pci_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	ulong data = le32_to_cpu(ent->t267.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	ql_dbg(ql_dbg_misc, vha, 0xd20b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	    "%s: dis intr [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	qla27xx_write_reg(ISPREG(vha), offset, data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	ql_dbg(ql_dbg_misc, vha, 0xd20c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	    "%s: gethb(%x) [%lx]\n", __func__, ent->t268.buf_type, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	switch (ent->t268.buf_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	case T268_BUF_TYPE_EXTD_TRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		if (vha->hw->eft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 			if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 				ent->t268.buf_size = EFT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 				ent->t268.start_addr = vha->hw->eft_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			qla27xx_insertbuf(vha->hw->eft, EFT_SIZE, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			ql_dbg(ql_dbg_misc, vha, 0xd028,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			    "%s: missing eft\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	case T268_BUF_TYPE_EXCH_BUFOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		if (vha->hw->exchoffld_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				ent->t268.buf_size = vha->hw->exchoffld_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				ent->t268.start_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 					vha->hw->exchoffld_buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			qla27xx_insertbuf(vha->hw->exchoffld_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			    vha->hw->exchoffld_size, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			ql_dbg(ql_dbg_misc, vha, 0xd028,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			    "%s: missing exch offld\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	case T268_BUF_TYPE_EXTD_LOGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		if (vha->hw->exlogin_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 				ent->t268.buf_size = vha->hw->exlogin_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 				ent->t268.start_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 					vha->hw->exlogin_buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			qla27xx_insertbuf(vha->hw->exlogin_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			    vha->hw->exlogin_size, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			ql_dbg(ql_dbg_misc, vha, 0xd028,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			    "%s: missing ext login\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	case T268_BUF_TYPE_REQ_MIRROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	case T268_BUF_TYPE_RSP_MIRROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		 * Mirror pointers are not implemented in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		 * driver, instead shadow pointers are used by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		 * the drier. Skip these entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		ql_dbg(ql_dbg_async, vha, 0xd02b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		    "%s: unknown buffer %x\n", __func__, ent->t268.buf_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	ql_dbg(ql_dbg_misc, vha, 0xd20d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	    "%s: scratch [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	qla27xx_insert32(0xaaaaaaaa, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	qla27xx_insert32(0xbbbbbbbb, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	qla27xx_insert32(0xcccccccc, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	qla27xx_insert32(0xdddddddd, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	qla27xx_insert32(*len + sizeof(uint32_t), buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		ent->t269.scratch_size = 5 * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	ulong addr = le32_to_cpu(ent->t270.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	ulong dwords = le32_to_cpu(ent->t270.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	ql_dbg(ql_dbg_misc, vha, 0xd20e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	    "%s: rdremreg [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	qla27xx_write_reg(ISPREG(vha), IOBASE_ADDR, 0x40, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	while (dwords--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		qla27xx_write_reg(ISPREG(vha), 0xc0, addr|0x80000000, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		qla27xx_insert32(addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		qla27xx_read_reg(ISPREG(vha), 0xc4, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		addr += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	ulong addr = le32_to_cpu(ent->t271.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	ulong data = le32_to_cpu(ent->t271.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	ql_dbg(ql_dbg_misc, vha, 0xd20f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	    "%s: wrremreg [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), 0x40, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	qla27xx_write_reg(ISPREG(vha), 0xc4, data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	qla27xx_write_reg(ISPREG(vha), 0xc0, addr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	ulong dwords = le32_to_cpu(ent->t272.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	ulong start = le32_to_cpu(ent->t272.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	ql_dbg(ql_dbg_misc, vha, 0xd210,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	    "%s: rdremram [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		ql_dbg(ql_dbg_misc, vha, 0xd02c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		    "%s: @%lx -> (%lx dwords)\n", __func__, start, dwords);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		buf += *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		qla27xx_dump_mpi_ram(vha->hw, start, buf, dwords, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	*len += dwords * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	ulong dwords = le32_to_cpu(ent->t273.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	ulong addr = le32_to_cpu(ent->t273.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	uint32_t value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	ql_dbg(ql_dbg_misc, vha, 0xd211,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	    "%s: pcicfg [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	while (dwords--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		value = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		if (pci_read_config_dword(vha->hw->pdev, addr, &value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			ql_dbg(ql_dbg_misc, vha, 0xd02d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			    "%s: failed pcicfg read at %lx\n", __func__, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		qla27xx_insert32(addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		qla27xx_insert32(value, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		addr += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ulong type = ent->t274.queue_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	uint count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	uint i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd212,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	    "%s: getqsh(%lx) [%lx]\n", __func__, type, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	if (type == T274_QUEUE_TYPE_REQ_SHAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		for (i = 0; i < vha->hw->max_req_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			struct req_que *req = vha->hw->req_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			if (req || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 				qla27xx_insert16(i, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				qla27xx_insert16(1, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				qla27xx_insert32(req && req->out_ptr ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 				    *req->out_ptr : 0, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 				count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	} else if (type == T274_QUEUE_TYPE_RSP_SHAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			if (rsp || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 				qla27xx_insert16(i, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				qla27xx_insert16(1, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				qla27xx_insert32(rsp && rsp->in_ptr ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				    *rsp->in_ptr : 0, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 				count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	} else if (QLA_TGT_MODE_ENABLED() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	    ent->t274.queue_type == T274_QUEUE_TYPE_ATIO_SHAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		struct atio *atr = ha->tgt.atio_ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		if (atr || !buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			qla27xx_insert16(0, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			qla27xx_insert16(1, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			qla27xx_insert32(ha->tgt.atio_q_in ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			    readl(ha->tgt.atio_q_in) : 0, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		ql_dbg(ql_dbg_misc, vha, 0xd02f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		    "%s: unknown queue %lx\n", __func__, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		if (count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			ent->t274.num_queues = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	ulong offset = offsetof(typeof(*ent), t275.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	ulong length = le32_to_cpu(ent->t275.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	ulong size = le32_to_cpu(ent->hdr.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	void *buffer = ent->t275.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd213,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	    "%s: buffer(%lx) [%lx]\n", __func__, length, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	if (!length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		ql_dbg(ql_dbg_misc, vha, 0xd020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		    "%s: buffer zero length\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	if (offset + length > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		length = size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		ql_dbg(ql_dbg_misc, vha, 0xd030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		    "%s: buffer overflow, truncate [%lx]\n", __func__, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		ent->t275.length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	qla27xx_insertbuf(buffer, length, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)     struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	    "%s: cond [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		ulong cond1 = le32_to_cpu(ent->t276.cond1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		ulong cond2 = le32_to_cpu(ent->t276.cond2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		uint type = vha->hw->pdev->device >> 4 & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		uint func = vha->hw->port_no & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		if (type != cond1 || func != cond2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			struct qla27xx_fwdt_template *tmp = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			tmp->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			ent = qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)     struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	ulong cmd_addr = le32_to_cpu(ent->t277.cmd_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	ulong wr_cmd_data = le32_to_cpu(ent->t277.wr_cmd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	ulong data_addr = le32_to_cpu(ent->t277.data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	    "%s: rdpep [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	qla27xx_insert32(wr_cmd_data, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	qla27xx_read_reg(ISPREG(vha), data_addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)     struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	ulong cmd_addr = le32_to_cpu(ent->t278.cmd_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	ulong wr_cmd_data = le32_to_cpu(ent->t278.wr_cmd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	ulong data_addr = le32_to_cpu(ent->t278.data_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	ulong wr_data = le32_to_cpu(ent->t278.wr_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	    "%s: wrpep [%lx]\n", __func__, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	qla27xx_write_reg(ISPREG(vha), data_addr, wr_data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) static struct qla27xx_fwdt_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	ulong type = le32_to_cpu(ent->hdr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	ql_dbg(ql_dbg_misc, vha, 0xd2ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	    "%s: other %lx [%lx]\n", __func__, type, *len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	qla27xx_skip_entry(ent, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	return qla27xx_next_entry(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	uint type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	typeof(qla27xx_fwdt_entry_other)(*call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) } qla27xx_fwdt_entry_call[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	{ ENTRY_TYPE_NOP,		qla27xx_fwdt_entry_t0    },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	{ ENTRY_TYPE_TMP_END,		qla27xx_fwdt_entry_t255  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	{ ENTRY_TYPE_RD_IOB_T1,		qla27xx_fwdt_entry_t256  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	{ ENTRY_TYPE_WR_IOB_T1,		qla27xx_fwdt_entry_t257  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	{ ENTRY_TYPE_RD_IOB_T2,		qla27xx_fwdt_entry_t258  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	{ ENTRY_TYPE_WR_IOB_T2,		qla27xx_fwdt_entry_t259  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	{ ENTRY_TYPE_RD_PCI,		qla27xx_fwdt_entry_t260  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	{ ENTRY_TYPE_WR_PCI,		qla27xx_fwdt_entry_t261  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	{ ENTRY_TYPE_RD_RAM,		qla27xx_fwdt_entry_t262  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	{ ENTRY_TYPE_GET_QUEUE,		qla27xx_fwdt_entry_t263  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	{ ENTRY_TYPE_GET_FCE,		qla27xx_fwdt_entry_t264  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	{ ENTRY_TYPE_PSE_RISC,		qla27xx_fwdt_entry_t265  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	{ ENTRY_TYPE_RST_RISC,		qla27xx_fwdt_entry_t266  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	{ ENTRY_TYPE_DIS_INTR,		qla27xx_fwdt_entry_t267  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	{ ENTRY_TYPE_GET_HBUF,		qla27xx_fwdt_entry_t268  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	{ ENTRY_TYPE_SCRATCH,		qla27xx_fwdt_entry_t269  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	{ ENTRY_TYPE_RDREMREG,		qla27xx_fwdt_entry_t270  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	{ ENTRY_TYPE_WRREMREG,		qla27xx_fwdt_entry_t271  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	{ ENTRY_TYPE_RDREMRAM,		qla27xx_fwdt_entry_t272  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	{ ENTRY_TYPE_PCICFG,		qla27xx_fwdt_entry_t273  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	{ ENTRY_TYPE_GET_SHADOW,	qla27xx_fwdt_entry_t274  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	{ ENTRY_TYPE_WRITE_BUF,		qla27xx_fwdt_entry_t275  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	{ ENTRY_TYPE_CONDITIONAL,	qla27xx_fwdt_entry_t276  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	{ ENTRY_TYPE_RDPEPREG,		qla27xx_fwdt_entry_t277  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	{ ENTRY_TYPE_WRPEPREG,		qla27xx_fwdt_entry_t278  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	{ -1,				qla27xx_fwdt_entry_other }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) typeof(qla27xx_fwdt_entry_call->call)(qla27xx_find_entry(uint type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	while (list->type < type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (list->type == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return list->call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	return qla27xx_fwdt_entry_other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) qla27xx_walk_template(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	struct qla27xx_fwdt_entry *ent = (void *)tmp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	    le32_to_cpu(tmp->entry_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	ulong type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	tmp->count = le32_to_cpu(tmp->entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	ql_dbg(ql_dbg_misc, vha, 0xd01a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	    "%s: entry count %u\n", __func__, tmp->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	while (ent && tmp->count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		type = le32_to_cpu(ent->hdr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		ent = qla27xx_find_entry(type)(vha, ent, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		if (!ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		if (ent == INVALID_ENTRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			*len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			ql_dbg(ql_dbg_async, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			    "Unable to capture FW dump");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			goto bailout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (tmp->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		ql_dbg(ql_dbg_misc, vha, 0xd018,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		    "%s: entry count residual=+%u\n", __func__, tmp->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		ql_dbg(ql_dbg_misc, vha, 0xd019,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		    "%s: missing end entry\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) bailout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	cpu_to_le32s(&tmp->count);	/* endianize residual count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	tmp->capture_timestamp = cpu_to_le32(jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) qla27xx_driver_info(struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	uint8_t v[] = { 0, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	WARN_ON_ONCE(sscanf(qla2x00_version_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			    "%hhu.%hhu.%hhu.%hhu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			    v + 0, v + 1, v + 2, v + 3) != 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	tmp->driver_info[0] = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	tmp->driver_info[1] = cpu_to_le32(v[5] << 8 | v[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	tmp->driver_info[2] = __constant_cpu_to_le32(0x12345678);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) qla27xx_firmware_info(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892)     struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	tmp->firmware_version[0] = cpu_to_le32(vha->hw->fw_major_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	tmp->firmware_version[1] = cpu_to_le32(vha->hw->fw_minor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	tmp->firmware_version[2] = cpu_to_le32(vha->hw->fw_subminor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	tmp->firmware_version[3] = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	tmp->firmware_version[4] = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	  vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) ql27xx_edit_template(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	qla27xx_time_stamp(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	qla27xx_driver_info(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	qla27xx_firmware_info(vha, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) static inline uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) qla27xx_template_checksum(void *p, ulong size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	__le32 *buf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	uint64_t sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	size /= sizeof(*buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	for ( ; size--; buf++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		sum += le32_to_cpu(*buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	sum = (sum & 0xffffffff) + (sum >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	return ~sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	return qla27xx_template_checksum(tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		le32_to_cpu(tmp->template_size)) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	return le32_to_cpu(tmp->template_type) == TEMPLATE_TYPE_FWDUMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) static ulong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) qla27xx_execute_fwdt_template(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)     struct qla27xx_fwdt_template *tmp, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	ulong len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	if (qla27xx_fwdt_template_valid(tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		len = le32_to_cpu(tmp->template_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		tmp = memcpy(buf, tmp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		ql27xx_edit_template(vha, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		qla27xx_walk_template(vha, tmp, buf, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) ulong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct qla27xx_fwdt_template *tmp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	ulong len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (qla27xx_fwdt_template_valid(tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		len = le32_to_cpu(tmp->template_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		qla27xx_walk_template(vha, tmp, NULL, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) ulong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) qla27xx_fwdt_template_size(void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	struct qla27xx_fwdt_template *tmp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	return le32_to_cpu(tmp->template_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) qla27xx_fwdt_template_valid(void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct qla27xx_fwdt_template *tmp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (!qla27xx_verify_template_header(tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		ql_log(ql_log_warn, NULL, 0xd01c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		    "%s: template type %x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		    le32_to_cpu(tmp->template_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	if (!qla27xx_verify_template_checksum(tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		ql_log(ql_log_warn, NULL, 0xd01d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		    "%s: failed template checksum\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	ulong flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	if (!hardware_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		spin_lock_irqsave(&vha->hw->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	if (!vha->hw->mpi_fw_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		struct fwdt *fwdt = &vha->hw->fwdt[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		ulong len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		void *buf = vha->hw->mpi_fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		bool walk_template_only = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		if (vha->hw->mpi_fw_dumped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			/* Use the spare area for any further dumps. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			buf += fwdt->dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			walk_template_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			ql_log(ql_log_warn, vha, 0x02f4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			       "-> MPI firmware already dumped -- dump saving to temporary buffer %p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			       buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		if (!fwdt->template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			ql_log(ql_log_warn, vha, 0x02f6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 			       "-> fwdt1 no template\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			goto bailout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		if (len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			goto bailout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		} else if (len != fwdt->dump_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			ql_log(ql_log_warn, vha, 0x02f7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			       "-> fwdt1 fwdump residual=%+ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			       fwdt->dump_size - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		vha->hw->stat.num_mpi_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		if (walk_template_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			goto bailout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		vha->hw->mpi_fw_dump_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		vha->hw->mpi_fw_dumped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		ql_log(ql_log_warn, vha, 0x02f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		       "-> MPI firmware dump saved to buffer (%lu/%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		       vha->host_no, vha->hw->mpi_fw_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) bailout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	if (!hardware_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) qla27xx_fwdump(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	lockdep_assert_held(&vha->hw->hardware_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (!vha->hw->fw_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		ql_log(ql_log_warn, vha, 0xd01e, "-> fwdump no buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	} else if (vha->hw->fw_dumped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		ql_log(ql_log_warn, vha, 0xd01f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		    "-> Firmware already dumped (%p) -- ignoring request\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		    vha->hw->fw_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		struct fwdt *fwdt = vha->hw->fwdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		ulong len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		void *buf = vha->hw->fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		ql_log(ql_log_warn, vha, 0xd011, "-> fwdt0 running...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		if (!fwdt->template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			ql_log(ql_log_warn, vha, 0xd012,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			       "-> fwdt0 no template\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if (len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		} else if (len != fwdt->dump_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			ql_log(ql_log_warn, vha, 0xd013,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			       "-> fwdt0 fwdump residual=%+ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 				fwdt->dump_size - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		vha->hw->fw_dump_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		vha->hw->fw_dumped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		ql_log(ql_log_warn, vha, 0xd015,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		    "-> Firmware dump saved to buffer (%lu/%p) <%lx>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		    vha->host_no, vha->hw->fw_dump, vha->hw->fw_dump_cap_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }