1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Huawei Technologies Co., Ltd 3 */ 4 5 #include "hinic_compat.h" 6 #include "hinic_csr.h" 7 #include "hinic_pmd_hwdev.h" 8 #include "hinic_pmd_hwif.h" 9 #include "hinic_pmd_eqs.h" 10 #include "hinic_pmd_mgmt.h" 11 #include "hinic_pmd_mbox.h" 12 13 #define HINIC_MBOX_INT_DST_FUNC_SHIFT 0 14 #define HINIC_MBOX_INT_DST_AEQN_SHIFT 10 15 #define HINIC_MBOX_INT_SRC_RESP_AEQN_SHIFT 12 16 #define HINIC_MBOX_INT_STAT_DMA_SHIFT 14 17 /* The size of data to be send (unit of 4 bytes) */ 18 #define HINIC_MBOX_INT_TX_SIZE_SHIFT 20 19 /* SO_RO(strong order, relax order) */ 20 #define HINIC_MBOX_INT_STAT_DMA_SO_RO_SHIFT 25 21 #define HINIC_MBOX_INT_WB_EN_SHIFT 28 22 23 24 #define HINIC_MBOX_INT_DST_FUNC_MASK 0x3FF 25 #define HINIC_MBOX_INT_DST_AEQN_MASK 0x3 26 #define HINIC_MBOX_INT_SRC_RESP_AEQN_MASK 0x3 27 #define HINIC_MBOX_INT_STAT_DMA_MASK 0x3F 28 #define HINIC_MBOX_INT_TX_SIZE_MASK 0x1F 29 #define HINIC_MBOX_INT_STAT_DMA_SO_RO_MASK 0x3 30 #define HINIC_MBOX_INT_WB_EN_MASK 0x1 31 32 #define HINIC_MBOX_INT_SET(val, field) \ 33 (((val) & HINIC_MBOX_INT_##field##_MASK) << \ 34 HINIC_MBOX_INT_##field##_SHIFT) 35 36 enum hinic_mbox_tx_status { 37 TX_DONE = 0, 38 TX_IN_PROGRESS, 39 }; 40 41 #define HINIC_MBOX_CTRL_TRIGGER_AEQE_SHIFT 0 42 /* specifies the issue request for the message data. 43 * 0 - Tx request is done; 44 * 1 - Tx request is in process. 45 */ 46 #define HINIC_MBOX_CTRL_TX_STATUS_SHIFT 1 47 48 #define HINIC_MBOX_CTRL_TRIGGER_AEQE_MASK 0x1 49 #define HINIC_MBOX_CTRL_TX_STATUS_MASK 0x1 50 51 #define HINIC_MBOX_CTRL_SET(val, field) \ 52 (((val) & HINIC_MBOX_CTRL_##field##_MASK) << \ 53 HINIC_MBOX_CTRL_##field##_SHIFT) 54 55 #define HINIC_MBOX_HEADER_MSG_LEN_SHIFT 0 56 #define HINIC_MBOX_HEADER_MODULE_SHIFT 11 57 #define HINIC_MBOX_HEADER_SEG_LEN_SHIFT 16 58 #define HINIC_MBOX_HEADER_NO_ACK_SHIFT 22 59 #define HINIC_MBOX_HEADER_SEQID_SHIFT 24 60 #define HINIC_MBOX_HEADER_LAST_SHIFT 30 61 62 #define HINIC_MBOX_HEADER_DIRECTION_SHIFT 31 63 #define HINIC_MBOX_HEADER_CMD_SHIFT 32 64 #define HINIC_MBOX_HEADER_MSG_ID_SHIFT 40 65 #define HINIC_MBOX_HEADER_STATUS_SHIFT 48 66 #define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_SHIFT 54 67 68 #define HINIC_MBOX_HEADER_MSG_LEN_MASK 0x7FF 69 #define HINIC_MBOX_HEADER_MODULE_MASK 0x1F 70 #define HINIC_MBOX_HEADER_SEG_LEN_MASK 0x3F 71 #define HINIC_MBOX_HEADER_NO_ACK_MASK 0x1 72 #define HINIC_MBOX_HEADER_SEQID_MASK 0x3F 73 #define HINIC_MBOX_HEADER_LAST_MASK 0x1 74 #define HINIC_MBOX_HEADER_DIRECTION_MASK 0x1 75 #define HINIC_MBOX_HEADER_CMD_MASK 0xFF 76 #define HINIC_MBOX_HEADER_MSG_ID_MASK 0xFF 77 #define HINIC_MBOX_HEADER_STATUS_MASK 0x3F 78 #define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_MASK 0x3FF 79 80 #define HINIC_MBOX_HEADER_GET(val, field) \ 81 (((val) >> HINIC_MBOX_HEADER_##field##_SHIFT) & \ 82 HINIC_MBOX_HEADER_##field##_MASK) 83 #define HINIC_MBOX_HEADER_SET(val, field) \ 84 ((u64)((val) & HINIC_MBOX_HEADER_##field##_MASK) << \ 85 HINIC_MBOX_HEADER_##field##_SHIFT) 86 87 #define HINIC_MBOX_COMP_TIME_MS 8000U 88 #define MBOX_MSG_POLLING_TIMEOUT_MS 5000 89 90 /* The size unit is Bytes */ 91 #define HINIC_MBOX_DATA_SIZE 2040 92 #define MBOX_MAX_BUF_SZ 2048UL 93 #define MBOX_HEADER_SZ 8 94 95 /* MBOX size is 64B, 8B for mbox_header, 4B reserved */ 96 #define MBOX_SEG_LEN 48 97 #define MBOX_SEG_LEN_ALIGN 4 98 #define MBOX_WB_STATUS_LEN 16UL 99 #define MBOX_SIZE 64 100 101 /* mbox write back status is 16B, only first 4B is used */ 102 #define MBOX_WB_STATUS_ERRCODE_MASK 0xFFFF 103 #define MBOX_WB_STATUS_MASK 0xFF 104 #define MBOX_WB_ERROR_CODE_MASK 0xFF00 105 #define MBOX_WB_STATUS_FINISHED_SUCCESS 0xFF 106 #define MBOX_WB_STATUS_FINISHED_WITH_ERR 0xFE 107 #define MBOX_WB_STATUS_NOT_FINISHED 0x00 108 109 #define MBOX_STATUS_FINISHED(wb) \ 110 (((wb) & MBOX_WB_STATUS_MASK) != MBOX_WB_STATUS_NOT_FINISHED) 111 #define MBOX_STATUS_SUCCESS(wb) \ 112 (((wb) & MBOX_WB_STATUS_MASK) == MBOX_WB_STATUS_FINISHED_SUCCESS) 113 #define MBOX_STATUS_ERRCODE(wb) \ 114 ((wb) & MBOX_WB_ERROR_CODE_MASK) 115 116 #define SEQ_ID_START_VAL 0 117 118 #define DST_AEQ_IDX_DEFAULT_VAL 0 119 #define SRC_AEQ_IDX_DEFAULT_VAL 0 120 #define NO_DMA_ATTRIBUTE_VAL 0 121 122 #define MBOX_MSG_NO_DATA_LEN 1 123 124 #define FUNC_ID_OFF_SET_8B 8 125 #define FUNC_ID_OFF_SET_10B 10 126 127 #define MBOX_BODY_FROM_HDR(header) ((u8 *)(header) + MBOX_HEADER_SZ) 128 #define MBOX_AREA(hwif) \ 129 ((hwif)->cfg_regs_base + HINIC_FUNC_CSR_MAILBOX_DATA_OFF) 130 131 #define MBOX_RESPONSE_ERROR 0x1 132 #define MBOX_MSG_ID_MASK 0xFF 133 #define MBOX_MSG_ID(func_to_func) ((func_to_func)->send_msg_id) 134 135 enum hinic_hwif_direction_type { 136 /* driver send msg to up or up send msg to driver*/ 137 HINIC_HWIF_DIRECT_SEND = 0, 138 /* after driver/up send msg to each other, then up/driver ack the msg */ 139 HINIC_HWIF_RESPONSE, 140 }; 141 142 enum mbox_send_mod { 143 MBOX_SEND_MSG_POLL = 1 144 }; 145 146 enum mbox_seg_type { 147 NOT_LAST_SEG, 148 LAST_SEG, 149 }; 150 151 enum mbox_ordering_type { 152 STRONG_ORDER, 153 RELAX_ORDER, 154 }; 155 156 enum mbox_write_back_type { 157 NOT_WRITE_BACK = 0, 158 WRITE_BACK, 159 }; 160 161 enum mbox_aeq_trig_type { 162 NOT_TRIGGER, 163 TRIGGER, 164 }; 165 166 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, 167 enum hinic_mod_type mod, u16 cmd, void *msg, 168 u16 msg_len, u16 dst_func, 169 enum hinic_hwif_direction_type direction, 170 enum hinic_mbox_ack_type ack_type, 171 struct mbox_msg_info *msg_info); 172 173 static int recv_vf_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, 174 struct hinic_recv_mbox *recv_mbox, 175 void *buf_out, u16 *out_size, void *param) 176 { 177 int rc = 0; 178 *out_size = 0; 179 180 switch (recv_mbox->mod) { 181 case HINIC_MOD_COMM: 182 hinic_comm_async_event_handle(func_to_func->hwdev, 183 recv_mbox->cmd, recv_mbox->mbox, 184 recv_mbox->mbox_len, 185 buf_out, out_size); 186 break; 187 case HINIC_MOD_L2NIC: 188 hinic_l2nic_async_event_handle(func_to_func->hwdev, param, 189 recv_mbox->cmd, recv_mbox->mbox, 190 recv_mbox->mbox_len, 191 buf_out, out_size); 192 break; 193 default: 194 PMD_DRV_LOG(ERR, "No handler, mod: %d", recv_mbox->mod); 195 rc = HINIC_MBOX_VF_CMD_ERROR; 196 break; 197 } 198 199 return rc; 200 } 201 202 static void set_mbx_msg_status(struct mbox_msg_info *msg_info, int status) 203 { 204 if (status == HINIC_DEV_BUSY_ACTIVE_FW) 205 msg_info->status = HINIC_MBOX_PF_BUSY_ACTIVE_FW; 206 else if (status == HINIC_MBOX_VF_CMD_ERROR) 207 msg_info->status = HINIC_MBOX_VF_CMD_ERROR; 208 else if (status) 209 msg_info->status = HINIC_MBOX_PF_SEND_ERR; 210 } 211 212 static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, 213 struct hinic_recv_mbox *recv_mbox, 214 u16 src_func_idx, void *param) 215 { 216 struct hinic_hwdev *dev = func_to_func->hwdev; 217 struct mbox_msg_info msg_info = { 0 }; 218 u16 out_size = MBOX_MAX_BUF_SZ; 219 void *buf_out = recv_mbox->buf_out; 220 int err = 0; 221 222 if (HINIC_IS_VF(dev)) { 223 err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out, 224 &out_size, param); 225 } else { 226 err = -EINVAL; 227 PMD_DRV_LOG(ERR, "PMD doesn't support non-VF handle mailbox message"); 228 } 229 230 if (!out_size || err) 231 out_size = MBOX_MSG_NO_DATA_LEN; 232 233 if (recv_mbox->ack_type == MBOX_ACK) { 234 msg_info.msg_id = recv_mbox->msg_info.msg_id; 235 set_mbx_msg_status(&msg_info, err); 236 send_mbox_to_func(func_to_func, recv_mbox->mod, recv_mbox->cmd, 237 buf_out, out_size, src_func_idx, 238 HINIC_HWIF_RESPONSE, MBOX_ACK, &msg_info); 239 } 240 } 241 242 static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox, 243 u8 seq_id, u8 seg_len, u8 msg_id) 244 { 245 if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN) 246 return false; 247 248 if (seq_id == 0) { 249 recv_mbox->seq_id = seq_id; 250 recv_mbox->msg_info.msg_id = msg_id; 251 } else { 252 if ((seq_id != recv_mbox->seq_id + 1) || 253 msg_id != recv_mbox->msg_info.msg_id) { 254 recv_mbox->seq_id = 0; 255 return false; 256 } 257 258 recv_mbox->seq_id = seq_id; 259 } 260 261 return true; 262 } 263 264 static void clear_mbox_status(struct hinic_send_mbox *mbox) 265 { 266 /* clear mailbox write back status */ 267 *mbox->wb_status = 0; 268 rte_wmb(); 269 } 270 271 static void mbox_copy_header(struct hinic_send_mbox *mbox, u64 *header) 272 { 273 u32 *data = (u32 *)header; 274 u32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32); 275 276 for (i = 0; i < idx_max; i++) 277 __raw_writel(*(data + i), mbox->data + i * sizeof(u32)); 278 } 279 280 static void 281 mbox_copy_send_data(struct hinic_send_mbox *mbox, void *seg, u16 seg_len) 282 { 283 u32 *data = (u32 *)seg; 284 u32 data_len, chk_sz = sizeof(u32); 285 u32 i, idx_max; 286 u8 mbox_max_buf[MBOX_SEG_LEN] = {0}; 287 288 /* The mbox message should be aligned in 4 bytes. */ 289 if (seg_len % chk_sz) { 290 memcpy(mbox_max_buf, seg, seg_len); 291 data = (u32 *)mbox_max_buf; 292 } 293 294 data_len = seg_len; 295 idx_max = ALIGN(data_len, chk_sz) / chk_sz; 296 297 for (i = 0; i < idx_max; i++) 298 __raw_writel(*(data + i), 299 mbox->data + MBOX_HEADER_SZ + i * sizeof(u32)); 300 } 301 302 static int mbox_msg_ack_aeqn(struct hinic_hwdev *hwdev) 303 { 304 u16 aeq_num = HINIC_HWIF_NUM_AEQS(hwdev->hwif); 305 int msg_ack_aeqn; 306 307 if (aeq_num >= HINIC_MAX_AEQS - 1) { 308 msg_ack_aeqn = HINIC_AEQN_2; 309 } else if (aeq_num == HINIC_MIN_AEQS) { 310 /* This is used for ovs */ 311 msg_ack_aeqn = HINIC_AEQN_1; 312 } else { 313 PMD_DRV_LOG(ERR, "Warning: Invalid aeq num: %d\n", aeq_num); 314 msg_ack_aeqn = -1; 315 } 316 317 return msg_ack_aeqn; 318 } 319 320 static u16 mbox_msg_dst_aeqn(struct hinic_hwdev *hwdev, 321 enum hinic_hwif_direction_type seq_dir) 322 { 323 u16 dst_aeqn; 324 325 if (seq_dir == HINIC_HWIF_DIRECT_SEND) 326 dst_aeqn = HINIC_AEQN_0; 327 else 328 dst_aeqn = mbox_msg_ack_aeqn(hwdev); 329 330 return dst_aeqn; 331 } 332 333 static int mbox_seg_ack_aeqn(struct hinic_hwdev *hwdev) 334 { 335 return mbox_msg_ack_aeqn(hwdev); 336 } 337 338 static void write_mbox_msg_attr(struct hinic_mbox_func_to_func *func_to_func, 339 u16 dst_func, u16 dst_aeqn, u16 seg_ack_aeqn, 340 __rte_unused u16 seg_len, int poll) 341 { 342 u32 mbox_int, mbox_ctrl; 343 344 mbox_int = HINIC_MBOX_INT_SET(dst_func, DST_FUNC) | 345 HINIC_MBOX_INT_SET(dst_aeqn, DST_AEQN) | 346 /* N/A in polling mode */ 347 HINIC_MBOX_INT_SET(seg_ack_aeqn, SRC_RESP_AEQN) | 348 HINIC_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) | 349 HINIC_MBOX_INT_SET(ALIGN(MBOX_SIZE, MBOX_SEG_LEN_ALIGN) >> 2, 350 TX_SIZE) | 351 HINIC_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) | 352 HINIC_MBOX_INT_SET(WRITE_BACK, WB_EN); 353 354 hinic_hwif_write_reg(func_to_func->hwdev->hwif, 355 HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int); 356 357 rte_wmb(); 358 mbox_ctrl = HINIC_MBOX_CTRL_SET(TX_IN_PROGRESS, TX_STATUS); 359 360 if (poll) 361 mbox_ctrl |= HINIC_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE); 362 else 363 mbox_ctrl |= HINIC_MBOX_CTRL_SET(TRIGGER, TRIGGER_AEQE); 364 365 hinic_hwif_write_reg(func_to_func->hwdev->hwif, 366 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl); 367 } 368 369 static int init_mbox_info(struct hinic_recv_mbox *mbox_info) 370 { 371 int err; 372 373 mbox_info->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); 374 if (!mbox_info->mbox) { 375 PMD_DRV_LOG(ERR, "Alloc mbox buf_in mem failed\n"); 376 return -ENOMEM; 377 } 378 379 mbox_info->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); 380 if (!mbox_info->buf_out) { 381 PMD_DRV_LOG(ERR, "Alloc mbox buf_out mem failed\n"); 382 err = -ENOMEM; 383 goto alloc_buf_out_err; 384 } 385 386 return 0; 387 388 alloc_buf_out_err: 389 kfree(mbox_info->mbox); 390 391 return err; 392 } 393 394 static void clean_mbox_info(struct hinic_recv_mbox *mbox_info) 395 { 396 kfree(mbox_info->buf_out); 397 kfree(mbox_info->mbox); 398 } 399 400 static int alloc_mbox_info(struct hinic_recv_mbox *mbox_info) 401 { 402 u16 func_idx, i; 403 int err; 404 405 for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) { 406 err = init_mbox_info(&mbox_info[func_idx]); 407 if (err) { 408 PMD_DRV_LOG(ERR, "Initialize function[%d] mailbox information failed, err: %d", 409 func_idx, err); 410 goto init_mbox_info_err; 411 } 412 } 413 414 return 0; 415 416 init_mbox_info_err: 417 for (i = 0; i < func_idx; i++) 418 clean_mbox_info(&mbox_info[i]); 419 420 return err; 421 } 422 423 static void free_mbox_info(struct hinic_recv_mbox *mbox_info) 424 { 425 u16 func_idx; 426 427 for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) 428 clean_mbox_info(&mbox_info[func_idx]); 429 } 430 431 static void prepare_send_mbox(struct hinic_mbox_func_to_func *func_to_func) 432 { 433 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox; 434 435 send_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif); 436 } 437 438 static int alloc_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func) 439 { 440 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox; 441 struct hinic_hwdev *hwdev = func_to_func->hwdev; 442 struct hinic_hwif *hwif = hwdev->hwif; 443 u32 addr_h, addr_l; 444 445 send_mbox->wb_vaddr = dma_zalloc_coherent(hwdev, MBOX_WB_STATUS_LEN, 446 &send_mbox->wb_paddr, SOCKET_ID_ANY); 447 if (!send_mbox->wb_vaddr) { 448 PMD_DRV_LOG(ERR, "Allocating memory for mailbox wb status failed"); 449 return -ENOMEM; 450 } 451 send_mbox->wb_status = (volatile u64 *)send_mbox->wb_vaddr; 452 453 addr_h = upper_32_bits(send_mbox->wb_paddr); 454 addr_l = lower_32_bits(send_mbox->wb_paddr); 455 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, addr_h); 456 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, addr_l); 457 458 return 0; 459 } 460 461 static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func) 462 { 463 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox; 464 struct hinic_hwdev *hwdev = func_to_func->hwdev; 465 struct hinic_hwif *hwif = hwdev->hwif; 466 467 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, 0); 468 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, 0); 469 470 dma_free_coherent(hwdev, MBOX_WB_STATUS_LEN, 471 send_mbox->wb_vaddr, send_mbox->wb_paddr); 472 } 473 474 static int recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, 475 void *header, struct hinic_recv_mbox *recv_mbox, void *param) 476 { 477 u64 mbox_header = *((u64 *)header); 478 void *mbox_body = MBOX_BODY_FROM_HDR(header); 479 u16 src_func_idx; 480 enum hinic_hwif_direction_type direction; 481 u8 seq_id, seg_len; 482 u8 msg_id; 483 u8 front_id; 484 485 seq_id = HINIC_MBOX_HEADER_GET(mbox_header, SEQID); 486 seg_len = HINIC_MBOX_HEADER_GET(mbox_header, SEG_LEN); 487 direction = HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION); 488 src_func_idx = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX); 489 msg_id = HINIC_MBOX_HEADER_GET(mbox_header, MSG_ID); 490 front_id = recv_mbox->seq_id; 491 492 if (!check_mbox_seq_id_and_seg_len(recv_mbox, seq_id, seg_len, 493 msg_id)) { 494 PMD_DRV_LOG(ERR, 495 "Mailbox sequence and segment check failed, src func id: 0x%x, " 496 "front id: 0x%x, current id: 0x%x, seg len: 0x%x " 497 "front msg_id: %d, cur msg_id: %d", 498 src_func_idx, front_id, seq_id, seg_len, 499 recv_mbox->msg_info.msg_id, msg_id); 500 return HINIC_ERROR; 501 } 502 503 memcpy((u8 *)recv_mbox->mbox + seq_id * HINIC_MSG_SEG_LEN, 504 mbox_body, seg_len); 505 506 if (!HINIC_MBOX_HEADER_GET(mbox_header, LAST)) 507 return HINIC_ERROR; 508 509 recv_mbox->seq_id = 0; 510 recv_mbox->cmd = HINIC_MBOX_HEADER_GET(mbox_header, CMD); 511 recv_mbox->mod = HINIC_MBOX_HEADER_GET(mbox_header, MODULE); 512 recv_mbox->mbox_len = HINIC_MBOX_HEADER_GET(mbox_header, MSG_LEN); 513 recv_mbox->ack_type = HINIC_MBOX_HEADER_GET(mbox_header, NO_ACK); 514 recv_mbox->msg_info.msg_id = HINIC_MBOX_HEADER_GET(mbox_header, MSG_ID); 515 recv_mbox->msg_info.status = HINIC_MBOX_HEADER_GET(mbox_header, STATUS); 516 517 if (direction == HINIC_HWIF_RESPONSE) { 518 if (recv_mbox->msg_info.msg_id == func_to_func->send_msg_id && 519 func_to_func->event_flag == EVENT_START) { 520 return HINIC_OK; 521 } 522 523 PMD_DRV_LOG(ERR, "Mbox response timeout, current send msg id(0x%x), recv msg id(0x%x), status(0x%x)", 524 func_to_func->send_msg_id, recv_mbox->msg_info.msg_id, 525 recv_mbox->msg_info.status); 526 return HINIC_ERROR; 527 } 528 529 recv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param); 530 531 return HINIC_ERROR; 532 } 533 534 /** 535 * hinic_mbox_func_aeqe_handler - Process mbox info from func which is 536 * sent by aeqe. 537 * 538 * @param handle 539 * Pointer to hradware nic device. 540 * @param header 541 * Mbox header info. 542 * @param size 543 * The size of aeqe descriptor. 544 * @param param 545 * customized parameter. 546 * 547 * @return 548 * 0 on success, negative error value otherwise. 549 */ 550 int hinic_mbox_func_aeqe_handler(void *handle, u8 *header, 551 __rte_unused u8 size, void *param) 552 { 553 struct hinic_mbox_func_to_func *func_to_func = 554 ((struct hinic_hwdev *)handle)->func_to_func; 555 struct hinic_recv_mbox *recv_mbox; 556 u64 mbox_header = *((u64 *)header); 557 u16 src = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX); 558 559 if (src >= HINIC_MAX_FUNCTIONS) { 560 PMD_DRV_LOG(ERR, "Mailbox source function id: %d is invalid", 561 src); 562 return HINIC_ERROR; 563 } 564 565 recv_mbox = (HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION) == 566 HINIC_HWIF_DIRECT_SEND) ? 567 &func_to_func->mbox_send[src] : 568 &func_to_func->mbox_resp[src]; 569 570 return recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param); 571 } 572 573 static u16 get_mbox_status(struct hinic_send_mbox *mbox) 574 { 575 /* write back is 16B, but only use first 4B */ 576 u64 wb_val = be64_to_cpu(*mbox->wb_status); 577 578 rte_rmb(); /* verify reading before check */ 579 580 return (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK); 581 } 582 583 static void dump_mox_reg(struct hinic_hwdev *hwdev) 584 { 585 u32 val; 586 587 val = hinic_hwif_read_reg(hwdev->hwif, 588 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF); 589 PMD_DRV_LOG(WARNING, "Mailbox control reg: 0x%x", val); 590 val = hinic_hwif_read_reg(hwdev->hwif, 591 HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF); 592 PMD_DRV_LOG(WARNING, "Mailbox interrupt offset: 0x%x", val); 593 } 594 595 static int send_mbox_seg(struct hinic_mbox_func_to_func *func_to_func, 596 u64 header, u16 dst_func, void *seg, u16 seg_len) 597 { 598 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox; 599 struct hinic_hwdev *hwdev = func_to_func->hwdev; 600 u16 seq_dir = HINIC_MBOX_HEADER_GET(header, DIRECTION); 601 u16 dst_aeqn, seg_ack_aeqn; 602 u16 err_code, wb_status = 0; 603 u32 cnt = 0; 604 605 dst_aeqn = mbox_msg_dst_aeqn(hwdev, seq_dir); 606 seg_ack_aeqn = mbox_seg_ack_aeqn(hwdev); 607 608 clear_mbox_status(send_mbox); 609 610 mbox_copy_header(send_mbox, &header); 611 612 mbox_copy_send_data(send_mbox, seg, seg_len); 613 614 write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_ack_aeqn, 615 seg_len, MBOX_SEND_MSG_POLL); 616 617 rte_wmb(); 618 619 while (cnt < MBOX_MSG_POLLING_TIMEOUT_MS) { 620 wb_status = get_mbox_status(send_mbox); 621 if (MBOX_STATUS_FINISHED(wb_status)) 622 break; 623 624 rte_delay_ms(1); /* loop every ms */ 625 cnt++; 626 } 627 628 if (cnt == MBOX_MSG_POLLING_TIMEOUT_MS) { 629 PMD_DRV_LOG(ERR, "Send mailbox segment timeout, wb status: 0x%x", 630 wb_status); 631 dump_mox_reg(hwdev); 632 return -ETIMEDOUT; 633 } 634 635 if (!MBOX_STATUS_SUCCESS(wb_status)) { 636 PMD_DRV_LOG(ERR, "Send mailbox segment to function %d error, wb status: 0x%x", 637 dst_func, wb_status); 638 /* 639 * err_code: 0 responses no errors, other values can 640 * refer to FS doc. 641 */ 642 err_code = MBOX_STATUS_ERRCODE(wb_status); 643 return err_code ? err_code : -EFAULT; 644 } 645 646 return 0; 647 } 648 649 static void set_mbox_to_func_event(struct hinic_mbox_func_to_func *func_to_func, 650 enum mbox_event_state event_flag) 651 { 652 spin_lock(&func_to_func->mbox_lock); 653 func_to_func->event_flag = event_flag; 654 spin_unlock(&func_to_func->mbox_lock); 655 } 656 657 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, 658 enum hinic_mod_type mod, u16 cmd, void *msg, 659 u16 msg_len, u16 dst_func, 660 enum hinic_hwif_direction_type direction, 661 enum hinic_mbox_ack_type ack_type, 662 struct mbox_msg_info *msg_info) 663 { 664 struct hinic_hwdev *hwdev = func_to_func->hwdev; 665 int err = 0; 666 u32 seq_id = 0; 667 u16 seg_len = HINIC_MSG_SEG_LEN; 668 u16 left = msg_len; 669 u8 *msg_seg = (u8 *)msg; 670 u64 header = 0; 671 672 err = hinic_mutex_lock(&func_to_func->msg_send_mutex); 673 if (err) 674 return err; 675 676 header = HINIC_MBOX_HEADER_SET(msg_len, MSG_LEN) | 677 HINIC_MBOX_HEADER_SET(mod, MODULE) | 678 HINIC_MBOX_HEADER_SET(seg_len, SEG_LEN) | 679 HINIC_MBOX_HEADER_SET(ack_type, NO_ACK) | 680 HINIC_MBOX_HEADER_SET(SEQ_ID_START_VAL, SEQID) | 681 HINIC_MBOX_HEADER_SET(NOT_LAST_SEG, LAST) | 682 HINIC_MBOX_HEADER_SET(direction, DIRECTION) | 683 HINIC_MBOX_HEADER_SET(cmd, CMD) | 684 HINIC_MBOX_HEADER_SET(msg_info->msg_id, MSG_ID) | 685 HINIC_MBOX_HEADER_SET(msg_info->status, STATUS) | 686 HINIC_MBOX_HEADER_SET(hinic_global_func_id(hwdev), 687 SRC_GLB_FUNC_IDX); 688 689 while (!(HINIC_MBOX_HEADER_GET(header, LAST))) { 690 if (left <= HINIC_MSG_SEG_LEN) { 691 header &= 692 ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEG_LEN_MASK, 693 SEG_LEN)); 694 header |= HINIC_MBOX_HEADER_SET(left, SEG_LEN); 695 header |= HINIC_MBOX_HEADER_SET(LAST_SEG, LAST); 696 697 seg_len = left; 698 } 699 700 err = send_mbox_seg(func_to_func, header, dst_func, msg_seg, 701 seg_len); 702 if (err) { 703 PMD_DRV_LOG(ERR, "Fail to send mbox seg, err: %d", err); 704 goto send_err; 705 } 706 707 left -= HINIC_MSG_SEG_LEN; 708 msg_seg += HINIC_MSG_SEG_LEN; 709 710 seq_id++; 711 header &= ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEQID_MASK, 712 SEQID)); 713 header |= HINIC_MBOX_HEADER_SET(seq_id, SEQID); 714 } 715 716 send_err: 717 (void)hinic_mutex_unlock(&func_to_func->msg_send_mutex); 718 719 return err; 720 } 721 722 static int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, 723 enum hinic_mod_type mod, u16 cmd, u16 dst_func, 724 void *buf_in, u16 in_size, void *buf_out, u16 *out_size, 725 u32 timeout) 726 { 727 struct hinic_recv_mbox *mbox_for_resp = 728 &func_to_func->mbox_resp[dst_func]; 729 struct mbox_msg_info msg_info = {0}; 730 u32 time; 731 int err; 732 733 err = hinic_mutex_lock(&func_to_func->mbox_send_mutex); 734 if (err) 735 return err; 736 737 msg_info.msg_id = (MBOX_MSG_ID(func_to_func) + 1) & MBOX_MSG_ID_MASK; 738 MBOX_MSG_ID(func_to_func) = msg_info.msg_id; 739 740 set_mbox_to_func_event(func_to_func, EVENT_START); 741 742 err = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size, 743 dst_func, HINIC_HWIF_DIRECT_SEND, 744 MBOX_ACK, &msg_info); 745 if (err) 746 goto send_err; 747 748 time = msecs_to_jiffies(timeout ? timeout : HINIC_MBOX_COMP_TIME_MS); 749 err = hinic_aeq_poll_msg(func_to_func->ack_aeq, time, NULL); 750 if (err) { 751 set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT); 752 PMD_DRV_LOG(ERR, "Send mailbox message time out"); 753 err = -ETIMEDOUT; 754 goto send_err; 755 } 756 757 set_mbox_to_func_event(func_to_func, EVENT_END); 758 759 if (mbox_for_resp->msg_info.status) { 760 err = mbox_for_resp->msg_info.status; 761 if (err != HINIC_MBOX_PF_BUSY_ACTIVE_FW) 762 PMD_DRV_LOG(ERR, "Mailbox response error: 0x%x", 763 mbox_for_resp->msg_info.status); 764 else 765 PMD_DRV_LOG(ERR, "Chip is in active, PF can't process VF message"); 766 goto send_err; 767 } 768 769 rte_rmb(); 770 771 if (mbox_for_resp->mbox_len && buf_out && out_size) { 772 if (mbox_for_resp->mbox_len <= *out_size) { 773 memcpy(buf_out, mbox_for_resp->mbox, 774 mbox_for_resp->mbox_len); 775 *out_size = mbox_for_resp->mbox_len; 776 } else { 777 PMD_DRV_LOG(ERR, "Mailbox response message len[%u] overflow", 778 mbox_for_resp->mbox_len); 779 err = -ERANGE; 780 } 781 } 782 783 send_err: 784 if (err && out_size) 785 *out_size = 0; 786 (void)hinic_mutex_unlock(&func_to_func->mbox_send_mutex); 787 788 return err; 789 } 790 791 static int 792 mbox_func_params_valid(__rte_unused struct hinic_mbox_func_to_func *mbox_obj, 793 void *buf_in, u16 in_size) 794 { 795 if (!buf_in || !in_size) 796 return -EINVAL; 797 798 if (in_size > HINIC_MBOX_DATA_SIZE) { 799 PMD_DRV_LOG(ERR, "Mailbox message len(%d) exceed limit(%d)", 800 in_size, HINIC_MBOX_DATA_SIZE); 801 return -EINVAL; 802 } 803 804 return 0; 805 } 806 807 static u8 hinic_pf_id_of_vf(void *hwdev) 808 { 809 struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif; 810 return hwif->attr.port_to_port_idx; 811 } 812 813 /** 814 * hinic_mbox_to_pf - Send mbox info to pf and need pf to response. 815 * 816 * @param hwdev 817 * Pointer to hardware nic device. 818 * @param mod 819 * Mode type of hardware. 820 * @param cmd 821 * The command sent to pf. 822 * @param buf_in 823 * Input parameter. 824 * @param in_size 825 * Input parameter size. 826 * @param buf_out 827 * Output parameter. 828 * @param out_size 829 * Output parameter size. 830 * @param timeout 831 * Timeout. 832 * 833 * @return 834 * 0 on success, negative error value otherwise. 835 */ 836 int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, 837 enum hinic_mod_type mod, u8 cmd, void *buf_in, 838 u16 in_size, void *buf_out, u16 *out_size, u32 timeout) 839 { 840 struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func; 841 int err; 842 843 err = mbox_func_params_valid(func_to_func, buf_in, in_size); 844 if (err) { 845 PMD_DRV_LOG(ERR, "Mailbox parameters check failed: %d", err); 846 return err; 847 } 848 849 if (!HINIC_IS_VF(hwdev)) { 850 PMD_DRV_LOG(ERR, "Input function type error, func_type: %d", 851 hinic_func_type(hwdev)); 852 return -EINVAL; 853 } 854 855 return hinic_mbox_to_func(func_to_func, mod, cmd, 856 hinic_pf_id_of_vf(hwdev), buf_in, in_size, 857 buf_out, out_size, timeout); 858 } 859 860 /** 861 * hinic_mbox_to_pf_no_ack - Send mbox info to pf and do not need pf to response 862 * 863 * @param hwdev 864 * Pointer to hardware nic device. 865 * @param mod 866 * Mode type of hardware. 867 * @param cmd 868 * The command sent to pf. 869 * @param buf_in 870 * Input parameter. 871 * @param in_size 872 * Input parameter size. 873 * 874 * @return 875 * 0 on success, negative error value otherwise. 876 */ 877 int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, 878 u8 cmd, void *buf_in, u16 in_size) 879 { 880 int err; 881 struct mbox_msg_info msg_info = {0}; 882 883 err = hinic_mutex_lock(&hwdev->func_to_func->mbox_send_mutex); 884 if (err) 885 return err; 886 887 err = send_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in, in_size, 888 hinic_pf_id_of_vf(hwdev), HINIC_HWIF_DIRECT_SEND, 889 MBOX_NO_ACK, &msg_info); 890 if (err) 891 PMD_DRV_LOG(ERR, "Send mailbox no ack failed, err: %d", err); 892 893 (void)hinic_mutex_unlock(&hwdev->func_to_func->mbox_send_mutex); 894 895 return err; 896 } 897 898 static int hinic_func_to_func_init(struct hinic_hwdev *hwdev) 899 { 900 struct hinic_mbox_func_to_func *func_to_func; 901 int err; 902 903 func_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL); 904 if (!func_to_func) { 905 PMD_DRV_LOG(ERR, "Allocating memory for func_to_func object failed"); 906 return -ENOMEM; 907 } 908 hwdev->func_to_func = func_to_func; 909 func_to_func->hwdev = hwdev; 910 (void)hinic_mutex_init(&func_to_func->mbox_send_mutex, NULL); 911 (void)hinic_mutex_init(&func_to_func->msg_send_mutex, NULL); 912 913 err = alloc_mbox_info(func_to_func->mbox_send); 914 if (err) { 915 PMD_DRV_LOG(ERR, "Allocating memory for mailbox sending failed"); 916 goto alloc_mbox_for_send_err; 917 } 918 919 err = alloc_mbox_info(func_to_func->mbox_resp); 920 if (err) { 921 PMD_DRV_LOG(ERR, "Allocating memory for mailbox responding failed"); 922 goto alloc_mbox_for_resp_err; 923 } 924 925 err = alloc_mbox_wb_status(func_to_func); 926 if (err) 927 goto alloc_wb_status_err; 928 929 prepare_send_mbox(func_to_func); 930 931 return 0; 932 933 alloc_wb_status_err: 934 free_mbox_info(func_to_func->mbox_resp); 935 936 alloc_mbox_for_resp_err: 937 free_mbox_info(func_to_func->mbox_send); 938 939 alloc_mbox_for_send_err: 940 kfree(func_to_func); 941 942 return err; 943 } 944 945 /** 946 * hinic_comm_func_to_func_free - Uninitialize func to func resource. 947 * 948 * @param hwdev 949 * Pointer to hardware nic device. 950 */ 951 void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev) 952 { 953 struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func; 954 955 free_mbox_wb_status(func_to_func); 956 free_mbox_info(func_to_func->mbox_resp); 957 free_mbox_info(func_to_func->mbox_send); 958 (void)hinic_mutex_destroy(&func_to_func->mbox_send_mutex); 959 (void)hinic_mutex_destroy(&func_to_func->msg_send_mutex); 960 kfree(func_to_func); 961 } 962 963 /** 964 * hinic_comm_func_to_func_init - Initialize func to func resource. 965 * 966 * @param hwdev 967 * Pointer to hardware nic device. 968 */ 969 int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev) 970 { 971 int rc; 972 u16 msg_ack_aeqn; 973 974 rc = hinic_func_to_func_init(hwdev); 975 if (rc) 976 return rc; 977 978 msg_ack_aeqn = mbox_msg_ack_aeqn(hwdev); 979 980 hwdev->func_to_func->ack_aeq = &hwdev->aeqs->aeq[msg_ack_aeqn]; 981 hwdev->func_to_func->recv_aeq = &hwdev->aeqs->aeq[HINIC_AEQN_0]; 982 983 return 0; 984 } 985 986