Skip to content

Commit

Permalink
net/atlantic: add FW mailbox guard mutex
Browse files Browse the repository at this point in the history
Driver uses the Firmware mailbox to read statistics and configure
some features.
This patch introduces a mutex to provide consistent access to the
FW mailbox to prevent potential data corruption.

Fixes: 86d3677 ("net/atlantic: implement firmware operations")
Cc: stable@dpdk.org

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
  • Loading branch information
Pavel Belous authored and Ferruh Yigit committed Oct 8, 2019
1 parent c133989 commit e992463
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 21 deletions.
4 changes: 4 additions & 0 deletions drivers/net/atlantic/atl_ethdev.c
Expand Up @@ -407,6 +407,8 @@ eth_atl_dev_init(struct rte_eth_dev *eth_dev)

hw->aq_nic_cfg = &adapter->hw_cfg;

pthread_mutex_init(&hw->mbox_mutex, NULL);

/* disable interrupt */
atl_disable_intr(hw);

Expand Down Expand Up @@ -471,6 +473,8 @@ eth_atl_dev_uninit(struct rte_eth_dev *eth_dev)
rte_free(eth_dev->data->mac_addrs);
eth_dev->data->mac_addrs = NULL;

pthread_mutex_destroy(&hw->mbox_mutex);

return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/atlantic/atl_types.h
Expand Up @@ -10,6 +10,7 @@
#include <string.h>
#include <stdbool.h>
#include <netinet/in.h>
#include <pthread.h>

typedef uint8_t u8;
typedef int8_t s8;
Expand Down Expand Up @@ -137,6 +138,8 @@ struct aq_hw_s {
u32 rpc_addr;
u32 rpc_tid;
struct hw_aq_atl_utils_fw_rpc rpc;

pthread_mutex_t mbox_mutex;
};

struct aq_fw_ops {
Expand Down
82 changes: 61 additions & 21 deletions drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
Expand Up @@ -6,6 +6,7 @@
*/

#include <rte_ether.h>
#include <pthread.h>
#include "../atl_hw_regs.h"

#include "../atl_types.h"
Expand Down Expand Up @@ -217,13 +218,15 @@ int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
u32 mac_addr[2] = { 0 };
u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR);

pthread_mutex_lock(&self->mbox_mutex);

if (efuse_addr != 0) {
err = hw_atl_utils_fw_downld_dwords(self,
efuse_addr + (40U * 4U),
mac_addr,
ARRAY_SIZE(mac_addr));
if (err)
return err;
goto exit;
mac_addr[0] = rte_constant_bswap32(mac_addr[0]);
mac_addr[1] = rte_constant_bswap32(mac_addr[1]);
}
Expand Down Expand Up @@ -252,6 +255,10 @@ int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
h >>= 8;
mac[0] = (u8)(0xFFU & h);
}

exit:
pthread_mutex_unlock(&self->mbox_mutex);

return err;
}

Expand All @@ -261,6 +268,9 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS);


pthread_mutex_lock(&self->mbox_mutex);

/* Toggle statistics bit for FW to update */
mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
Expand All @@ -271,9 +281,15 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
BIT(CAPS_HI_STATISTICS)),
1U, 10000U);
if (err)
return err;
goto exit;

err = hw_atl_utils_update_stats(self);

exit:
pthread_mutex_unlock(&self->mbox_mutex);

return err;

return hw_atl_utils_update_stats(self);
}

static int aq_fw2x_get_temp(struct aq_hw_s *self, int *temp)
Expand All @@ -283,6 +299,8 @@ static int aq_fw2x_get_temp(struct aq_hw_s *self, int *temp)
u32 temp_val = mpi_opts & BIT(CAPS_HI_TEMPERATURE);
u32 temp_res;

pthread_mutex_lock(&self->mbox_mutex);

/* Toggle statistics bit for FW to 0x36C.18 (CAPS_HI_TEMPERATURE) */
mpi_opts = mpi_opts ^ BIT(CAPS_HI_TEMPERATURE);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
Expand All @@ -298,6 +316,9 @@ static int aq_fw2x_get_temp(struct aq_hw_s *self, int *temp)
&temp_res,
sizeof(temp_res) / sizeof(u32));


pthread_mutex_unlock(&self->mbox_mutex);

if (err)
return err;

Expand Down Expand Up @@ -515,6 +536,8 @@ static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
if ((self->caps_lo & BIT(CAPS_LO_SMBUS_READ)) == 0)
return -EOPNOTSUPP;

pthread_mutex_lock(&self->mbox_mutex);

request.msg_id = 0;
request.device_id = dev_addr;
request.address = offset;
Expand All @@ -526,7 +549,7 @@ static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
sizeof(request) / sizeof(u32));

if (err < 0)
return err;
goto exit;

/* Toggle 0x368.CAPS_LO_SMBUS_READ bit */
mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
Expand All @@ -541,17 +564,19 @@ static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
10U, 10000U);

if (err < 0)
return err;
goto exit;

err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),
&result,
sizeof(result) / sizeof(u32));

if (err < 0)
return err;
goto exit;

if (result)
return -EIO;
if (result) {
err = -EIO;
goto exit;
}

if (num_dwords) {
err = hw_atl_utils_fw_downld_dwords(self,
Expand All @@ -560,7 +585,7 @@ static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
num_dwords);

if (err < 0)
return err;
goto exit;
}

if (bytes_remains) {
Expand All @@ -573,13 +598,16 @@ static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
1);

if (err < 0)
return err;
goto exit;

rte_memcpy((u8 *)data + len - bytes_remains,
&val, bytes_remains);
}

return 0;
exit:
pthread_mutex_unlock(&self->mbox_mutex);

return err;
}


Expand All @@ -598,13 +626,15 @@ static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
request.address = offset;
request.length = len;

pthread_mutex_lock(&self->mbox_mutex);

/* Write SMBUS request to cfg memory */
err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
(u32 *)(void *)&request,
sizeof(request) / sizeof(u32));

if (err < 0)
return err;
goto exit;

/* Write SMBUS data to cfg memory */
u32 num_dwords = len / sizeof(u32);
Expand All @@ -617,7 +647,7 @@ static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
num_dwords);

if (err < 0)
return err;
goto exit;
}

if (bytes_remains) {
Expand All @@ -633,7 +663,7 @@ static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
1);

if (err < 0)
return err;
goto exit;
}

/* Toggle 0x368.CAPS_LO_SMBUS_WRITE bit */
Expand All @@ -648,20 +678,25 @@ static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
10U, 10000U);

if (err < 0)
return err;
goto exit;

/* Read status of write operation */
err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),
&result,
sizeof(result) / sizeof(u32));

if (err < 0)
return err;
goto exit;

if (result)
return -EIO;
if (result) {
err = -EIO;
goto exit;
}

return 0;
exit:
pthread_mutex_unlock(&self->mbox_mutex);

return err;
}

static int aq_fw2x_send_macsec_request(struct aq_hw_s *self,
Expand All @@ -677,13 +712,15 @@ static int aq_fw2x_send_macsec_request(struct aq_hw_s *self,
if ((self->caps_lo & BIT(CAPS_LO_MACSEC)) == 0)
return -EOPNOTSUPP;

pthread_mutex_lock(&self->mbox_mutex);

/* 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;
goto exit;

/* Toggle 0x368.CAPS_LO_MACSEC bit */
mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
Expand All @@ -697,13 +734,16 @@ static int aq_fw2x_send_macsec_request(struct aq_hw_s *self,
1000U, 10000U);

if (err < 0)
return err;
goto exit;

/* 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)));

exit:
pthread_mutex_unlock(&self->mbox_mutex);

return err;
}

Expand Down

0 comments on commit e992463

Please sign in to comment.