Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/cxgbe/common/t4_hw.c
Show First 20 Lines • Show All 283 Lines • ▼ Show 20 Lines | int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, | ||||
u32 ctl_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_CTRL); | u32 ctl_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_CTRL); | ||||
u32 ctl; | u32 ctl; | ||||
__be64 cmd_rpl[MBOX_LEN/8]; | __be64 cmd_rpl[MBOX_LEN/8]; | ||||
u32 pcie_fw; | u32 pcie_fw; | ||||
if ((size & 15) || size > MBOX_LEN) | if ((size & 15) || size > MBOX_LEN) | ||||
return -EINVAL; | return -EINVAL; | ||||
if (adap->flags & IS_VF) { | |||||
if (is_t6(adap)) | |||||
data_reg = FW_T6VF_MBDATA_BASE_ADDR; | |||||
else | |||||
data_reg = FW_T4VF_MBDATA_BASE_ADDR; | |||||
ctl_reg = VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL); | |||||
} | |||||
/* | /* | ||||
* If we have a negative timeout, that implies that we can't sleep. | * If we have a negative timeout, that implies that we can't sleep. | ||||
*/ | */ | ||||
if (timeout < 0) { | if (timeout < 0) { | ||||
sleep_ok = false; | sleep_ok = false; | ||||
timeout = -timeout; | timeout = -timeout; | ||||
} | } | ||||
Show All 38 Lines | int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, | ||||
} | } | ||||
/* | /* | ||||
* Copy in the new mailbox command and send it on its way ... | * Copy in the new mailbox command and send it on its way ... | ||||
*/ | */ | ||||
for (i = 0; i < size; i += 8, p++) | for (i = 0; i < size; i += 8, p++) | ||||
t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p)); | t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p)); | ||||
if (adap->flags & IS_VF) { | |||||
/* | |||||
* For the VFs, the Mailbox Data "registers" are | |||||
* actually backed by T4's "MA" interface rather than | |||||
* PL Registers (as is the case for the PFs). Because | |||||
* these are in different coherency domains, the write | |||||
* to the VF's PL-register-backed Mailbox Control can | |||||
* race in front of the writes to the MA-backed VF | |||||
* Mailbox Data "registers". So we need to do a | |||||
* read-back on at least one byte of the VF Mailbox | |||||
* Data registers before doing the write to the VF | |||||
* Mailbox Control register. | |||||
*/ | |||||
t4_read_reg(adap, data_reg); | |||||
} | |||||
CH_DUMP_MBOX(adap, mbox, data_reg); | CH_DUMP_MBOX(adap, mbox, data_reg); | ||||
t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW)); | t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW)); | ||||
t4_read_reg(adap, ctl_reg); /* flush write */ | t4_read_reg(adap, ctl_reg); /* flush write */ | ||||
delay_idx = 0; | delay_idx = 0; | ||||
ms = delay[0]; | ms = delay[0]; | ||||
/* | /* | ||||
* Loop waiting for the reply; bail out if we time out or the firmware | * Loop waiting for the reply; bail out if we time out or the firmware | ||||
* reports an error. | * reports an error. | ||||
*/ | */ | ||||
for (i = 0; | pcie_fw = 0; | ||||
!((pcie_fw = t4_read_reg(adap, A_PCIE_FW)) & F_PCIE_FW_ERR) && | for (i = 0; i < timeout; i += ms) { | ||||
i < timeout; | if (!(adap->flags & IS_VF)) { | ||||
i += ms) { | pcie_fw = t4_read_reg(adap, A_PCIE_FW); | ||||
if (pcie_fw & F_PCIE_FW_ERR) | |||||
break; | |||||
} | |||||
if (sleep_ok) { | if (sleep_ok) { | ||||
ms = delay[delay_idx]; /* last element may repeat */ | ms = delay[delay_idx]; /* last element may repeat */ | ||||
if (delay_idx < ARRAY_SIZE(delay) - 1) | if (delay_idx < ARRAY_SIZE(delay) - 1) | ||||
delay_idx++; | delay_idx++; | ||||
msleep(ms); | msleep(ms); | ||||
} else { | } else { | ||||
mdelay(ms); | mdelay(ms); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 8,810 Lines • Show Last 20 Lines |