aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c88
1 files changed, 56 insertions, 32 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index c4fef839168c..978f593094c0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -152,6 +152,26 @@ static int mlx4_status_to_errno(u8 status)
152 return trans_table[status]; 152 return trans_table[status];
153} 153}
154 154
155static u8 mlx4_errno_to_status(int errno)
156{
157 switch (errno) {
158 case -EPERM:
159 return CMD_STAT_BAD_OP;
160 case -EINVAL:
161 return CMD_STAT_BAD_PARAM;
162 case -ENXIO:
163 return CMD_STAT_BAD_SYS_STATE;
164 case -EBUSY:
165 return CMD_STAT_RESOURCE_BUSY;
166 case -ENOMEM:
167 return CMD_STAT_EXCEED_LIM;
168 case -ENFILE:
169 return CMD_STAT_ICM_ERROR;
170 default:
171 return CMD_STAT_INTERNAL_ERR;
172 }
173}
174
155static int comm_pending(struct mlx4_dev *dev) 175static int comm_pending(struct mlx4_dev *dev)
156{ 176{
157 struct mlx4_priv *priv = mlx4_priv(dev); 177 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -361,10 +381,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
361 mlx4_err(dev, "response expected while" 381 mlx4_err(dev, "response expected while"
362 "output mailbox is NULL for " 382 "output mailbox is NULL for "
363 "command 0x%x\n", op); 383 "command 0x%x\n", op);
364 vhcr->status = -EINVAL; 384 vhcr->status = CMD_STAT_BAD_PARAM;
365 } 385 }
366 } 386 }
367 ret = vhcr->status; 387 ret = mlx4_status_to_errno(vhcr->status);
368 } 388 }
369 } else { 389 } else {
370 ret = mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_POST, 0, 390 ret = mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_POST, 0,
@@ -378,10 +398,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
378 mlx4_err(dev, "response expected while" 398 mlx4_err(dev, "response expected while"
379 "output mailbox is NULL for " 399 "output mailbox is NULL for "
380 "command 0x%x\n", op); 400 "command 0x%x\n", op);
381 vhcr->status = -EINVAL; 401 vhcr->status = CMD_STAT_BAD_PARAM;
382 } 402 }
383 } 403 }
384 ret = vhcr->status; 404 ret = mlx4_status_to_errno(vhcr->status);
385 } else 405 } else
386 mlx4_err(dev, "failed execution of VHCR_POST command" 406 mlx4_err(dev, "failed execution of VHCR_POST command"
387 "opcode 0x%x\n", op); 407 "opcode 0x%x\n", op);
@@ -1066,6 +1086,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1066 u64 out_param; 1086 u64 out_param;
1067 int ret = 0; 1087 int ret = 0;
1068 int i; 1088 int i;
1089 int err = 0;
1069 1090
1070 /* Create sw representation of Virtual HCR */ 1091 /* Create sw representation of Virtual HCR */
1071 vhcr = kzalloc(sizeof(struct mlx4_vhcr), GFP_KERNEL); 1092 vhcr = kzalloc(sizeof(struct mlx4_vhcr), GFP_KERNEL);
@@ -1105,7 +1126,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1105 if (!cmd) { 1126 if (!cmd) {
1106 mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n", 1127 mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n",
1107 vhcr->op, slave); 1128 vhcr->op, slave);
1108 vhcr_cmd->status = -EINVAL; 1129 vhcr_cmd->status = CMD_STAT_BAD_PARAM;
1109 goto out_status; 1130 goto out_status;
1110 } 1131 }
1111 1132
@@ -1114,18 +1135,18 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1114 vhcr->in_param &= INBOX_MASK; 1135 vhcr->in_param &= INBOX_MASK;
1115 inbox = mlx4_alloc_cmd_mailbox(dev); 1136 inbox = mlx4_alloc_cmd_mailbox(dev);
1116 if (IS_ERR(inbox)) { 1137 if (IS_ERR(inbox)) {
1117 ret = PTR_ERR(inbox); 1138 vhcr_cmd->status = CMD_STAT_BAD_SIZE;
1118 inbox = NULL; 1139 inbox = NULL;
1119 goto out; 1140 goto out_status;
1120 } 1141 }
1121 1142
1122 ret = mlx4_ACCESS_MEM(dev, inbox->dma, slave, 1143 if (mlx4_ACCESS_MEM(dev, inbox->dma, slave,
1123 vhcr->in_param, 1144 vhcr->in_param,
1124 MLX4_MAILBOX_SIZE, 1); 1145 MLX4_MAILBOX_SIZE, 1)) {
1125 if (ret) {
1126 mlx4_err(dev, "%s: Failed reading inbox (cmd:0x%x)\n", 1146 mlx4_err(dev, "%s: Failed reading inbox (cmd:0x%x)\n",
1127 __func__, cmd->opcode); 1147 __func__, cmd->opcode);
1128 goto out; 1148 vhcr_cmd->status = CMD_STAT_INTERNAL_ERR;
1149 goto out_status;
1129 } 1150 }
1130 } 1151 }
1131 1152
@@ -1134,7 +1155,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1134 mlx4_warn(dev, "Command:0x%x from slave: %d failed protection " 1155 mlx4_warn(dev, "Command:0x%x from slave: %d failed protection "
1135 "checks for resource_id:%d\n", vhcr->op, slave, 1156 "checks for resource_id:%d\n", vhcr->op, slave,
1136 vhcr->in_modifier); 1157 vhcr->in_modifier);
1137 vhcr_cmd->status = -EPERM; 1158 vhcr_cmd->status = CMD_STAT_BAD_OP;
1138 goto out_status; 1159 goto out_status;
1139 } 1160 }
1140 1161
@@ -1142,16 +1163,16 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1142 if (cmd->has_outbox) { 1163 if (cmd->has_outbox) {
1143 outbox = mlx4_alloc_cmd_mailbox(dev); 1164 outbox = mlx4_alloc_cmd_mailbox(dev);
1144 if (IS_ERR(outbox)) { 1165 if (IS_ERR(outbox)) {
1145 ret = PTR_ERR(outbox); 1166 vhcr_cmd->status = CMD_STAT_BAD_SIZE;
1146 outbox = NULL; 1167 outbox = NULL;
1147 goto out; 1168 goto out_status;
1148 } 1169 }
1149 } 1170 }
1150 1171
1151 /* Execute the command! */ 1172 /* Execute the command! */
1152 if (cmd->wrapper) { 1173 if (cmd->wrapper) {
1153 vhcr_cmd->status = cmd->wrapper(dev, slave, vhcr, inbox, outbox, 1174 err = cmd->wrapper(dev, slave, vhcr, inbox, outbox,
1154 cmd); 1175 cmd);
1155 if (cmd->out_is_imm) 1176 if (cmd->out_is_imm)
1156 vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param); 1177 vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param);
1157 } else { 1178 } else {
@@ -1159,20 +1180,11 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1159 vhcr->in_param; 1180 vhcr->in_param;
1160 out_param = cmd->has_outbox ? (u64) outbox->dma : 1181 out_param = cmd->has_outbox ? (u64) outbox->dma :
1161 vhcr->out_param; 1182 vhcr->out_param;
1162 vhcr_cmd->status = __mlx4_cmd(dev, in_param, &out_param, 1183 err = __mlx4_cmd(dev, in_param, &out_param,
1163 cmd->out_is_imm, vhcr->in_modifier, 1184 cmd->out_is_imm, vhcr->in_modifier,
1164 vhcr->op_modifier, vhcr->op, 1185 vhcr->op_modifier, vhcr->op,
1165 MLX4_CMD_TIME_CLASS_A, 1186 MLX4_CMD_TIME_CLASS_A,
1166 MLX4_CMD_NATIVE); 1187 MLX4_CMD_NATIVE);
1167
1168 if (vhcr_cmd->status) {
1169 mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with"
1170 " error:%d, status %d\n",
1171 vhcr->op, slave, vhcr->errno,
1172 vhcr_cmd->status);
1173 ret = vhcr_cmd->status;
1174 goto out;
1175 }
1176 1188
1177 if (cmd->out_is_imm) { 1189 if (cmd->out_is_imm) {
1178 vhcr->out_param = out_param; 1190 vhcr->out_param = out_param;
@@ -1180,12 +1192,24 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
1180 } 1192 }
1181 } 1193 }
1182 1194
1195 if (err) {
1196 mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with"
1197 " error:%d, status %d\n",
1198 vhcr->op, slave, vhcr->errno, err);
1199 vhcr_cmd->status = mlx4_errno_to_status(err);
1200 goto out_status;
1201 }
1202
1203
1183 /* Write outbox if command completed successfully */ 1204 /* Write outbox if command completed successfully */
1184 if (cmd->has_outbox && !vhcr->errno) { 1205 if (cmd->has_outbox && !vhcr_cmd->status) {
1185 ret = mlx4_ACCESS_MEM(dev, outbox->dma, slave, 1206 ret = mlx4_ACCESS_MEM(dev, outbox->dma, slave,
1186 vhcr->out_param, 1207 vhcr->out_param,
1187 MLX4_MAILBOX_SIZE, MLX4_CMD_WRAPPED); 1208 MLX4_MAILBOX_SIZE, MLX4_CMD_WRAPPED);
1188 if (ret) { 1209 if (ret) {
1210 /* If we failed to write back the outbox after the
1211 *command was successfully executed, we must fail this
1212 * slave, as it is now in undefined state */
1189 mlx4_err(dev, "%s:Failed writing outbox\n", __func__); 1213 mlx4_err(dev, "%s:Failed writing outbox\n", __func__);
1190 goto out; 1214 goto out;
1191 } 1215 }