diff options
6 files changed, 294 insertions, 7 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/Makefile b/drivers/net/ethernet/aquantia/atlantic/Makefile index fa845c15d0e1..23f0e5b5fcdb 100644 --- a/drivers/net/ethernet/aquantia/atlantic/Makefile +++ b/drivers/net/ethernet/aquantia/atlantic/Makefile @@ -25,6 +25,7 @@ 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_fw.o \ hw_atl2/hw_atl2_llh.o \ macsec/macsec_api.o diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index e770d91e0876..03fea9469f01 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -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 { diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index 2edf137a7030..ce46cdbc69e6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -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" @@ -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), }, + {} }; @@ -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); @@ -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) @@ -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)) { @@ -245,19 +267,19 @@ 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; } @@ -265,7 +287,7 @@ static int aq_pci_probe(struct pci_dev *pdev, if (bar == 4) { err = -EIO; - goto err_free_aq_hw; + goto err_free_aq_hw_priv; } numvecs = min((u8)AQ_CFG_VECS_DEF, @@ -305,6 +327,8 @@ err_register: 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: @@ -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); diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c new file mode 100644 index 000000000000..58c74a73b6cf --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Atlantic Network Driver + * Copyright (C) 2020 Marvell International Ltd. + */ + +#include "aq_hw.h" +#include "hw_atl2_utils.h" +#include "hw_atl2_internal.h" + +#define DEFAULT_BOARD_BASIC_CAPABILITIES \ + .is_64_dma = true, \ + .msix_irqs = 8U, \ + .irq_mask = ~0U, \ + .vecs = HW_ATL2_RSS_MAX, \ + .tcs = HW_ATL2_TC_MAX, \ + .rxd_alignment = 1U, \ + .rxd_size = HW_ATL2_RXD_SIZE, \ + .rxds_max = HW_ATL2_MAX_RXD, \ + .rxds_min = HW_ATL2_MIN_RXD, \ + .txd_alignment = 1U, \ + .txd_size = HW_ATL2_TXD_SIZE, \ + .txds_max = HW_ATL2_MAX_TXD, \ + .txds_min = HW_ATL2_MIN_TXD, \ + .txhwb_alignment = 4096U, \ + .tx_rings = HW_ATL2_TX_RINGS, \ + .rx_rings = HW_ATL2_RX_RINGS, \ + .hw_features = NETIF_F_HW_CSUM | \ + NETIF_F_RXCSUM | \ + NETIF_F_RXHASH | \ + NETIF_F_SG | \ + NETIF_F_TSO | \ + NETIF_F_TSO6 | \ + NETIF_F_LRO | \ + NETIF_F_NTUPLE | \ + NETIF_F_HW_VLAN_CTAG_FILTER | \ + NETIF_F_HW_VLAN_CTAG_RX | \ + NETIF_F_HW_VLAN_CTAG_TX | \ + NETIF_F_GSO_UDP_L4 | \ + NETIF_F_GSO_PARTIAL, \ + .hw_priv_flags = IFF_UNICAST_FLT, \ + .flow_control = true, \ + .mtu = HW_ATL2_MTU_JUMBO, \ + .mac_regs_count = 72, \ + .hw_alive_check_addr = 0x10U, \ + .priv_data_len = sizeof(struct hw_atl2_priv) + +const struct aq_hw_caps_s hw_atl2_caps_aqc113 = { + DEFAULT_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = AQ_NIC_RATE_10G | + AQ_NIC_RATE_5G | + AQ_NIC_RATE_2GS | + AQ_NIC_RATE_1G | + AQ_NIC_RATE_100M | + AQ_NIC_RATE_10M, +}; + +static int hw_atl2_hw_reset(struct aq_hw_s *self) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_rss_hash_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_rss_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_offload_set(struct aq_hw_s *self, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_init(struct aq_hw_s *self, u8 *mac_addr) +{ + struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; + u8 base_index, count; + int err; + + err = hw_atl2_utils_get_action_resolve_table_caps(self, &base_index, + &count); + if (err) + return err; + + priv->art_base_index = 8 * base_index; + + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_tx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_rx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_start(struct aq_hw_s *self) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_tx_xmit(struct aq_hw_s *self, + struct aq_ring_s *ring, + unsigned int frags) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_rx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_tx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_rx_fill(struct aq_hw_s *self, struct aq_ring_s *ring, + unsigned int sw_tail_old) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_tx_head_update(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_rx_receive(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_irq_enable(struct aq_hw_s *self, u64 mask) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_irq_disable(struct aq_hw_s *self, u64 mask) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_irq_read(struct aq_hw_s *self, u64 *mask) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_interrupt_moderation_set(struct aq_hw_s *self) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_stop(struct aq_hw_s *self) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static int hw_atl2_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring) +{ + return -EOPNOTSUPP; +} + +static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self) +{ + return &self->curr_stats; +} + +const struct aq_hw_ops hw_atl2_ops = { + .hw_set_mac_address = hw_atl2_hw_mac_addr_set, + .hw_init = hw_atl2_hw_init, + .hw_reset = hw_atl2_hw_reset, + .hw_start = hw_atl2_hw_start, + .hw_ring_tx_start = hw_atl2_hw_ring_tx_start, + .hw_ring_tx_stop = hw_atl2_hw_ring_tx_stop, + .hw_ring_rx_start = hw_atl2_hw_ring_rx_start, + .hw_ring_rx_stop = hw_atl2_hw_ring_rx_stop, + .hw_stop = hw_atl2_hw_stop, + + .hw_ring_tx_xmit = hw_atl2_hw_ring_tx_xmit, + .hw_ring_tx_head_update = hw_atl2_hw_ring_tx_head_update, + + .hw_ring_rx_receive = hw_atl2_hw_ring_rx_receive, + .hw_ring_rx_fill = hw_atl2_hw_ring_rx_fill, + + .hw_irq_enable = hw_atl2_hw_irq_enable, + .hw_irq_disable = hw_atl2_hw_irq_disable, + .hw_irq_read = hw_atl2_hw_irq_read, + + .hw_ring_rx_init = hw_atl2_hw_ring_rx_init, + .hw_ring_tx_init = hw_atl2_hw_ring_tx_init, + .hw_interrupt_moderation_set = hw_atl2_hw_interrupt_moderation_set, + .hw_rss_set = hw_atl2_hw_rss_set, + .hw_rss_hash_set = hw_atl2_hw_rss_hash_set, + .hw_get_hw_stats = hw_atl2_utils_get_hw_stats, + .hw_set_offload = hw_atl2_hw_offload_set, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.h new file mode 100644 index 000000000000..de8723f1c28a --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Atlantic Network Driver + * Copyright (C) 2020 Marvell International Ltd. + */ + +#ifndef HW_ATL2_H +#define HW_ATL2_H + +#include "aq_common.h" + +extern const struct aq_hw_caps_s hw_atl2_caps_aqc113; +extern const struct aq_hw_ops hw_atl2_ops; + +#endif /* HW_ATL2_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h index 233db3222bb8..f82058484332 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h @@ -9,9 +9,29 @@ #include "hw_atl2_utils.h" #define HW_ATL2_MTU_JUMBO 16352U +#define HW_ATL2_MTU 1514U + +#define HW_ATL2_TX_RINGS 4U +#define HW_ATL2_RX_RINGS 4U + +#define HW_ATL2_RINGS_MAX 32U +#define HW_ATL2_TXD_SIZE (16U) +#define HW_ATL2_RXD_SIZE (16U) + +#define HW_ATL2_TC_MAX 1U +#define HW_ATL2_RSS_MAX 8U + +#define HW_ATL2_MIN_RXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE)) +#define HW_ATL2_MIN_TXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_TXD_MULTIPLE)) + +#define HW_ATL2_MAX_RXD 8184U +#define HW_ATL2_MAX_TXD 8184U struct hw_atl2_priv { struct statistics_s last_stats; + unsigned int art_base_index; }; #endif /* HW_ATL2_INTERNAL_H */ |