From f73061d53b5a234a898bac4221fe62258c1cd20b Mon Sep 17 00:00:00 2001 From: Pavel Belous Date: Tue, 12 Mar 2019 15:24:59 +0000 Subject: [PATCH] net/atlantic: use EEPROM magic as a device address 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 Signed-off-by: Pavel Belous --- 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(-) diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c index 5bc04f55cc..a510646a5f 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 3d90f6caef..3edaf0c7c0 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 13f02b9f99..4299b7016e 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 5f3f708473..f2a87826c0 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 f90ccfe9e0..1d91901554 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) -- 2.20.1