From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ferruh.yigit@intel.com>
Received: from mga14.intel.com (mga14.intel.com [192.55.52.115])
 by dpdk.org (Postfix) with ESMTP id D1DFDA84F
 for <dev@dpdk.org>; Thu, 11 Jan 2018 18:07:08 +0100 (CET)
X-Amp-Result: SKIPPED(no attachment in message)
X-Amp-File-Uploaded: False
Received: from orsmga003.jf.intel.com ([10.7.209.27])
 by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;
 11 Jan 2018 09:07:08 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.46,345,1511856000"; d="scan'208";a="19346006"
Received: from silpixa00372839.ir.intel.com (HELO
 silpixa00372839.ger.corp.intel.com) ([10.237.222.154])
 by orsmga003.jf.intel.com with ESMTP; 11 Jan 2018 09:07:06 -0800
From: Ferruh Yigit <ferruh.yigit@intel.com>
To: Bruce Richardson <bruce.richardson@intel.com>,
 Konstantin Ananyev <konstantin.ananyev@intel.com>,
 Thomas Monjalon <thomas@monjalon.net>
Cc: dev@dpdk.org, Ferruh Yigit <ferruh.yigit@intel.com>,
 Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 11 Jan 2018 17:06:45 +0000
Message-Id: <20180111170658.2809-2-ferruh.yigit@intel.com>
X-Mailer: git-send-email 2.14.3
In-Reply-To: <20180111170658.2809-1-ferruh.yigit@intel.com>
References: <20180108174514.14688-1-stephen@networkplumber.org>
 <20180111170658.2809-1-ferruh.yigit@intel.com>
Subject: [dpdk-dev] [PATCH v4 02/15] ethdev: add linkstatus get/set helper
	functions
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Thu, 11 Jan 2018 17:07:09 -0000

From: Stephen Hemminger <stephen@networkplumber.org>

Many drivers are all doing copy/paste of the same code to atomically
update the link status. Reduce duplication, and allow for future
changes by having common function for this.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_ether/rte_ethdev.c           | 36 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h           | 28 +++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_version.map |  8 ++++++++
 3 files changed, 72 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b3495992d..4d67248e5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1500,6 +1500,42 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	}
 }
 
+int
+_rte_eth_linkstatus_set(struct rte_eth_dev *dev,
+		       const struct rte_eth_link *new_link)
+{
+	volatile uint64_t *dev_link
+		 = (volatile uint64_t *)&(dev->data->dev_link);
+	union {
+		uint64_t val64;
+		struct rte_eth_link link;
+	} orig;
+
+	RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
+
+	orig.val64 = rte_atomic64_exchange(dev_link,
+					   *(const uint64_t *)new_link);
+
+	return (orig.link.link_status == new_link->link_status) ? -1 : 0;
+}
+
+void
+_rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
+			struct rte_eth_link *link)
+{
+	volatile uint64_t *src = (uint64_t *)&(dev->data->dev_link);
+	uint64_t tmp;
+
+	RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
+
+	/* can't use rte_atomic64_read because it returns signed int */
+	do {
+		tmp = *src;
+	} while (!rte_atomic64_cmpset(src, tmp, tmp));
+
+	memcpy(link, &tmp, sizeof(tmp));
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f0eeefe6a..ffeac5aeb 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2220,6 +2220,34 @@ int rte_eth_dev_set_link_down(uint16_t port_id);
  */
 void rte_eth_dev_close(uint16_t port_id);
 
+
+/**
+ * @internal
+ * Atomically set the link status for the specific device.
+ * It is for use by DPDK device driver use only.
+ * User applications should not call it
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param link
+ *  New link status value.
+ * @return
+ *  0 if link state has changed, -1 if the same.
+ */
+int _rte_eth_linkstatus_set(struct rte_eth_dev *dev,
+			    const struct rte_eth_link *link);
+
+/**
+ * @internal
+ * Atomically get the link speed and status.
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param link
+ *  link status value.
+ */
+void _rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
+			     struct rte_eth_link *link);
+
 /**
  * Reset a Ethernet device and keep its port id.
  *
diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/rte_ethdev_version.map
index e9681ac8e..5ff629cb9 100644
--- a/lib/librte_ether/rte_ethdev_version.map
+++ b/lib/librte_ether/rte_ethdev_version.map
@@ -198,6 +198,14 @@ DPDK_17.11 {
 
 } DPDK_17.08;
 
+DPDK_18.02 {
+	global:
+
+	_rte_eth_linkstatus_get;
+	_rte_eth_linkstatus_set;
+
+} DPDK_17.11;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.14.3