/** * hinic_sq_read_wqe - read wqe ptr in the current ci and update the ci * @sq: send queue * @skb: return skb that was saved * @wqe_size: the size of the wqe * @cons_idx: consumer index of the wqe * * Return wqe in ci position **/ struct hinic_sq_wqe *hinic_sq_read_wqe(struct hinic_sq *sq, struct sk_buff **skb, unsigned int *wqe_size, u16 *cons_idx) { struct hinic_hw_wqe *hw_wqe; struct hinic_sq_wqe *sq_wqe; struct hinic_sq_ctrl *ctrl; unsigned int buf_sect_len; u32 ctrl_info; /* read the ctrl section for getting wqe size */ hw_wqe = hinic_read_wqe(sq->wq, sizeof(*ctrl), cons_idx); if (IS_ERR(hw_wqe)) return NULL; sq_wqe = &hw_wqe->sq_wqe; ctrl = &sq_wqe->ctrl; ctrl_info = be32_to_cpu(ctrl->ctrl_info); buf_sect_len = HINIC_SQ_CTRL_GET(ctrl_info, BUFDESC_SECT_LEN); *wqe_size = sizeof(*ctrl) + sizeof(sq_wqe->task); *wqe_size += SECT_SIZE_FROM_8BYTES(buf_sect_len); *skb = sq->saved_skb[*cons_idx]; /* using the real wqe size to read wqe again */ hw_wqe = hinic_read_wqe(sq->wq, *wqe_size, cons_idx); return &hw_wqe->sq_wqe; }
/** * hinic_rq_read_wqe - read wqe ptr in the current ci and update the ci * @rq: recv queue * @wqe_size: the size of the wqe * @skb: return saved skb * @cons_idx: consumer index of the wqe * * Return wqe in ci position **/ struct hinic_rq_wqe *hinic_rq_read_wqe(struct hinic_rq *rq, unsigned int wqe_size, struct sk_buff **skb, u16 *cons_idx) { struct hinic_hw_wqe *hw_wqe; struct hinic_rq_cqe *cqe; int rx_done; u32 status; hw_wqe = hinic_read_wqe(rq->wq, wqe_size, cons_idx); if (IS_ERR(hw_wqe)) return NULL; cqe = rq->cqe[*cons_idx]; status = be32_to_cpu(cqe->status); rx_done = HINIC_RQ_CQE_STATUS_GET(status, RXDONE); if (!rx_done) return NULL; *skb = rq->saved_skb[*cons_idx]; return &hw_wqe->rq_wqe; }
/** * cmdq_ceq_handler - cmdq completion event handler * @handle: private data for the handler(cmdqs) * @ceqe_data: ceq element data **/ static void cmdq_ceq_handler(void *handle, u32 ceqe_data) { enum hinic_cmdq_type cmdq_type = CMDQ_CEQE_GET(ceqe_data, TYPE); struct hinic_cmdqs *cmdqs = (struct hinic_cmdqs *)handle; struct hinic_cmdq *cmdq = &cmdqs->cmdq[cmdq_type]; struct hinic_cmdq_header *header; struct hinic_hw_wqe *hw_wqe; int err, set_arm = 0; u32 saved_data; u16 ci; /* Read the smallest wqe size for getting wqe size */ while ((hw_wqe = hinic_read_wqe(cmdq->wq, WQE_SCMD_SIZE, &ci))) { if (IS_ERR(hw_wqe)) break; header = CMDQ_WQE_HEADER(&hw_wqe->cmdq_wqe); saved_data = be32_to_cpu(header->saved_data); if (HINIC_SAVED_DATA_GET(saved_data, ARM)) { /* arm_bit was set until here */ set_arm = 0; if (cmdq_arm_ceq_handler(cmdq, &hw_wqe->cmdq_wqe)) break; } else { set_arm = 1; hw_wqe = hinic_read_wqe(cmdq->wq, WQE_LCMD_SIZE, &ci); if (IS_ERR(hw_wqe)) break; if (cmdq_cmd_ceq_handler(cmdq, ci, &hw_wqe->cmdq_wqe)) break; } } if (set_arm) { struct hinic_hwif *hwif = cmdqs->hwif; struct pci_dev *pdev = hwif->pdev; err = hinic_set_arm_bit(cmdqs, HINIC_SET_ARM_CMDQ, cmdq_type); if (err) dev_err(&pdev->dev, "Failed to set arm for CMDQ\n"); } }
/** * hinic_sq_read_wqe - read wqe ptr in the current ci and update the ci * @sq: send queue * @skb: return skb that was saved * @wqe_size: the size of the wqe * @cons_idx: consumer index of the wqe * * Return wqe in ci position **/ struct hinic_sq_wqe *hinic_sq_read_wqe(struct hinic_sq *sq, struct sk_buff **skb, unsigned int wqe_size, u16 *cons_idx) { struct hinic_hw_wqe *hw_wqe; hw_wqe = hinic_read_wqe(sq->wq, wqe_size, cons_idx); *skb = sq->saved_skb[*cons_idx]; return &hw_wqe->sq_wqe; }