mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
hinic3: Command Queue flush interfaces
Add the data structures and functions for command queue flushing. Co-developed-by: Zhu Yikai <zhuyikai1@h-partners.com> Signed-off-by: Zhu Yikai <zhuyikai1@h-partners.com> Signed-off-by: Fan Gong <gongfan1@huawei.com> Link: https://patch.msgid.link/2cfd5dfbccb5265e22bdb5a2b279122a57795bb1.1757653621.git.zhuyikai1@h-partners.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
a0543a7935
commit
b92e6c734d
|
|
@ -237,3 +237,102 @@ int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define HINIC3_WAIT_CMDQ_IDLE_TIMEOUT 5000
|
||||
|
||||
static enum hinic3_wait_return check_cmdq_stop_handler(void *priv_data)
|
||||
{
|
||||
struct hinic3_hwdev *hwdev = priv_data;
|
||||
enum hinic3_cmdq_type cmdq_type;
|
||||
struct hinic3_cmdqs *cmdqs;
|
||||
|
||||
cmdqs = hwdev->cmdqs;
|
||||
for (cmdq_type = 0; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
|
||||
if (!hinic3_cmdq_idle(&cmdqs->cmdq[cmdq_type]))
|
||||
return HINIC3_WAIT_PROCESS_WAITING;
|
||||
}
|
||||
|
||||
return HINIC3_WAIT_PROCESS_CPL;
|
||||
}
|
||||
|
||||
static int wait_cmdq_stop(struct hinic3_hwdev *hwdev)
|
||||
{
|
||||
struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
|
||||
enum hinic3_cmdq_type cmdq_type;
|
||||
int err;
|
||||
|
||||
if (!(cmdqs->status & HINIC3_CMDQ_ENABLE))
|
||||
return 0;
|
||||
|
||||
cmdqs->status &= ~HINIC3_CMDQ_ENABLE;
|
||||
err = hinic3_wait_for_timeout(hwdev, check_cmdq_stop_handler,
|
||||
HINIC3_WAIT_CMDQ_IDLE_TIMEOUT,
|
||||
USEC_PER_MSEC);
|
||||
|
||||
if (err)
|
||||
goto err_reenable_cmdq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_reenable_cmdq:
|
||||
for (cmdq_type = 0; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
|
||||
if (!hinic3_cmdq_idle(&cmdqs->cmdq[cmdq_type]))
|
||||
dev_err(hwdev->dev, "Cmdq %d is busy\n", cmdq_type);
|
||||
}
|
||||
cmdqs->status |= HINIC3_CMDQ_ENABLE;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev)
|
||||
{
|
||||
struct comm_cmd_clear_resource clear_db = {};
|
||||
struct comm_cmd_clear_resource clr_res = {};
|
||||
struct hinic3_hwif *hwif = hwdev->hwif;
|
||||
struct mgmt_msg_params msg_params = {};
|
||||
int ret = 0;
|
||||
int err;
|
||||
|
||||
err = wait_cmdq_stop(hwdev);
|
||||
if (err) {
|
||||
dev_warn(hwdev->dev, "CMDQ is still working, CMDQ timeout value is unreasonable\n");
|
||||
ret = err;
|
||||
}
|
||||
|
||||
hinic3_toggle_doorbell(hwif, DISABLE_DOORBELL);
|
||||
|
||||
clear_db.func_id = hwif->attr.func_global_idx;
|
||||
mgmt_msg_params_init_default(&msg_params, &clear_db, sizeof(clear_db));
|
||||
err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
|
||||
COMM_CMD_FLUSH_DOORBELL, &msg_params);
|
||||
if (err || clear_db.head.status) {
|
||||
dev_warn(hwdev->dev, "Failed to flush doorbell, err: %d, status: 0x%x\n",
|
||||
err, clear_db.head.status);
|
||||
if (err)
|
||||
ret = err;
|
||||
else
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
clr_res.func_id = hwif->attr.func_global_idx;
|
||||
msg_params.buf_in = &clr_res;
|
||||
msg_params.in_size = sizeof(clr_res);
|
||||
err = hinic3_send_mbox_to_mgmt_no_ack(hwdev, MGMT_MOD_COMM,
|
||||
COMM_CMD_START_FLUSH,
|
||||
&msg_params);
|
||||
if (err) {
|
||||
dev_warn(hwdev->dev, "Failed to notice flush message, err: %d\n",
|
||||
err);
|
||||
ret = err;
|
||||
}
|
||||
|
||||
hinic3_toggle_doorbell(hwif, ENABLE_DOORBELL);
|
||||
|
||||
err = hinic3_reinit_cmdq_ctxts(hwdev);
|
||||
if (err) {
|
||||
dev_warn(hwdev->dev, "Failed to reinit cmdq\n");
|
||||
ret = err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,5 +39,6 @@ int hinic3_set_dma_attr_tbl(struct hinic3_hwdev *hwdev, u8 entry_idx, u8 st,
|
|||
int hinic3_set_wq_page_size(struct hinic3_hwdev *hwdev, u16 func_idx,
|
||||
u32 page_size);
|
||||
int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth);
|
||||
int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -245,6 +245,12 @@ struct comm_cmd_set_cmdq_ctxt {
|
|||
struct comm_cmdq_ctxt_info ctxt;
|
||||
};
|
||||
|
||||
struct comm_cmd_clear_resource {
|
||||
struct mgmt_msg_head head;
|
||||
u16 func_id;
|
||||
u16 rsvd1[3];
|
||||
};
|
||||
|
||||
/* Services supported by HW. HW uses these values when delivering events.
|
||||
* HW supports multiple services that are not yet supported by driver
|
||||
* (e.g. RoCE).
|
||||
|
|
|
|||
|
|
@ -514,6 +514,7 @@ void hinic3_free_hwdev(struct hinic3_hwdev *hwdev)
|
|||
u64 drv_features[COMM_MAX_FEATURE_QWORD] = {};
|
||||
|
||||
hinic3_set_comm_features(hwdev, drv_features, COMM_MAX_FEATURE_QWORD);
|
||||
hinic3_func_rx_tx_flush(hwdev);
|
||||
hinic3_uninit_comm_ch(hwdev);
|
||||
hinic3_free_cfg_mgmt(hwdev);
|
||||
destroy_workqueue(hwdev->workq);
|
||||
|
|
|
|||
|
|
@ -173,6 +173,20 @@ static enum hinic3_outbound_ctrl hinic3_get_outbound_ctrl_status(struct hinic3_h
|
|||
return HINIC3_AF5_GET(attr5, OUTBOUND_CTRL);
|
||||
}
|
||||
|
||||
void hinic3_toggle_doorbell(struct hinic3_hwif *hwif,
|
||||
enum hinic3_doorbell_ctrl flag)
|
||||
{
|
||||
u32 addr, attr4;
|
||||
|
||||
addr = HINIC3_CSR_FUNC_ATTR4_ADDR;
|
||||
attr4 = hinic3_hwif_read_reg(hwif, addr);
|
||||
|
||||
attr4 &= ~HINIC3_AF4_DOORBELL_CTRL_MASK;
|
||||
attr4 |= HINIC3_AF4_SET(flag, DOORBELL_CTRL);
|
||||
|
||||
hinic3_hwif_write_reg(hwif, addr, attr4);
|
||||
}
|
||||
|
||||
static int db_area_idx_init(struct hinic3_hwif *hwif, u64 db_base_phy,
|
||||
u8 __iomem *db_base, u64 db_dwqe_len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ enum hinic3_msix_auto_mask {
|
|||
u32 hinic3_hwif_read_reg(struct hinic3_hwif *hwif, u32 reg);
|
||||
void hinic3_hwif_write_reg(struct hinic3_hwif *hwif, u32 reg, u32 val);
|
||||
|
||||
void hinic3_toggle_doorbell(struct hinic3_hwif *hwif,
|
||||
enum hinic3_doorbell_ctrl flag);
|
||||
|
||||
int hinic3_alloc_db_addr(struct hinic3_hwdev *hwdev, void __iomem **db_base,
|
||||
void __iomem **dwqe_base);
|
||||
void hinic3_free_db_addr(struct hinic3_hwdev *hwdev, const u8 __iomem *db_base);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user