Skip to content

Commit

Permalink
Merge branch 'net-atlantic-A2-support'
Browse files Browse the repository at this point in the history
Igor Russkikh says:

====================
net: atlantic: A2 support

This patchset adds support for the new generation of Atlantic NICs.

Chip generations are mostly compatible register-wise, but there are still
some differences. Therefore we've made some of first generation (A1) code
non-static to re-use it where possible.

Some pieces are A2 specific, in which case we redefine/extend such APIs.

v2:
 * removed #pragma pack (2 structures require the packed attribute);
 * use defines instead of magic numbers where possible;

v1: https://patchwork.ozlabs.org/cover/1276220/
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 1, 2020
2 parents e00edb4 + 43c670c commit bf2320a
Show file tree
Hide file tree
Showing 23 changed files with 2,798 additions and 121 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ atlantic-objs := aq_main.o \
hw_atl/hw_atl_utils.o \
hw_atl/hw_atl_utils_fw2x.o \
hw_atl/hw_atl_llh.o \
hw_atl2/hw_atl2.o \
hw_atl2/hw_atl2_utils.o \
hw_atl2/hw_atl2_utils_fw.o \
hw_atl2/hw_atl2_llh.o \
macsec/macsec_api.o

atlantic-$(CONFIG_MACSEC) += aq_macsec.o
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@

#define AQ_CFG_LOCK_TRYS 100U

#define AQ_CFG_DRV_AUTHOR "aQuantia"
#define AQ_CFG_DRV_DESC "aQuantia Corporation(R) Network Driver"
#define AQ_CFG_DRV_AUTHOR "Marvell"
#define AQ_CFG_DRV_DESC "Marvell (Aquantia) Corporation(R) Network Driver"
#define AQ_CFG_DRV_NAME "atlantic"

#endif /* AQ_CFG_H */
33 changes: 21 additions & 12 deletions drivers/net/ethernet/aquantia/atlantic/aq_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,31 @@
#define AQ_DEVICE_ID_AQC111S 0x91B1
#define AQ_DEVICE_ID_AQC112S 0x92B1

#define HW_ATL_NIC_NAME "aQuantia AQtion 10Gbit Network Adapter"
#define AQ_DEVICE_ID_AQC113DEV 0x00C0
#define AQ_DEVICE_ID_AQC113CS 0x94C0
#define AQ_DEVICE_ID_AQC114CS 0x93C0
#define AQ_DEVICE_ID_AQC113 0x04C0
#define AQ_DEVICE_ID_AQC113C 0x14C0
#define AQ_DEVICE_ID_AQC115C 0x12C0

#define HW_ATL_NIC_NAME "Marvell (aQuantia) AQtion 10Gbit Network Adapter"

#define AQ_HWREV_ANY 0
#define AQ_HWREV_1 1
#define AQ_HWREV_2 2

#define AQ_NIC_RATE_10G BIT(0)
#define AQ_NIC_RATE_5G BIT(1)
#define AQ_NIC_RATE_5GSR BIT(2)
#define AQ_NIC_RATE_2GS BIT(3)
#define AQ_NIC_RATE_1G BIT(4)
#define AQ_NIC_RATE_100M BIT(5)

#define AQ_NIC_RATE_EEE_10G BIT(6)
#define AQ_NIC_RATE_EEE_5G BIT(7)
#define AQ_NIC_RATE_EEE_2GS BIT(8)
#define AQ_NIC_RATE_EEE_1G BIT(9)
#define AQ_NIC_RATE_10G BIT(0)
#define AQ_NIC_RATE_5G BIT(1)
#define AQ_NIC_RATE_5GSR BIT(2)
#define AQ_NIC_RATE_2GS BIT(3)
#define AQ_NIC_RATE_1G BIT(4)
#define AQ_NIC_RATE_100M BIT(5)
#define AQ_NIC_RATE_10M BIT(6)

#define AQ_NIC_RATE_EEE_10G BIT(7)
#define AQ_NIC_RATE_EEE_5G BIT(8)
#define AQ_NIC_RATE_EEE_2GS BIT(9)
#define AQ_NIC_RATE_EEE_1G BIT(10)
#define AQ_NIC_RATE_EEE_100M BIT(11)

#endif /* AQ_COMMON_H */
3 changes: 3 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@ static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
if (speed & AQ_NIC_RATE_EEE_1G)
rate |= SUPPORTED_1000baseT_Full;

if (speed & AQ_NIC_RATE_EEE_100M)
rate |= SUPPORTED_100baseT_Full;

return rate;
}

Expand Down
22 changes: 21 additions & 1 deletion drivers/net/ethernet/aquantia/atlantic/aq_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct aq_hw_caps_s {
u8 rx_rings;
bool flow_control;
bool is_64_dma;
u32 priv_data_len;
};

struct aq_hw_link_status_s {
Expand Down Expand Up @@ -136,6 +137,19 @@ enum aq_priv_flags {
BIT(AQ_HW_LOOPBACK_PHYINT_SYS) |\
BIT(AQ_HW_LOOPBACK_PHYEXT_SYS))

#define ATL_HW_CHIP_MIPS 0x00000001U
#define ATL_HW_CHIP_TPO2 0x00000002U
#define ATL_HW_CHIP_RPF2 0x00000004U
#define ATL_HW_CHIP_MPI_AQ 0x00000010U
#define ATL_HW_CHIP_ATLANTIC 0x00800000U
#define ATL_HW_CHIP_REVISION_A0 0x01000000U
#define ATL_HW_CHIP_REVISION_B0 0x02000000U
#define ATL_HW_CHIP_REVISION_B1 0x04000000U
#define ATL_HW_CHIP_ANTIGUA 0x08000000U

#define ATL_HW_IS_CHIP_FEATURE(_HW_, _F_) (!!(ATL_HW_CHIP_##_F_ & \
(_HW_)->chip_features))

struct aq_hw_s {
atomic_t flags;
u8 rbl_enabled:1;
Expand All @@ -159,6 +173,7 @@ struct aq_hw_s {
struct hw_atl_utils_fw_rpc rpc;
s64 ptp_clk_offset;
u16 phy_id;
void *priv;
};

struct aq_ring_s;
Expand All @@ -182,6 +197,11 @@ struct aq_hw_ops {

int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);

int (*hw_soft_reset)(struct aq_hw_s *self);

int (*hw_prepare)(struct aq_hw_s *self,
const struct aq_fw_ops **fw_ops);

int (*hw_reset)(struct aq_hw_s *self);

int (*hw_init)(struct aq_hw_s *self, u8 *mac_addr);
Expand Down Expand Up @@ -254,7 +274,7 @@ struct aq_hw_ops {

struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self);

int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
u32 (*hw_get_fw_version)(struct aq_hw_s *self);

int (*hw_set_offload)(struct aq_hw_s *self,
struct aq_nic_cfg_s *aq_nic_cfg);
Expand Down
43 changes: 36 additions & 7 deletions drivers/net/ethernet/aquantia/atlantic/aq_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,20 @@ static void aq_nic_polling_timer_cb(struct timer_list *t)
AQ_CFG_POLLING_TIMER_INTERVAL);
}

static int aq_nic_hw_prepare(struct aq_nic_s *self)
{
int err = 0;

err = self->aq_hw_ops->hw_soft_reset(self->aq_hw);
if (err)
goto exit;

err = self->aq_hw_ops->hw_prepare(self->aq_hw, &self->aq_fw_ops);

exit:
return err;
}

int aq_nic_ndev_register(struct aq_nic_s *self)
{
int err = 0;
Expand All @@ -266,7 +280,7 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
goto err_exit;
}

err = hw_atl_utils_initfw(self->aq_hw, &self->aq_fw_ops);
err = aq_nic_hw_prepare(self);
if (err)
goto err_exit;

Expand Down Expand Up @@ -364,7 +378,8 @@ int aq_nic_init(struct aq_nic_s *self)
if (err < 0)
goto err_exit;

if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) {
if (ATL_HW_IS_CHIP_FEATURE(self->aq_hw, ATLANTIC) &&
self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) {
self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX;
err = aq_phy_init(self->aq_hw);
}
Expand Down Expand Up @@ -764,6 +779,9 @@ int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p)
u32 *regs_buff = p;
int err = 0;

if (unlikely(!self->aq_hw_ops->hw_get_regs))
return -EOPNOTSUPP;

regs->version = 1;

err = self->aq_hw_ops->hw_get_regs(self->aq_hw,
Expand All @@ -778,6 +796,9 @@ int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p)

int aq_nic_get_regs_count(struct aq_nic_s *self)
{
if (unlikely(!self->aq_hw_ops->hw_get_regs))
return 0;

return self->aq_nic_cfg.aq_hw_caps->mac_regs_count;
}

Expand Down Expand Up @@ -885,6 +906,10 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, supported,
100baseT_Full);

if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10M)
ethtool_link_ksettings_add_link_mode(cmd, supported,
10baseT_Full);

if (self->aq_nic_cfg.aq_hw_caps->flow_control) {
ethtool_link_ksettings_add_link_mode(cmd, supported,
Pause);
Expand Down Expand Up @@ -924,6 +949,10 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, advertising,
100baseT_Full);

if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10M)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
10baseT_Full);

if (self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
Pause);
Expand Down Expand Up @@ -954,6 +983,10 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
speed = cmd->base.speed;

switch (speed) {
case SPEED_10:
rate = AQ_NIC_RATE_10M;
break;

case SPEED_100:
rate = AQ_NIC_RATE_100M;
break;
Expand Down Expand Up @@ -1006,11 +1039,7 @@ struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self)

u32 aq_nic_get_fw_version(struct aq_nic_s *self)
{
u32 fw_version = 0U;

self->aq_hw_ops->hw_get_fw_version(self->aq_hw, &fw_version);

return fw_version;
return self->aq_hw_ops->hw_get_fw_version(self->aq_hw);
}

int aq_nic_set_loopback(struct aq_nic_s *self)
Expand Down
39 changes: 32 additions & 7 deletions drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "aq_pci_func.h"
#include "hw_atl/hw_atl_a0.h"
#include "hw_atl/hw_atl_b0.h"
#include "hw_atl2/hw_atl2.h"
#include "aq_filters.h"
#include "aq_drvinfo.h"
#include "aq_macsec.h"
Expand All @@ -41,6 +42,13 @@ static const struct pci_device_id aq_pci_tbl[] = {
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC111S), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC112S), },

{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113DEV), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113CS), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC114CS), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC115C), },

{}
};

Expand Down Expand Up @@ -70,6 +78,13 @@ static const struct aq_board_revision_s hw_atl_boards[] = {
{ AQ_DEVICE_ID_AQC109S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109s, },
{ AQ_DEVICE_ID_AQC111S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc111s, },
{ AQ_DEVICE_ID_AQC112S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc112s, },

{ AQ_DEVICE_ID_AQC113DEV, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC113, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC113C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
};

MODULE_DEVICE_TABLE(pci, aq_pci_tbl);
Expand Down Expand Up @@ -104,10 +119,8 @@ int aq_pci_func_init(struct pci_dev *pdev)
int err;

err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err) {
if (!err)
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));

}
if (err) {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!err)
Expand Down Expand Up @@ -237,6 +250,15 @@ static int aq_pci_probe(struct pci_dev *pdev,
goto err_ioremap;
}
self->aq_hw->aq_nic_cfg = aq_nic_get_cfg(self);
if (self->aq_hw->aq_nic_cfg->aq_hw_caps->priv_data_len) {
int len = self->aq_hw->aq_nic_cfg->aq_hw_caps->priv_data_len;

self->aq_hw->priv = kzalloc(len, GFP_KERNEL);
if (!self->aq_hw->priv) {
err = -ENOMEM;
goto err_free_aq_hw;
}
}

for (bar = 0; bar < 4; ++bar) {
if (IORESOURCE_MEM & pci_resource_flags(pdev, bar)) {
Expand All @@ -245,27 +267,27 @@ static int aq_pci_probe(struct pci_dev *pdev,
mmio_pa = pci_resource_start(pdev, bar);
if (mmio_pa == 0U) {
err = -EIO;
goto err_free_aq_hw;
goto err_free_aq_hw_priv;
}

reg_sz = pci_resource_len(pdev, bar);
if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) {
err = -EIO;
goto err_free_aq_hw;
goto err_free_aq_hw_priv;
}

self->aq_hw->mmio = ioremap(mmio_pa, reg_sz);
if (!self->aq_hw->mmio) {
err = -EIO;
goto err_free_aq_hw;
goto err_free_aq_hw_priv;
}
break;
}
}

if (bar == 4) {
err = -EIO;
goto err_free_aq_hw;
goto err_free_aq_hw_priv;
}

numvecs = min((u8)AQ_CFG_VECS_DEF,
Expand Down Expand Up @@ -305,6 +327,8 @@ static int aq_pci_probe(struct pci_dev *pdev,
aq_pci_free_irq_vectors(self);
err_hwinit:
iounmap(self->aq_hw->mmio);
err_free_aq_hw_priv:
kfree(self->aq_hw->priv);
err_free_aq_hw:
kfree(self->aq_hw);
err_ioremap:
Expand Down Expand Up @@ -332,6 +356,7 @@ static void aq_pci_remove(struct pci_dev *pdev)
aq_nic_free_vectors(self);
aq_pci_free_irq_vectors(self);
iounmap(self->aq_hw->mmio);
kfree(self->aq_hw->priv);
kfree(self->aq_hw);
pci_release_regions(pdev);
free_netdev(self->ndev);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self)
hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U);

/* misc */
aq_hw_write_reg(self, 0x00007040U, IS_CHIP_FEATURE(TPO2) ?
aq_hw_write_reg(self, 0x00007040U, ATL_HW_IS_CHIP_FEATURE(self, TPO2) ?
0x00010000U : 0x00000000U);
hw_atl_tdm_tx_dca_en_set(self, 0U);
hw_atl_tdm_tx_dca_mode_set(self, 0U);
Expand Down Expand Up @@ -886,6 +886,8 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
}

const struct aq_hw_ops hw_atl_ops_a0 = {
.hw_soft_reset = hw_atl_utils_soft_reset,
.hw_prepare = hw_atl_utils_initfw,
.hw_set_mac_address = hw_atl_a0_hw_mac_addr_set,
.hw_init = hw_atl_a0_hw_init,
.hw_reset = hw_atl_a0_hw_reset,
Expand Down
Loading

0 comments on commit bf2320a

Please sign in to comment.