Commit b83bb584 authored by Fan Gong's avatar Fan Gong Committed by Paolo Abeni
Browse files

hinic3: Tx & Rx configuration

parent 97dcb914
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -75,6 +75,21 @@ struct l2nic_cmd_force_pkt_drop {
	u8                   rsvd1[3];
};

struct l2nic_cmd_set_dcb_state {
	struct mgmt_msg_head head;
	u16                  func_id;
	/* 0 - get dcb state, 1 - set dcb state */
	u8                   op_code;
	/* 0 - disable, 1 - enable dcb */
	u8                   state;
	/* 0 - disable, 1 - enable dcb */
	u8                   port_state;
	u8                   rsvd[7];
};

/* IEEE 802.1Qaz std */
#define L2NIC_DCB_COS_MAX     0x8

/* Commands between NIC to fw */
enum l2nic_cmd {
	/* FUNC CFG */
+55 −1
Original line number Diff line number Diff line
@@ -184,6 +184,47 @@ static void hinic3_free_txrxq_resources(struct net_device *netdev,
	q_params->txqs_res = NULL;
}

static int hinic3_configure_txrxqs(struct net_device *netdev,
				   struct hinic3_dyna_txrxq_params *q_params)
{
	int err;

	err = hinic3_configure_txqs(netdev, q_params->num_qps,
				    q_params->sq_depth, q_params->txqs_res);
	if (err) {
		netdev_err(netdev, "Failed to configure txqs\n");
		return err;
	}

	err = hinic3_configure_rxqs(netdev, q_params->num_qps,
				    q_params->rq_depth, q_params->rxqs_res);
	if (err) {
		netdev_err(netdev, "Failed to configure rxqs\n");
		return err;
	}

	return 0;
}

static int hinic3_configure(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	int err;

	netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
	netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
	err = hinic3_set_port_mtu(netdev, netdev->mtu);
	if (err) {
		netdev_err(netdev, "Failed to set mtu\n");
		return err;
	}

	/* Ensure DCB is disabled */
	hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);

	return 0;
}

static int hinic3_alloc_channel_resources(struct net_device *netdev,
					  struct hinic3_dyna_qp_params *qp_params,
					  struct hinic3_dyna_txrxq_params *trxq_params)
@@ -232,14 +273,28 @@ static int hinic3_open_channel(struct net_device *netdev)
		return err;
	}

	err = hinic3_configure_txrxqs(netdev, &nic_dev->q_params);
	if (err) {
		netdev_err(netdev, "Failed to configure txrxqs\n");
		goto err_free_qp_ctxts;
	}

	err = hinic3_qps_irq_init(netdev);
	if (err) {
		netdev_err(netdev, "Failed to init txrxq irq\n");
		goto err_free_qp_ctxts;
	}

	err = hinic3_configure(netdev);
	if (err) {
		netdev_err(netdev, "Failed to init txrxq irq\n");
		goto err_uninit_qps_irq;
	}

	return 0;

err_uninit_qps_irq:
	hinic3_qps_irq_uninit(netdev);
err_free_qp_ctxts:
	hinic3_free_qp_ctxts(nic_dev);

@@ -288,7 +343,6 @@ static int hinic3_open(struct net_device *netdev)
err_uninit_qps:
	hinic3_uninit_qps(nic_dev, &qp_params);
	hinic3_free_channel_resources(netdev, &qp_params, &nic_dev->q_params);

err_destroy_num_qps:
	hinic3_destroy_num_qps(netdev);
err_free_nicio_res:
+25 −0
Original line number Diff line number Diff line
@@ -289,3 +289,28 @@ int hinic3_force_drop_tx_pkt(struct hinic3_hwdev *hwdev)

	return pkt_drop.msg_head.status;
}

int hinic3_sync_dcb_state(struct hinic3_hwdev *hwdev, u8 op_code, u8 state)
{
	struct l2nic_cmd_set_dcb_state dcb_state = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	dcb_state.op_code = op_code;
	dcb_state.state = state;
	dcb_state.func_id = hinic3_global_func_id(hwdev);

	mgmt_msg_params_init_default(&msg_params, &dcb_state,
				     sizeof(dcb_state));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC,
				       L2NIC_CMD_QOS_DCB_STATE, &msg_params);
	if (err || dcb_state.head.status) {
		dev_err(hwdev->dev,
			"Failed to set dcb state, err: %d, status: 0x%x\n",
			err, dcb_state.head.status);
		return -EFAULT;
	}

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -52,4 +52,6 @@ int hinic3_set_ci_table(struct hinic3_hwdev *hwdev,
			struct hinic3_sq_attr *attr);
int hinic3_force_drop_tx_pkt(struct hinic3_hwdev *hwdev);

int hinic3_sync_dcb_state(struct hinic3_hwdev *hwdev, u8 op_code, u8 state);

#endif
+64 −0
Original line number Diff line number Diff line
@@ -85,6 +85,27 @@ static int rx_alloc_mapped_page(struct page_pool *page_pool,
	return 0;
}

/* Associate fixed completion element to every wqe in the rq. Every rq wqe will
 * always post completion to the same place.
 */
static void rq_associate_cqes(struct hinic3_rxq *rxq)
{
	struct hinic3_queue_pages *qpages;
	struct hinic3_rq_wqe *rq_wqe;
	dma_addr_t cqe_dma;
	u32 i;

	qpages = &rxq->rq->wq.qpages;

	for (i = 0; i < rxq->q_depth; i++) {
		rq_wqe = get_q_element(qpages, i, NULL);
		cqe_dma = rxq->cqe_start_paddr +
			  i * sizeof(struct hinic3_rq_cqe);
		rq_wqe->cqe_hi_addr = cpu_to_le32(upper_32_bits(cqe_dma));
		rq_wqe->cqe_lo_addr = cpu_to_le32(lower_32_bits(cqe_dma));
	}
}

static void rq_wqe_buf_set(struct hinic3_io_queue *rq, uint32_t wqe_idx,
			   dma_addr_t dma_addr, u16 len)
{
@@ -445,6 +466,49 @@ void hinic3_free_rxqs_res(struct net_device *netdev, u16 num_rq,
	}
}

int hinic3_configure_rxqs(struct net_device *netdev, u16 num_rq,
			  u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	struct hinic3_dyna_rxq_res *rqres;
	struct msix_entry *msix_entry;
	struct hinic3_rxq *rxq;
	u16 q_id;
	u32 pkts;

	for (q_id = 0; q_id < num_rq; q_id++) {
		rxq = &nic_dev->rxqs[q_id];
		rqres = &rxqs_res[q_id];
		msix_entry = &nic_dev->qps_msix_entries[q_id];

		rxq->irq_id = msix_entry->vector;
		rxq->msix_entry_idx = msix_entry->entry;
		rxq->next_to_update = 0;
		rxq->next_to_alloc = rqres->next_to_alloc;
		rxq->q_depth = rq_depth;
		rxq->delta = rxq->q_depth;
		rxq->q_mask = rxq->q_depth - 1;
		rxq->cons_idx = 0;

		rxq->cqe_arr = rqres->cqe_start_vaddr;
		rxq->cqe_start_paddr = rqres->cqe_start_paddr;
		rxq->rx_info = rqres->rx_info;
		rxq->page_pool = rqres->page_pool;

		rxq->rq = &nic_dev->nic_io->rq[rxq->q_id];

		rq_associate_cqes(rxq);

		pkts = hinic3_rx_fill_buffers(rxq);
		if (!pkts) {
			netdev_err(netdev, "Failed to fill Rx buffer\n");
			return -ENOMEM;
		}
	}

	return 0;
}

int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(rxq->netdev);
Loading