Commit 8f571c4c authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-next'



Huazhong Tan says:

====================
net: hns3: updates for -next

This series adds support for pushing link status to VFs for
the HNS3 ethernet driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c329e5af 01305e16
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -172,4 +172,7 @@ struct hclgevf_mbx_arq_ring {
		(arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
#define hclge_mbx_head_ptr_move_arq(arq) \
		(arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)

/* PF immediately push link status to VFs when link status changed */
#define HCLGE_MBX_PUSH_LINK_STATUS_EN			BIT(0)
#endif
+34 −1
Original line number Diff line number Diff line
@@ -2880,6 +2880,28 @@ static int hclge_get_mac_phy_link(struct hclge_dev *hdev, int *link_status)
	return hclge_get_mac_link_status(hdev, link_status);
}

static void hclge_push_link_status(struct hclge_dev *hdev)
{
	struct hclge_vport *vport;
	int ret;
	u16 i;

	for (i = 0; i < pci_num_vf(hdev->pdev); i++) {
		vport = &hdev->vport[i + HCLGE_VF_VPORT_START_NUM];

		if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) ||
		    vport->vf_info.link_state != IFLA_VF_LINK_STATE_AUTO)
			continue;

		ret = hclge_push_vf_link_status(vport);
		if (ret) {
			dev_err(&hdev->pdev->dev,
				"failed to push link status to vf%u, ret = %d\n",
				i, ret);
		}
	}
}

static void hclge_update_link_status(struct hclge_dev *hdev)
{
	struct hnae3_handle *rhandle = &hdev->vport[0].roce;
@@ -2908,6 +2930,7 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
			rclient->ops->link_status_change(rhandle, state);

		hdev->hw.mac.link = state;
		hclge_push_link_status(hdev);
	}

	clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
@@ -3246,14 +3269,24 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	int link_state_old;
	int ret;

	vport = hclge_get_vf_vport(hdev, vf);
	if (!vport)
		return -EINVAL;

	link_state_old = vport->vf_info.link_state;
	vport->vf_info.link_state = link_state;

	return 0;
	ret = hclge_push_vf_link_status(vport);
	if (ret) {
		vport->vf_info.link_state = link_state_old;
		dev_err(&hdev->pdev->dev,
			"failed to push vf%d link status, ret = %d\n", vf, ret);
	}

	return ret;
}

static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
+1 −0
Original line number Diff line number Diff line
@@ -1089,4 +1089,5 @@ void hclge_report_hw_error(struct hclge_dev *hdev,
			   enum hnae3_hw_error_type type);
void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
void hclge_dbg_dump_rst_info(struct hclge_dev *hdev);
int hclge_push_vf_link_status(struct hclge_vport *vport);
#endif
+5 −7
Original line number Diff line number Diff line
@@ -490,16 +490,14 @@ static void hclge_get_vf_media_type(struct hclge_vport *vport,
	resp_msg->len = HCLGE_VF_MEDIA_TYPE_LENGTH;
}

static int hclge_get_link_info(struct hclge_vport *vport,
			       struct hclge_mbx_vf_to_pf_cmd *mbx_req)
int hclge_push_vf_link_status(struct hclge_vport *vport)
{
#define HCLGE_VF_LINK_STATE_UP		1U
#define HCLGE_VF_LINK_STATE_DOWN	0U

	struct hclge_dev *hdev = vport->back;
	u16 link_status;
	u8 msg_data[8];
	u8 dest_vfid;
	u8 msg_data[9];
	u16 duplex;

	/* mac.link can only be 0 or 1 */
@@ -520,11 +518,11 @@ static int hclge_get_link_info(struct hclge_vport *vport,
	memcpy(&msg_data[0], &link_status, sizeof(u16));
	memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
	memcpy(&msg_data[6], &duplex, sizeof(u16));
	dest_vfid = mbx_req->mbx_src_vfid;
	msg_data[8] = HCLGE_MBX_PUSH_LINK_STATUS_EN;

	/* send this requested info to VF */
	return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
				  HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
				  HCLGE_MBX_LINK_STAT_CHANGE, vport->vport_id);
}

static void hclge_get_link_mode(struct hclge_vport *vport,
@@ -794,7 +792,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
			hclge_get_vf_tcinfo(vport, &resp_msg);
			break;
		case HCLGE_MBX_GET_LINK_STATUS:
			ret = hclge_get_link_info(vport, req);
			ret = hclge_push_vf_link_status(vport);
			if (ret)
				dev_err(&hdev->pdev->dev,
					"failed to inform link stat to VF, ret = %d\n",
+5 −3
Original line number Diff line number Diff line
@@ -2340,9 +2340,10 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev)
	if (!(hdev->serv_processed_cnt % HCLGEVF_STATS_TIMER_INTERVAL))
		hclgevf_tqps_update_stats(handle);

	/* request the link status from the PF. PF would be able to tell VF
	 * about such updates in future so we might remove this later
	/* VF does not need to request link status when this bit is set, because
	 * PF will push its link status to VFs when link status changed.
	 */
	if (!test_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS, &hdev->state))
		hclgevf_request_link_info(hdev);

	hclgevf_update_link_mode(hdev);
@@ -2657,6 +2658,7 @@ static int hclgevf_ae_start(struct hnae3_handle *handle)
	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);

	clear_bit(HCLGEVF_STATE_DOWN, &hdev->state);
	clear_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS, &hdev->state);

	hclgevf_reset_tqp_stats(handle);

Loading