From 2f40244b39ba1f115e8e4b502ddc191a359492b9 Mon Sep 17 00:00:00 2001 From: Pavel Belous Date: Thu, 18 Apr 2019 11:39:55 +0000 Subject: [PATCH] net/atlantic: implement MACsec firmware interface Implementation of firmware interface for MACsec configuration. Structure with config data is written into FW memory, then we trigger FW to execute the request and wait for result. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh --- drivers/net/atlantic/atl_types.h | 2 + .../net/atlantic/hw_atl/hw_atl_utils_fw2x.c | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h index 3cc9e96089..dbaf2c635f 100644 --- a/drivers/net/atlantic/atl_types.h +++ b/drivers/net/atlantic/atl_types.h @@ -128,6 +128,8 @@ struct aq_hw_s { struct hw_atl_stats_s last_stats; struct aq_stats_s curr_stats; + u32 caps_lo; + u64 speed; unsigned int chip_features; u32 fw_ver_actual; 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 f215ceb704..89a3759b89 100644 --- a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c +++ b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c @@ -62,6 +62,7 @@ static int aq_fw2x_set_state(struct aq_hw_s *self, static int aq_fw2x_init(struct aq_hw_s *self) { int err = 0; + struct hw_aq_atl_utils_mbox mbox; /* check 10 times by 1ms */ AQ_HW_WAIT_FOR(0U != (self->mbox_addr = @@ -70,6 +71,12 @@ static int aq_fw2x_init(struct aq_hw_s *self) AQ_HW_WAIT_FOR(0U != (self->rpc_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)), 1000U, 100U); + + /* Read caps */ + hw_atl_utils_mpi_read_stats(self, &mbox); + + self->caps_lo = mbox.info.caps_lo; + return err; } @@ -623,6 +630,49 @@ static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr, return 0; } +static int aq_fw2x_send_macsec_request(struct aq_hw_s *self, + struct macsec_msg_fw_request *req, + struct macsec_msg_fw_response *response) +{ + int err = 0; + u32 mpi_opts = 0; + + if (!response || !response) + return 0; + + if ((self->caps_lo & BIT(CAPS_LO_MACSEC)) == 0) + return -EOPNOTSUPP; + + /* Write macsec request to cfg memory */ + err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, + (u32 *)(void *)req, + RTE_ALIGN(sizeof(*req) / sizeof(u32), sizeof(u32))); + + if (err < 0) + return err; + + /* Toggle 0x368.CAPS_LO_MACSEC bit */ + mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR); + mpi_opts ^= BIT(CAPS_LO_MACSEC); + + 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) & + BIT(CAPS_LO_MACSEC)) == (mpi_opts & BIT(CAPS_LO_MACSEC)), + 1000U, 10000U); + + if (err < 0) + return err; + + /* Read status of write operation */ + err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32), + (u32 *)(void *)response, + RTE_ALIGN(sizeof(*response) / sizeof(u32), sizeof(u32))); + + return err; +} + const struct aq_fw_ops aq_fw_2x_ops = { .init = aq_fw2x_init, .deinit = aq_fw2x_deinit, @@ -641,4 +691,5 @@ const struct aq_fw_ops aq_fw_2x_ops = { .led_control = aq_fw2x_led_control, .get_eeprom = aq_fw2x_get_eeprom, .set_eeprom = aq_fw2x_set_eeprom, + .send_macsec_req = aq_fw2x_send_macsec_request, }; -- 2.20.1