[v3,05/10] net/atlantic: use EEPROM magic as a device address

Message ID 13dc16dc55b42d6ba0df358ad727308938fde8cf.1552402263.git.igor.russkikh@aquantia.com
State Under Review
Delegated to: Ferruh Yigit
Headers show
Series
  • net/atlantic: bugfixes and code cleanup
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Igor Russkikh March 12, 2019, 3:24 p.m.
From: Pavel Belous <Pavel.Belous@aquantia.com>

Default dev addr is replaced with magic field from the request.
Length is allowed to be less than maximum.
SMBUS access bit definitions also better organised now.

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Pavel Belous <Pavel.Belous@aquantia.com>
---
 drivers/net/atlantic/atl_ethdev.c             | 25 +++++++++++-----
 drivers/net/atlantic/atl_types.h              |  7 +++--
 drivers/net/atlantic/hw_atl/hw_atl_utils.c    |  4 +++
 drivers/net/atlantic/hw_atl/hw_atl_utils.h    | 23 +++++++-------
 .../net/atlantic/hw_atl/hw_atl_utils_fw2x.c   | 30 +++++++++++--------
 5 files changed, 58 insertions(+), 31 deletions(-)

Patch

diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 5bc04f55cc21..a510646a5f7e 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -1102,24 +1102,31 @@  atl_dev_get_eeprom_length(struct rte_eth_dev *dev __rte_unused)
 	return SFP_EEPROM_SIZE;
 }
 
-static int
-atl_dev_get_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom)
+int atl_dev_get_eeprom(struct rte_eth_dev *dev,
+		       struct rte_dev_eeprom_info *eeprom)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t dev_addr = SMBUS_DEVICE_ID;
 
 	if (hw->aq_fw_ops->get_eeprom == NULL)
 		return -ENOTSUP;
 
-	if (eeprom->length != SFP_EEPROM_SIZE || eeprom->data == NULL)
+	if (eeprom->length + eeprom->offset > SFP_EEPROM_SIZE ||
+	    eeprom->data == NULL)
 		return -EINVAL;
 
-	return hw->aq_fw_ops->get_eeprom(hw, eeprom->data, eeprom->length);
+	if (eeprom->magic)
+		dev_addr = eeprom->magic;
+
+	return hw->aq_fw_ops->get_eeprom(hw, dev_addr, eeprom->data,
+					 eeprom->length, eeprom->offset);
 }
 
-static int
-atl_dev_set_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom)
+int atl_dev_set_eeprom(struct rte_eth_dev *dev,
+		       struct rte_dev_eeprom_info *eeprom)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t dev_addr = SMBUS_DEVICE_ID;
 
 	if (hw->aq_fw_ops->set_eeprom == NULL)
 		return -ENOTSUP;
@@ -1127,7 +1134,11 @@  atl_dev_set_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom)
 	if (eeprom->length != SFP_EEPROM_SIZE || eeprom->data == NULL)
 		return -EINVAL;
 
-	return hw->aq_fw_ops->set_eeprom(hw, eeprom->data, eeprom->length);
+	if (eeprom->magic)
+		dev_addr = eeprom->magic;
+
+	return hw->aq_fw_ops->set_eeprom(hw, dev_addr,
+					 eeprom->data, eeprom->length);
 }
 
 static int
diff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h
index 3d90f6caefc2..3edaf0c7c047 100644
--- a/drivers/net/atlantic/atl_types.h
+++ b/drivers/net/atlantic/atl_types.h
@@ -137,9 +137,12 @@  struct aq_fw_ops {
 
 	int (*led_control)(struct aq_hw_s *self, u32 mode);
 
-	int (*get_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);
+	int (*get_eeprom)(struct aq_hw_s *self, int dev_addr,
+			  u32 *data, u32 len, u32 offset);
+
+	int (*set_eeprom)(struct aq_hw_s *self, int dev_addr,
+			  u32 *data, u32 len);
 
-	int (*set_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);
 };
 
 struct atl_sw_stats {
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/atlantic/hw_atl/hw_atl_utils.c
index 13f02b9f99c5..4299b7016e2f 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.c
@@ -305,6 +305,10 @@  int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
 			AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
 							   HW_ATL_MIF_CMD)),
 				       1, 1000U);
+			if (err) {
+				err = -ETIMEDOUT;
+				goto err_exit;
+			}
 
 		*(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
 		a += 4;
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/atlantic/hw_atl/hw_atl_utils.h
index 5f3f70847310..f2a87826c0d1 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.h
@@ -8,6 +8,7 @@ 
 #ifndef HW_ATL_UTILS_H
 #define HW_ATL_UTILS_H
 
+#define BIT(x)  (1UL << (x))
 #define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); }
 
 /* Hardware tx descriptor */
@@ -389,18 +390,8 @@  enum hal_atl_utils_fw_state_e {
 #define HAL_ATLANTIC_UTILS_FW_MSG_OFFLOAD_DEL  10U
 #define HAL_ATLANTIC_UTILS_FW_MSG_CABLE_DIAG   13U // 0xd
 
-#define SMBUS_READ_REQUEST BIT(13)
-#define SMBUS_WRITE_REQUEST BIT(14)
 #define SMBUS_DEVICE_ID 0x50
 
-enum hw_atl_fw2x_rate {
-	FW2X_RATE_100M    = 0x20,
-	FW2X_RATE_1G      = 0x100,
-	FW2X_RATE_2G5     = 0x200,
-	FW2X_RATE_5G      = 0x400,
-	FW2X_RATE_10G     = 0x800,
-};
-
 enum hw_atl_fw2x_caps_lo {
 	CAPS_LO_10BASET_HD = 0x00,
 	CAPS_LO_10BASET_FD,
@@ -414,6 +405,10 @@  enum hw_atl_fw2x_caps_lo {
 	CAPS_LO_2P5GBASET_FD,
 	CAPS_LO_5GBASET_FD,
 	CAPS_LO_10GBASET_FD,
+	CAPS_LO_AUTONEG,
+	CAPS_LO_SMBUS_READ,
+	CAPS_LO_SMBUS_WRITE,
+	CAPS_LO_MACSEC
 };
 
 enum hw_atl_fw2x_caps_hi {
@@ -451,6 +446,14 @@  enum hw_atl_fw2x_caps_hi {
 	CAPS_HI_TRANSACTION_ID,
 };
 
+enum hw_atl_fw2x_rate {
+	FW2X_RATE_100M    = BIT(CAPS_LO_100BASETX_FD),
+	FW2X_RATE_1G      = BIT(CAPS_LO_1000BASET_FD),
+	FW2X_RATE_2G5     = BIT(CAPS_LO_2P5GBASET_FD),
+	FW2X_RATE_5G      = BIT(CAPS_LO_5GBASET_FD),
+	FW2X_RATE_10G     = BIT(CAPS_LO_10GBASET_FD),
+};
+
 struct aq_hw_s;
 struct aq_fw_ops;
 struct aq_hw_link_status_s;
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
index f90ccfe9e010..1d9190155421 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -129,7 +129,11 @@  static u32 fw2x_to_eee_mask(u32 speed)
 
 static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
 {
-	u32 val = link_speed_mask_2fw2x_ratemask(speed);
+	u32 rate_mask = link_speed_mask_2fw2x_ratemask(speed);
+	u32 reg_val = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
+	u32 val = rate_mask | ((BIT(CAPS_LO_SMBUS_READ) |
+				BIT(CAPS_LO_SMBUS_WRITE) |
+				BIT(CAPS_LO_MACSEC)) & reg_val);
 
 	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val);
 
@@ -484,7 +488,8 @@  static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)
 	return 0;
 }
 
-static int aq_fw2x_get_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
+static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
+			      u32 *data, u32 len, u32 offset)
 {
 	int err = 0;
 	struct smbus_read_request request;
@@ -494,8 +499,8 @@  static int aq_fw2x_get_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
 	if (self->fw_ver_actual < HW_ATL_FW_FEATURE_EEPROM)
 		return -EOPNOTSUPP;
 
-	request.device_id = SMBUS_DEVICE_ID;
-	request.address = 0;
+	request.device_id = dev_addr;
+	request.address = offset;
 	request.length = len;
 
 	/* Write SMBUS request to cfg memory */
@@ -506,16 +511,16 @@  static int aq_fw2x_get_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
 	if (err < 0)
 		return err;
 
-	/* Toggle 0x368.SMBUS_READ_REQUEST bit */
+	/* Toggle 0x368.CAPS_LO_SMBUS_READ bit */
 	mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
-	mpi_opts ^= SMBUS_READ_REQUEST;
+	mpi_opts ^= BIT(CAPS_LO_SMBUS_READ);
 
 	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);
 
 	/* Wait until REQUEST_BIT matched in 0x370 */
 
 	AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &
-		SMBUS_READ_REQUEST) == (mpi_opts & SMBUS_READ_REQUEST),
+		BIT(CAPS_LO_SMBUS_READ)) == (mpi_opts & BIT(CAPS_LO_SMBUS_READ)),
 		10U, 10000U);
 
 	if (err < 0)
@@ -542,7 +547,8 @@  static int aq_fw2x_get_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
 }
 
 
-static int aq_fw2x_set_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
+static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
+			      u32 *data, u32 len)
 {
 	struct smbus_write_request request;
 	u32 mpi_opts, result = 0;
@@ -551,7 +557,7 @@  static int aq_fw2x_set_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
 	if (self->fw_ver_actual < HW_ATL_FW_FEATURE_EEPROM)
 		return -EOPNOTSUPP;
 
-	request.device_id = SMBUS_DEVICE_ID;
+	request.device_id = dev_addr;
 	request.address = 0;
 	request.length = len;
 
@@ -572,15 +578,15 @@  static int aq_fw2x_set_eeprom(struct aq_hw_s *self, u32 *data, u32 len)
 	if (err < 0)
 		return err;
 
-	/* Toggle 0x368.SMBUS_WRITE_REQUEST bit */
+	/* Toggle 0x368.CAPS_LO_SMBUS_WRITE bit */
 	mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
-	mpi_opts ^= SMBUS_WRITE_REQUEST;
+	mpi_opts ^= BIT(CAPS_LO_SMBUS_WRITE);
 
 	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);
 
 	/* Wait until REQUEST_BIT matched in 0x370 */
 	AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &
-		SMBUS_WRITE_REQUEST) == (mpi_opts & SMBUS_WRITE_REQUEST),
+		BIT(CAPS_LO_SMBUS_WRITE)) == (mpi_opts & BIT(CAPS_LO_SMBUS_WRITE)),
 		10U, 10000U);
 
 	if (err < 0)