[dpdk-dev] [PATCH v7 05/14] net/avf: enable link status update

Wenzhuo Lu wenzhuo.lu at intel.com
Wed Jan 10 14:01:57 CET 2018


From: Jingjing Wu <jingjing.wu at intel.com>

Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
---
 doc/guides/nics/features/avf.ini |  3 +++
 drivers/net/avf/avf.h            |  2 ++
 drivers/net/avf/avf_ethdev.c     | 51 +++++++++++++++++++++++++++++++++++++++-
 drivers/net/avf/avf_vchnl.c      | 38 +++++++++++++++++++++++++++++-
 4 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/avf.ini b/doc/guides/nics/features/avf.ini
index 8a294e9..77e4f53 100644
--- a/doc/guides/nics/features/avf.ini
+++ b/doc/guides/nics/features/avf.ini
@@ -4,6 +4,9 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Speed capabilities   = Y
+Link status          = Y
+Link status event    = Y
 Queue start/stop     = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
diff --git a/drivers/net/avf/avf.h b/drivers/net/avf/avf.h
index 22886d4..c97b2ee 100644
--- a/drivers/net/avf/avf.h
+++ b/drivers/net/avf/avf.h
@@ -202,4 +202,6 @@ int avf_switch_queue(struct avf_adapter *adapter, uint16_t qid,
 int avf_configure_queues(struct avf_adapter *adapter);
 int avf_config_irq_map(struct avf_adapter *adapter);
 void avf_add_del_all_mac_addr(struct avf_adapter *adapter, bool add);
+int avf_dev_link_update(struct rte_eth_dev *dev,
+			__rte_unused int wait_to_complete);
 #endif /* _AVF_ETHDEV_H_ */
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index 4480989..7f7ddf9 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -55,6 +55,7 @@ static void avf_dev_info_get(struct rte_eth_dev *dev,
 	.dev_close                  = avf_dev_close,
 	.dev_infos_get              = avf_dev_info_get,
 	.dev_supported_ptypes_get   = avf_dev_supported_ptypes_get,
+	.link_update                = avf_dev_link_update,
 	.rx_queue_start             = avf_dev_rx_queue_start,
 	.rx_queue_stop              = avf_dev_rx_queue_stop,
 	.tx_queue_start             = avf_dev_tx_queue_start,
@@ -429,6 +430,53 @@ static void avf_dev_info_get(struct rte_eth_dev *dev,
 	return ptypes;
 }
 
+int
+avf_dev_link_update(struct rte_eth_dev *dev,
+		    __rte_unused int wait_to_complete)
+{
+	struct rte_eth_link new_link;
+	struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+	/* Only read status info stored in VF, and the info is updated
+	 *  when receive LINK_CHANGE evnet from PF by Virtchnnl.
+	 */
+	switch (vf->link_speed) {
+	case VIRTCHNL_LINK_SPEED_100MB:
+		new_link.link_speed = ETH_SPEED_NUM_100M;
+		break;
+	case VIRTCHNL_LINK_SPEED_1GB:
+		new_link.link_speed = ETH_SPEED_NUM_1G;
+		break;
+	case VIRTCHNL_LINK_SPEED_10GB:
+		new_link.link_speed = ETH_SPEED_NUM_10G;
+		break;
+	case VIRTCHNL_LINK_SPEED_20GB:
+		new_link.link_speed = ETH_SPEED_NUM_20G;
+		break;
+	case VIRTCHNL_LINK_SPEED_25GB:
+		new_link.link_speed = ETH_SPEED_NUM_25G;
+		break;
+	case VIRTCHNL_LINK_SPEED_40GB:
+		new_link.link_speed = ETH_SPEED_NUM_40G;
+		break;
+	default:
+		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		break;
+	}
+
+	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP :
+					     ETH_LINK_DOWN;
+	new_link.link_autoneg = !!(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
+
+	rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
+			    *(uint64_t *)&dev->data->dev_link,
+			    *(uint64_t *)&new_link);
+
+	return 0;
+}
+
 static int
 avf_check_vf_reset_done(struct avf_hw *hw)
 {
@@ -712,7 +760,8 @@ static int eth_avf_pci_remove(struct rte_pci_device *pci_dev)
 /* Adaptive virtual function driver struct */
 static struct rte_pci_driver rte_avf_pmd = {
 	.id_table = pci_id_avf_map,
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+		     RTE_PCI_DRV_IOVA_AS_VA,
 	.probe = eth_avf_pci_probe,
 	.remove = eth_avf_pci_remove,
 };
diff --git a/drivers/net/avf/avf_vchnl.c b/drivers/net/avf/avf_vchnl.c
index 55a425a..f5da601 100644
--- a/drivers/net/avf/avf_vchnl.c
+++ b/drivers/net/avf/avf_vchnl.c
@@ -133,6 +133,41 @@
 	return err;
 }
 
+static void
+avf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
+			uint16_t msglen)
+{
+	struct virtchnl_pf_event *pf_msg =
+			(struct virtchnl_pf_event *)msg;
+	struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+	if (msglen < sizeof(struct virtchnl_pf_event)) {
+		PMD_DRV_LOG(DEBUG, "Error event");
+		return;
+	}
+	switch (pf_msg->event) {
+	case VIRTCHNL_EVENT_RESET_IMPENDING:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+					      NULL, NULL);
+		break;
+	case VIRTCHNL_EVENT_LINK_CHANGE:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
+		vf->link_up = pf_msg->event_data.link_event.link_status;
+		vf->link_speed = pf_msg->event_data.link_event.link_speed;
+		avf_dev_link_update(dev, 0);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
+		break;
+	case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
+		break;
+	default:
+		PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
+		break;
+	}
+}
+
 void
 avf_handle_virtchnl_msg(struct rte_eth_dev *dev)
 {
@@ -172,7 +207,8 @@
 		switch (aq_opc) {
 		case avf_aqc_opc_send_msg_to_vf:
 			if (msg_opc == VIRTCHNL_OP_EVENT) {
-				/* TODO */
+				avf_handle_pf_event_msg(dev, info.msg_buf,
+							info.msg_len);
 			} else {
 				/* read message and it's expected one */
 				if (msg_opc == vf->pend_cmd) {
-- 
1.9.3



More information about the dev mailing list