Skip to content

Commit f086470

Browse files
Saeed MahameedSaeed Mahameed
authored andcommitted
net/mlx5: cmdif, Return value improvements
Make sure that the two basic command interface functions cmd_exec and cmd_invoke will return well defined return values: return < 0 : Command execution couldn't be submitted by driver return > 0 : Command execution couldn't be performed by firmware return = 0 : Command was executed by FW, Caller must check FW outbox status. These statuses are valid for the blocking call of cmd_exec() e.g. when callback == NULL, in a downstream patch, will refactor the code to provide the same return value semantics to the callback. Signed-off-by: Saeed Mahameed <[email protected]> Reviewed-by: Moshe Shemesh <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 6cb8786 commit f086470

File tree

1 file changed

+43
-34
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+43
-34
lines changed

drivers/net/ethernet/mellanox/mlx5/core/cmd.c

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,10 @@ static int verify_block_sig(struct mlx5_cmd_prot_block *block)
190190
int xor_len = sizeof(*block) - sizeof(block->data) - 1;
191191

192192
if (xor8_buf(block, rsvd0_off, xor_len) != 0xff)
193-
return -EINVAL;
193+
return -EHWPOISON;
194194

195195
if (xor8_buf(block, 0, sizeof(*block)) != 0xff)
196-
return -EINVAL;
196+
return -EHWPOISON;
197197

198198
return 0;
199199
}
@@ -259,12 +259,12 @@ static int verify_signature(struct mlx5_cmd_work_ent *ent)
259259

260260
sig = xor8_buf(ent->lay, 0, sizeof(*ent->lay));
261261
if (sig != 0xff)
262-
return -EINVAL;
262+
return -EHWPOISON;
263263

264264
for (i = 0; i < n && next; i++) {
265265
err = verify_block_sig(next->buf);
266266
if (err)
267-
return err;
267+
return -EHWPOISON;
268268

269269
next = next->next;
270270
}
@@ -479,7 +479,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
479479
case MLX5_CMD_OP_ALLOC_SF:
480480
*status = MLX5_DRIVER_STATUS_ABORTED;
481481
*synd = MLX5_DRIVER_SYND;
482-
return -EIO;
482+
return -ENOLINK;
483483
default:
484484
mlx5_core_err(dev, "Unknown FW command (%d)\n", op);
485485
return -EINVAL;
@@ -1101,16 +1101,27 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
11011101
/* Notes:
11021102
* 1. Callback functions may not sleep
11031103
* 2. page queue commands do not support asynchrous completion
1104+
*
1105+
* return value in case (!callback):
1106+
* ret < 0 : Command execution couldn't be submitted by driver
1107+
* ret > 0 : Command execution couldn't be performed by firmware
1108+
* ret == 0: Command was executed by FW, Caller must check FW outbox status.
1109+
*
1110+
* return value in case (callback):
1111+
* ret < 0 : Command execution couldn't be submitted by driver
1112+
* ret == 0: Command will be submitted to FW for execution
1113+
* and the callback will be called for further status updates
11041114
*/
11051115
static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
11061116
struct mlx5_cmd_msg *out, void *uout, int uout_size,
11071117
mlx5_cmd_cbk_t callback,
1108-
void *context, int page_queue, u8 *status,
1118+
void *context, int page_queue,
11091119
u8 token, bool force_polling)
11101120
{
11111121
struct mlx5_cmd *cmd = &dev->cmd;
11121122
struct mlx5_cmd_work_ent *ent;
11131123
struct mlx5_cmd_stats *stats;
1124+
u8 status = 0;
11141125
int err = 0;
11151126
s64 ds;
11161127
u16 op;
@@ -1141,12 +1152,12 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
11411152
cmd_work_handler(&ent->work);
11421153
} else if (!queue_work(cmd->wq, &ent->work)) {
11431154
mlx5_core_warn(dev, "failed to queue work\n");
1144-
err = -ENOMEM;
1155+
err = -EALREADY;
11451156
goto out_free;
11461157
}
11471158

11481159
if (callback)
1149-
goto out; /* mlx5_cmd_comp_handler() will put(ent) */
1160+
return 0; /* mlx5_cmd_comp_handler() will put(ent) */
11501161

11511162
err = wait_func(dev, ent);
11521163
if (err == -ETIMEDOUT || err == -ECANCELED)
@@ -1164,12 +1175,11 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
11641175
mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
11651176
"fw exec time for %s is %lld nsec\n",
11661177
mlx5_command_str(op), ds);
1167-
*status = ent->status;
11681178

11691179
out_free:
1180+
status = ent->status;
11701181
cmd_ent_put(ent);
1171-
out:
1172-
return err;
1182+
return err ? : status;
11731183
}
11741184

11751185
static ssize_t dbg_write(struct file *filp, const char __user *buf,
@@ -1719,7 +1729,7 @@ void mlx5_cmd_flush(struct mlx5_core_dev *dev)
17191729
up(&cmd->sem);
17201730
}
17211731

1722-
static int status_to_err(u8 status)
1732+
static int deliv_status_to_err(u8 status)
17231733
{
17241734
switch (status) {
17251735
case MLX5_CMD_DELIVERY_STAT_OK:
@@ -1787,22 +1797,25 @@ static int is_manage_pages(void *in)
17871797
return MLX5_GET(mbox_in, in, opcode) == MLX5_CMD_OP_MANAGE_PAGES;
17881798
}
17891799

1800+
/* Notes:
1801+
* 1. Callback functions may not sleep
1802+
* 2. Page queue commands do not support asynchrous completion
1803+
*/
17901804
static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
17911805
int out_size, mlx5_cmd_cbk_t callback, void *context,
17921806
bool force_polling)
17931807
{
1794-
struct mlx5_cmd_msg *inb;
1795-
struct mlx5_cmd_msg *outb;
1808+
u16 opcode = MLX5_GET(mbox_in, in, opcode);
1809+
struct mlx5_cmd_msg *inb, *outb;
17961810
int pages_queue;
17971811
gfp_t gfp;
1798-
int err;
1799-
u8 status = 0;
1800-
u32 drv_synd;
1801-
u16 opcode;
18021812
u8 token;
1813+
int err;
18031814

1804-
opcode = MLX5_GET(mbox_in, in, opcode);
18051815
if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, opcode)) {
1816+
u32 drv_synd;
1817+
u8 status;
1818+
18061819
err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
18071820
MLX5_SET(mbox_out, out, status, status);
18081821
MLX5_SET(mbox_out, out, syndrome, drv_synd);
@@ -1833,26 +1846,22 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
18331846
}
18341847

18351848
err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context,
1836-
pages_queue, &status, token, force_polling);
1837-
if (err)
1838-
goto out_out;
1849+
pages_queue, token, force_polling);
1850+
if (callback)
1851+
return err;
18391852

1840-
mlx5_core_dbg(dev, "err %d, status %d\n", err, status);
1841-
if (status) {
1842-
err = status_to_err(status);
1843-
goto out_out;
1844-
}
1853+
if (err > 0) /* Failed in FW, command didn't execute */
1854+
err = deliv_status_to_err(err);
18451855

1846-
if (!callback)
1847-
err = mlx5_copy_from_msg(out, outb, out_size);
1856+
if (err)
1857+
goto out_out;
18481858

1859+
/* command completed by FW */
1860+
err = mlx5_copy_from_msg(out, outb, out_size);
18491861
out_out:
1850-
if (!callback)
1851-
mlx5_free_cmd_msg(dev, outb);
1852-
1862+
mlx5_free_cmd_msg(dev, outb);
18531863
out_in:
1854-
if (!callback)
1855-
free_msg(dev, inb);
1864+
free_msg(dev, inb);
18561865
return err;
18571866
}
18581867

0 commit comments

Comments
 (0)