^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) }