| .. | .. |
|---|
| 36 | 36 | #include "hns_roce_device.h" |
|---|
| 37 | 37 | #include "hns_roce_cmd.h" |
|---|
| 38 | 38 | |
|---|
| 39 | | -#define CMD_POLL_TOKEN 0xffff |
|---|
| 40 | | -#define CMD_MAX_NUM 32 |
|---|
| 41 | | -#define CMD_TOKEN_MASK 0x1f |
|---|
| 39 | +#define CMD_POLL_TOKEN 0xffff |
|---|
| 40 | +#define CMD_MAX_NUM 32 |
|---|
| 41 | +#define CMD_TOKEN_MASK 0x1f |
|---|
| 42 | 42 | |
|---|
| 43 | 43 | static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param, |
|---|
| 44 | 44 | u64 out_param, u32 in_modifier, |
|---|
| .. | .. |
|---|
| 93 | 93 | void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status, |
|---|
| 94 | 94 | u64 out_param) |
|---|
| 95 | 95 | { |
|---|
| 96 | | - struct hns_roce_cmd_context |
|---|
| 97 | | - *context = &hr_dev->cmd.context[token & hr_dev->cmd.token_mask]; |
|---|
| 96 | + struct hns_roce_cmd_context *context = |
|---|
| 97 | + &hr_dev->cmd.context[token % hr_dev->cmd.max_cmds]; |
|---|
| 98 | 98 | |
|---|
| 99 | 99 | if (token != context->token) |
|---|
| 100 | 100 | return; |
|---|
| .. | .. |
|---|
| 103 | 103 | context->out_param = out_param; |
|---|
| 104 | 104 | complete(&context->done); |
|---|
| 105 | 105 | } |
|---|
| 106 | | -EXPORT_SYMBOL_GPL(hns_roce_cmd_event); |
|---|
| 107 | 106 | |
|---|
| 108 | 107 | /* this should be called with "use_events" */ |
|---|
| 109 | 108 | static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, |
|---|
| .. | .. |
|---|
| 162 | 161 | u64 out_param, unsigned long in_modifier, |
|---|
| 163 | 162 | u8 op_modifier, u16 op, unsigned long timeout) |
|---|
| 164 | 163 | { |
|---|
| 165 | | - int ret = 0; |
|---|
| 164 | + int ret; |
|---|
| 166 | 165 | |
|---|
| 167 | 166 | down(&hr_dev->cmd.event_sem); |
|---|
| 168 | | - ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, |
|---|
| 169 | | - in_modifier, op_modifier, op, timeout); |
|---|
| 167 | + ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, in_modifier, |
|---|
| 168 | + op_modifier, op, timeout); |
|---|
| 170 | 169 | up(&hr_dev->cmd.event_sem); |
|---|
| 171 | 170 | |
|---|
| 172 | 171 | return ret; |
|---|
| .. | .. |
|---|
| 176 | 175 | unsigned long in_modifier, u8 op_modifier, u16 op, |
|---|
| 177 | 176 | unsigned long timeout) |
|---|
| 178 | 177 | { |
|---|
| 179 | | - if (hr_dev->is_reset) |
|---|
| 180 | | - return 0; |
|---|
| 178 | + int ret; |
|---|
| 179 | + |
|---|
| 180 | + if (hr_dev->hw->rst_prc_mbox) { |
|---|
| 181 | + ret = hr_dev->hw->rst_prc_mbox(hr_dev); |
|---|
| 182 | + if (ret == CMD_RST_PRC_SUCCESS) |
|---|
| 183 | + return 0; |
|---|
| 184 | + else if (ret == CMD_RST_PRC_EBUSY) |
|---|
| 185 | + return -EBUSY; |
|---|
| 186 | + } |
|---|
| 181 | 187 | |
|---|
| 182 | 188 | if (hr_dev->cmd.use_events) |
|---|
| 183 | | - return hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, |
|---|
| 184 | | - in_modifier, op_modifier, op, |
|---|
| 185 | | - timeout); |
|---|
| 189 | + ret = hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, |
|---|
| 190 | + in_modifier, op_modifier, op, |
|---|
| 191 | + timeout); |
|---|
| 186 | 192 | else |
|---|
| 187 | | - return hns_roce_cmd_mbox_poll(hr_dev, in_param, out_param, |
|---|
| 188 | | - in_modifier, op_modifier, op, |
|---|
| 189 | | - timeout); |
|---|
| 193 | + ret = hns_roce_cmd_mbox_poll(hr_dev, in_param, out_param, |
|---|
| 194 | + in_modifier, op_modifier, op, |
|---|
| 195 | + timeout); |
|---|
| 196 | + |
|---|
| 197 | + if (ret == CMD_RST_PRC_EBUSY) |
|---|
| 198 | + return -EBUSY; |
|---|
| 199 | + |
|---|
| 200 | + if (ret && (hr_dev->hw->rst_prc_mbox && |
|---|
| 201 | + hr_dev->hw->rst_prc_mbox(hr_dev) == CMD_RST_PRC_SUCCESS)) |
|---|
| 202 | + return 0; |
|---|
| 203 | + |
|---|
| 204 | + return ret; |
|---|
| 190 | 205 | } |
|---|
| 191 | | -EXPORT_SYMBOL_GPL(hns_roce_cmd_mbox); |
|---|
| 192 | 206 | |
|---|
| 193 | 207 | int hns_roce_cmd_init(struct hns_roce_dev *hr_dev) |
|---|
| 194 | 208 | { |
|---|
| .. | .. |
|---|
| 197 | 211 | mutex_init(&hr_dev->cmd.hcr_mutex); |
|---|
| 198 | 212 | sema_init(&hr_dev->cmd.poll_sem, 1); |
|---|
| 199 | 213 | hr_dev->cmd.use_events = 0; |
|---|
| 200 | | - hr_dev->cmd.toggle = 1; |
|---|
| 201 | 214 | hr_dev->cmd.max_cmds = CMD_MAX_NUM; |
|---|
| 202 | 215 | hr_dev->cmd.pool = dma_pool_create("hns_roce_cmd", dev, |
|---|
| 203 | 216 | HNS_ROCE_MAILBOX_SIZE, |
|---|
| .. | .. |
|---|
| 218 | 231 | struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd; |
|---|
| 219 | 232 | int i; |
|---|
| 220 | 233 | |
|---|
| 221 | | - hr_cmd->context = kmalloc_array(hr_cmd->max_cmds, |
|---|
| 222 | | - sizeof(*hr_cmd->context), |
|---|
| 223 | | - GFP_KERNEL); |
|---|
| 234 | + hr_cmd->context = |
|---|
| 235 | + kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL); |
|---|
| 224 | 236 | if (!hr_cmd->context) |
|---|
| 225 | 237 | return -ENOMEM; |
|---|
| 226 | 238 | |
|---|
| .. | .. |
|---|
| 238 | 250 | hr_cmd->token_mask = CMD_TOKEN_MASK; |
|---|
| 239 | 251 | hr_cmd->use_events = 1; |
|---|
| 240 | 252 | |
|---|
| 241 | | - down(&hr_cmd->poll_sem); |
|---|
| 242 | | - |
|---|
| 243 | 253 | return 0; |
|---|
| 244 | 254 | } |
|---|
| 245 | 255 | |
|---|
| 246 | 256 | void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev) |
|---|
| 247 | 257 | { |
|---|
| 248 | 258 | struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd; |
|---|
| 249 | | - int i; |
|---|
| 250 | | - |
|---|
| 251 | | - hr_cmd->use_events = 0; |
|---|
| 252 | | - |
|---|
| 253 | | - for (i = 0; i < hr_cmd->max_cmds; ++i) |
|---|
| 254 | | - down(&hr_cmd->event_sem); |
|---|
| 255 | 259 | |
|---|
| 256 | 260 | kfree(hr_cmd->context); |
|---|
| 257 | | - up(&hr_cmd->poll_sem); |
|---|
| 261 | + hr_cmd->use_events = 0; |
|---|
| 258 | 262 | } |
|---|
| 259 | 263 | |
|---|
| 260 | | -struct hns_roce_cmd_mailbox |
|---|
| 261 | | - *hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev) |
|---|
| 264 | +struct hns_roce_cmd_mailbox * |
|---|
| 265 | +hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev) |
|---|
| 262 | 266 | { |
|---|
| 263 | 267 | struct hns_roce_cmd_mailbox *mailbox; |
|---|
| 264 | 268 | |
|---|
| .. | .. |
|---|
| 266 | 270 | if (!mailbox) |
|---|
| 267 | 271 | return ERR_PTR(-ENOMEM); |
|---|
| 268 | 272 | |
|---|
| 269 | | - mailbox->buf = dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL, |
|---|
| 270 | | - &mailbox->dma); |
|---|
| 273 | + mailbox->buf = |
|---|
| 274 | + dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL, &mailbox->dma); |
|---|
| 271 | 275 | if (!mailbox->buf) { |
|---|
| 272 | 276 | kfree(mailbox); |
|---|
| 273 | 277 | return ERR_PTR(-ENOMEM); |
|---|
| .. | .. |
|---|
| 275 | 279 | |
|---|
| 276 | 280 | return mailbox; |
|---|
| 277 | 281 | } |
|---|
| 278 | | -EXPORT_SYMBOL_GPL(hns_roce_alloc_cmd_mailbox); |
|---|
| 279 | 282 | |
|---|
| 280 | 283 | void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev, |
|---|
| 281 | 284 | struct hns_roce_cmd_mailbox *mailbox) |
|---|
| .. | .. |
|---|
| 286 | 289 | dma_pool_free(hr_dev->cmd.pool, mailbox->buf, mailbox->dma); |
|---|
| 287 | 290 | kfree(mailbox); |
|---|
| 288 | 291 | } |
|---|
| 289 | | -EXPORT_SYMBOL_GPL(hns_roce_free_cmd_mailbox); |
|---|