@@ -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 */
11051115static 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
11691179out_free :
1180+ status = ent -> status ;
11701181 cmd_ent_put (ent );
1171- out :
1172- return err ;
1182+ return err ? : status ;
11731183}
11741184
11751185static 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+ */
17901804static 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 );
18491861out_out :
1850- if (!callback )
1851- mlx5_free_cmd_msg (dev , outb );
1852-
1862+ mlx5_free_cmd_msg (dev , outb );
18531863out_in :
1854- if (!callback )
1855- free_msg (dev , inb );
1864+ free_msg (dev , inb );
18561865 return err ;
18571866}
18581867
0 commit comments