]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[aqc1xx] Add support for Marvell AQtion Ethernet controller aqc1xx 1171/head
authorAnimesh Bhatt <animeshb@marvell.com>
Mon, 2 Sep 2024 12:45:54 +0000 (13:45 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 2 Sep 2024 12:45:54 +0000 (13:45 +0100)
This patch adds support for the AQtion Ethernet controller, enabling
iPXE to recognize and utilize the specific models (AQC114, AQC113, and
AQC107).

Tested-by: Animesh Bhatt <animeshb@marvell.com>
Signed-off-by: Animesh Bhatt <animeshb@marvell.com>
src/Makefile
src/drivers/net/marvell/aqc1xx.c [new file with mode: 0644]
src/drivers/net/marvell/aqc1xx.h [new file with mode: 0644]
src/drivers/net/marvell/atl2_hw.c [new file with mode: 0644]
src/drivers/net/marvell/atl2_hw.h [new file with mode: 0644]
src/drivers/net/marvell/atl_hw.c [new file with mode: 0644]
src/drivers/net/marvell/atl_hw.h [new file with mode: 0644]
src/include/ipxe/errfile.h

index bc82cc6fe082956a8e25ca1554d719f36542fd26..95719628f7f5d968a4857f2afec726ff4a825c1f 100644 (file)
@@ -77,6 +77,7 @@ SRCDIRS               += drivers/net/efi
 SRCDIRS                += drivers/net/tg3
 SRCDIRS                += drivers/net/bnxt
 SRCDIRS                += drivers/net/sfc
+SRCDIRS                += drivers/net/marvell
 SRCDIRS                += drivers/block
 SRCDIRS                += drivers/nvs
 SRCDIRS                += drivers/bitbash
diff --git a/src/drivers/net/marvell/aqc1xx.c b/src/drivers/net/marvell/aqc1xx.c
new file mode 100644 (file)
index 0000000..b108bf7
--- /dev/null
@@ -0,0 +1,629 @@
+/** @file
+ *
+ * Marvell AQtion family network card driver.
+ *
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+FILE_LICENCE ( BSD2 );
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <byteswap.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/ethernet.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/malloc.h>
+#include <ipxe/pci.h>
+#include <ipxe/profile.h>
+
+#include "aqc1xx.h"
+
+extern struct atl_hw_ops atl_hw;
+extern struct atl_hw_ops atl2_hw;
+
+/** @file
+*
+* Marvell AQC network card driver
+*
+*/
+
+static int atl_ring_alloc ( const struct atl_nic *nic, struct atl_ring *ring,
+                           uint32_t desc_size, uint32_t reg_base ) {
+       physaddr_t phy_addr;
+
+       /* Allocate ring buffer.*/
+       ring->length = ATL_RING_SIZE * desc_size;
+       ring->ring = dma_alloc ( nic->dma, &ring->map, ring->length,
+                               ring->length );
+
+       if ( !ring->ring )
+               return -ENOMEM;
+
+       /* Initialize the descriptor ring */
+       memset ( ring->ring, 0, ring->length );
+
+       /* Program ring address */
+       phy_addr = dma ( &ring->map, ring->ring );
+
+       /* Write ring address (hi & low parts).*/
+       ATL_WRITE_REG ( ( uint32_t )phy_addr, reg_base );
+       ATL_WRITE_REG ( ( uint32_t ) ( ( ( uint64_t )phy_addr ) >> 32 ), reg_base + 4 );
+
+       /* Write ring length.*/
+       ATL_WRITE_REG ( ATL_RING_SIZE, reg_base + 8 );
+
+       ring->sw_head = ring->sw_tail = 0;
+
+       DBGC ( nic, "AQUANTIA: %p ring is at [%08llx,%08llx), reg base %#x\n",
+           nic, ( ( unsigned long long )phy_addr ),
+           ( ( unsigned long long ) phy_addr + ring->length ), reg_base );
+
+       return 0;
+}
+
+static void atl_ring_free ( struct atl_ring *ring ) {
+       dma_free ( &ring->map, ring->ring, ring->length );
+       ring->ring = NULL;
+       ring->length = 0;
+}
+
+static void atl_ring_next_dx ( unsigned int *val ) {
+       ++( *val );
+       if ( *val == ATL_RING_SIZE )
+               *val = 0;
+}
+
+int atl_ring_full ( const struct atl_ring *ring ) {
+       unsigned int tail = ring->sw_tail;
+       atl_ring_next_dx ( &tail );
+       return tail == ring->sw_head;
+}
+
+void atl_rx_ring_fill ( struct atl_nic *nic ) {
+       struct atl_desc_rx *rx;
+       struct io_buffer *iobuf;
+       physaddr_t address;
+       unsigned int refilled = 0;
+
+       /* Refill ring */
+       while ( !atl_ring_full ( &nic->rx_ring ) ) {
+
+               /* Allocate I/O buffer */
+               iobuf = alloc_rx_iob ( ATL_RX_MAX_LEN, nic->dma );
+               if ( !iobuf ) {
+                       /* Wait for next refill */
+                       break;
+               }
+
+               /* Get next receive descriptor */
+               rx = ( struct atl_desc_rx * )nic->rx_ring.ring +
+                       nic->rx_ring.sw_tail;
+
+               /* Populate receive descriptor */
+               address = iob_dma ( iobuf );
+               rx->data_addr = address;
+               rx->hdr_addr = 0;
+
+               /* Record I/O buffer */
+               assert ( nic->iobufs[nic->rx_ring.sw_tail] == NULL );
+               nic->iobufs[nic->rx_ring.sw_tail] = iobuf;
+
+               DBGC( nic, "AQUANTIA: RX[%d] is [%llx,%llx)\n",
+                       nic->rx_ring.sw_tail,
+                       ( ( unsigned long long )address ),
+                       ( ( unsigned long long )address + ATL_RX_MAX_LEN ) );
+
+               atl_ring_next_dx ( &nic->rx_ring.sw_tail );
+               refilled++;
+       }
+
+       /* Push descriptors to card, if applicable */
+       if ( refilled ) {
+               wmb();
+               ATL_WRITE_REG ( nic->rx_ring.sw_tail, ATL_RING_TAIL_PTR );
+       }
+}
+
+/**
+* Open network device
+*
+* @v netdev            Network device
+* @ret rc              Return status code
+*/
+static int atl_open ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+       uint32_t ctrl = 0;
+
+       /* Tx ring */
+       if ( atl_ring_alloc ( nic, &nic->tx_ring, sizeof ( struct atl_desc_tx ),
+                               ATL_TX_DMA_DESC_ADDR ) != 0 )
+               goto err_tx_alloc;
+
+       /* Rx ring */
+       if ( atl_ring_alloc ( nic, &nic->rx_ring, sizeof ( struct atl_desc_rx ),
+                               ATL_RX_DMA_DESC_ADDR ) != 0 )
+               goto err_rx_alloc;
+
+       /* Allocate interrupt vectors */
+       ATL_WRITE_REG ( ( ATL_IRQ_CTRL_COR_EN | ATL_IRQ_CTRL_REG_RST_DIS ),
+                     ATL_IRQ_CTRL );
+
+       /*TX & RX Interruprt Mapping*/
+       ctrl = ATL_IRQ_MAP_REG1_RX0 | ATL_IRQ_MAP_REG1_RX0_EN |
+                  ATL_IRQ_MAP_REG1_TX0 | ATL_IRQ_MAP_REG1_TX0_EN;
+       ATL_WRITE_REG ( ctrl, ATL_IRQ_MAP_REG1 );
+
+       /*TX interrupt ctrl reg*/
+       ATL_WRITE_REG ( ATL_TX_IRQ_CTRL_WB_EN, ATL_TX_IRQ_CTRL );
+
+       /*RX interrupt ctrl reg*/
+       ATL_WRITE_REG ( ATL_RX_IRQ_CTRL_WB_EN, ATL_RX_IRQ_CTRL );
+
+       /*RX data path*/
+       ctrl = ATL_IRQ_TX | ATL_IRQ_RX;
+       /* itr mask */
+       ATL_WRITE_REG ( ctrl,  ATL_ITR_MSKS );
+       ATL_WRITE_REG ( ( uint32_t )ATL_RX_MAX_LEN / 1024U,
+                     ATL_RX_DMA_DESC_BUF_SIZE );
+
+       /*filter global ctrl */
+       ctrl = ATL_RPF_CTRL1_BRC_EN | ATL_RPF_CTRL1_L2_PROMISC |
+               ATL_RPF_CTRL1_ACTION | ATL_RPF_CTRL1_BRC_TSH;
+       ATL_WRITE_REG ( ctrl, ATL_RPF_CTRL1 );
+
+       /* vlan promisc */
+       ATL_WRITE_REG ( ATL_RPF_CTRL2_VLAN_PROMISC, ATL_RPF_CTRL2 );
+       /* enable rpf2 */
+       ATL_WRITE_REG ( ATL_RPF2_CTRL_EN, ATL_RPF2_CTRL );
+
+       /* RX Packet Buffer 0 Register 1 */
+       ATL_WRITE_REG ( ATL_RPB0_CTRL1_SIZE, ATL_RPB0_CTRL1 );
+
+       /*RX Packet Buffer 0 Register 2 */
+       ctrl = ATL_RPB0_CTRL2_LOW_TSH | ATL_RPB0_CTRL2_HIGH_TSH |
+               ATL_RPB0_CTRL2_FC_EN;
+       ATL_WRITE_REG ( ctrl, ATL_RPB0_CTRL2 );
+
+       /*RPB global ctrl*/
+       ctrl = ATL_READ_REG ( ATL_RPB_CTRL );
+       ctrl |= ( ATL_RPB_CTRL_EN | ATL_RPB_CTRL_FC );
+       ATL_WRITE_REG ( ctrl, ATL_RPB_CTRL );
+
+       /*TX data path*/
+       /* enable tpo2 */
+       ATL_WRITE_REG ( ATL_TPO2_EN, ATL_TPO2_CTRL );
+       /* tpb global ctrl *** */
+       ATL_WRITE_REG ( ATL_TPB0_CTRL1_SIZE, ATL_TPB0_CTRL1 );
+
+       ctrl = ATL_TPB0_CTRL2_LOW_TSH | ATL_TPB0_CTRL2_HIGH_TSH;
+       /* tpb global ctrl *** */
+       ATL_WRITE_REG ( ctrl, ATL_TPB0_CTRL2 );
+
+       ctrl = ATL_READ_REG ( ATL_TPB_CTRL );
+       ctrl |= ( ATL_TPB_CTRL_EN | ATL_TPB_CTRL_PAD_EN );
+       /* tpb global ctrl */
+       ATL_WRITE_REG ( ctrl, ATL_TPB_CTRL );
+
+       /*Enable rings*/
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RING_TX_CTRL ) | ATL_RING_TX_CTRL_EN,
+                     ATL_RING_TX_CTRL );
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RING_RX_CTRL ) | ATL_RING_RX_CTRL_EN,
+                     ATL_RING_RX_CTRL );
+
+       if ( nic->flags == ATL_FLAG_A2 ) {
+               ATL_WRITE_REG ( ATL2_RPF_NEW_EN_ADR_EN, ATL2_RPF_NEW_EN_ADR );
+       }
+
+       atl_rx_ring_fill ( nic );
+
+       nic->hw_ops->start ( nic );
+
+       return 0;
+
+err_rx_alloc:
+       atl_ring_free ( &nic->tx_ring );
+
+err_tx_alloc:
+       return -ENOMEM;
+}
+
+/**
+* Close network device
+*
+* @v netdev            Network device
+*/
+static void atl_close ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+
+       nic->hw_ops->stop ( nic );
+       /* rpb global ctrl */
+       ATL_WRITE_REG ( ATL_RPB_CTRL_DIS, ATL_RPB_CTRL );
+       /* tgb global ctrl */
+       ATL_WRITE_REG ( ATL_TPB_CTRL_DIS, ATL_TPB_CTRL);
+
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RING_TX_CTRL ) | ( ~ATL_RING_TX_CTRL_EN ),
+                       ATL_RING_TX_CTRL );
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RING_RX_CTRL ) | ( ~ATL_RING_RX_CTRL_EN ),
+                       ATL_RING_RX_CTRL );
+
+       /* clear itr mask */
+       ATL_WRITE_REG ( ATL_ITR_MSKS_DIS, ATL_ITR_MSKS );
+
+       /* Reset the NIC */
+       nic->hw_ops->reset ( nic );
+
+       atl_ring_free ( &nic->tx_ring );
+       atl_ring_free ( &nic->rx_ring );
+}
+
+/**
+* Transmit packet
+*
+* @v netdev            Network device
+* @v iobuf             I/O buffer
+* @ret rc              Return status code
+*/
+int atl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
+       struct atl_nic *nic = netdev->priv;
+       struct atl_desc_tx *tx;
+       physaddr_t address;
+       uint32_t len;
+
+       /* Get next transmit descriptor */
+       if ( atl_ring_full ( &nic->tx_ring ) ) {
+               DBGC ( nic, "AQUANTIA: %p out of transmit descriptors\n", nic );
+               return -ENOBUFS;
+       }
+
+       tx = ( struct atl_desc_tx * )nic->tx_ring.ring + nic->tx_ring.sw_tail;
+
+       /* Populate transmit descriptor */
+       memset ( tx, 0, sizeof ( *tx ) );
+       address = iob_dma ( iobuf );
+       tx->address = address;
+       len = iob_len ( iobuf );
+
+       tx->status = 0x1;
+       tx->status = ( (tx->status) & ~ATL_DESC_TX_BUF_LEN_MASK) |
+                       ( (len << ATL_DESC_TX_BUF_LEN_OFFSET) &
+                       ATL_DESC_TX_BUF_LEN_MASK );
+       tx->status = ((tx->status) & ~ATL_DESC_TX_EOP_MASK) |
+                       ( (ATL_DESC_TX_DX_EOP_VALUE << ATL_DESC_TX_EOP_OFFSET) &
+                       ATL_DESC_TX_EOP_MASK );
+       tx->status = ( (tx->status) & ~ATL_DESC_TX_CMD_MASK) |
+                       ( (ATL_DESC_TX_CMD_VALUE << ATL_DESC_TX_CMD_OFFSET) &
+                       ATL_DESC_TX_CMD_MASK );
+       tx->flag = ( (tx->flag) & ~ATL_DESC_TX_PAY_LEN_MASK) |
+                       ( (len << ATL_DESC_TX_PAY_LEN_OFFSET) &
+                       ATL_DESC_TX_PAY_LEN_MASK );
+       wmb();
+
+       DBGC2 ( nic, "AQUANTIA: %p TX[%d] is [%llx, %llx]\n",
+               nic, nic->tx_ring.sw_tail,
+           ( ( unsigned long long ) address ),
+           ( ( unsigned long long ) address + len ) );
+
+       atl_ring_next_dx ( &nic->tx_ring.sw_tail );
+       ATL_WRITE_REG ( nic->tx_ring.sw_tail, ATL_RING_TAIL );
+
+       return 0;
+}
+
+void atl_check_link ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+       uint32_t link_state;
+
+       /* Read link status */
+       link_state = nic->hw_ops->get_link ( nic );
+
+       DBGC ( nic, "AQUANTIA: %p link status is %08x\n", nic, link_state );
+
+       if ( link_state != nic->link_state ) {
+               if ( link_state ) {
+                       DBGC ( nic, "AQUANTIA: link up\n");
+                       netdev_link_up ( netdev );
+               } else {
+                       DBGC ( nic, "AQUANTIA: link lost\n");
+                       netdev_link_down ( netdev );
+               }
+               nic->link_state = link_state;
+       }
+}
+
+/**
+* Poll for completed packets
+*
+* @v netdev            Network device
+*/
+void atl_poll_tx ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+       struct atl_desc_tx_wb *tx;
+
+       /* Check for completed packets */
+       while ( nic->tx_ring.sw_head != nic->tx_ring.sw_tail ) {
+
+               /* Get next transmit descriptor */
+               tx = ( struct atl_desc_tx_wb * )nic->tx_ring.ring +
+               nic->tx_ring.sw_head;
+
+               /* Stop if descriptor is still in use */
+               if ( !( tx->status & cpu_to_le32 ( ATL_TX_DESC_STATUS_DD ) ) )
+                       return;
+
+               DBGC2 ( nic, "AQUANTIA: %p TX[%d] complete\n",
+                       nic, nic->tx_ring.sw_head );
+
+               /* Complete TX descriptor */
+               atl_ring_next_dx ( &nic->tx_ring.sw_head );
+               netdev_tx_complete_next ( netdev );
+       }
+}
+
+/**
+* Poll for received packets
+*
+* @v netdev            Network device
+*/
+void atl_poll_rx ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+       struct atl_desc_rx_wb *rx;
+       struct io_buffer *iobuf;
+       size_t len;
+
+       /* Check for received packets */
+       while ( nic->rx_ring.sw_head != nic->rx_ring.sw_tail ) {
+
+               /* Get next receive descriptor */
+               rx = ( struct atl_desc_rx_wb * )nic->rx_ring.ring +
+               nic->rx_ring.sw_head;
+
+               /* Stop if descriptor is still in use */
+               if ( !( rx->status & cpu_to_le16( ATL_RX_DESC_STATUS_DD ) ) )
+                       return;
+
+               /* Populate I/O buffer */
+               iobuf = nic->iobufs[nic->rx_ring.sw_head];
+               nic->iobufs[nic->rx_ring.sw_head] = NULL;
+               len = le16_to_cpu ( rx->pkt_len );
+               iob_put ( iobuf, len );
+
+               /* Hand off to network stack */
+               DBGC ( nic, "AQUANTIA: %p RX[%d] complete (length %zd)\n",
+                   nic, nic->rx_ring.sw_head, len );
+
+               netdev_rx ( netdev, iobuf );
+
+               atl_ring_next_dx ( &nic->rx_ring.sw_head );
+       }
+}
+
+/**
+* Poll for completed and received packets
+*
+* @v netdev            Network device
+*/
+static void atl_poll ( struct net_device *netdev ) {
+       struct atl_nic *nic = netdev->priv;
+
+       /* Check link state */
+       atl_check_link ( netdev );
+
+       /* Poll for TX completions */
+       atl_poll_tx ( netdev );
+
+       /* Poll for RX completions */
+       atl_poll_rx ( netdev );
+
+       /* Refill RX ring */
+       atl_rx_ring_fill ( nic );
+}
+
+/**
+* Enable or disable interrupts
+*
+* @v netdev            Network device
+* @v enable            Interrupts should be enabled
+*/
+static void atl_irq ( struct net_device *netdev, int enable ) {
+       struct atl_nic *nic = netdev->priv;
+       uint32_t mask;
+
+       mask = ( ATL_IRQ_TX | ATL_IRQ_RX );
+       if ( enable )
+               ATL_WRITE_REG ( mask, ATL_ITR_MSKS );
+       else
+               ATL_WRITE_REG ( mask, ATL_ITR_MSKC );
+}
+
+/** Marvell network device operations */
+static struct net_device_operations atl_operations = {
+       .open = atl_open,
+       .close = atl_close,
+       .transmit = atl_transmit,
+       .poll = atl_poll,
+       .irq = atl_irq,
+};
+
+/******************************************************************************
+*
+* PCI interface
+*
+*******************************************************************************
+*/
+
+/**
+* Probe PCI device
+*
+* @v pci               PCI device
+* @ret rc              Return status code
+*/
+static int atl_probe ( struct pci_device *pci ) {
+       struct net_device *netdev;
+       struct atl_nic *nic;
+       int rc = ENOERR;
+       uint32_t io_size = 0;
+
+       /* Allocate and initialise net device */
+       netdev = alloc_etherdev ( sizeof( *nic ) );
+       if ( !netdev ) {
+               rc = -ENOMEM;
+               goto err_alloc;
+       }
+       netdev_init ( netdev, &atl_operations );
+       nic = netdev->priv;
+       pci_set_drvdata ( pci, netdev );
+       netdev->dev = &pci->dev;
+       memset( nic, 0, sizeof ( *nic ) );
+       nic->flags = pci->id->driver_data;
+
+       /* Fix up PCI device */
+       adjust_pci_device ( pci );
+
+       switch ( nic->flags ) {
+               case ATL_FLAG_A1:
+                       nic->hw_ops = &atl_hw;
+                       io_size = ATL_BAR_SIZE;
+                       break;
+               case ATL_FLAG_A2:
+                       nic->hw_ops = &atl2_hw;
+                       io_size = ATL2_BAR_SIZE;
+                       break;
+               default:
+                       goto err_unsupported;
+                       break;
+       }
+
+       /* Map registers */
+       nic->regs = pci_ioremap ( pci, pci->membase, io_size );
+       if ( !nic->regs ) {
+               rc = -ENODEV;
+               goto err_ioremap;
+       }
+
+        /* Configure DMA */
+       nic->dma = &pci->dma;
+
+       /* Reset the NIC */
+       if ( ( rc = nic->hw_ops->reset ( nic ) ) != 0 )
+               goto err_reset;
+
+       /* Get MAC Address */
+       if ( ( rc = nic->hw_ops->get_mac ( nic, netdev->hw_addr ) ) != 0 )
+               goto err_mac;
+
+       /* Register network device */
+       if ( ( rc = register_netdev ( netdev ) ) != 0 )
+               goto err_register_netdev;
+
+       /* Set initial link state */
+       netdev_link_down ( netdev );
+
+       return 0;
+
+err_register_netdev:
+err_mac:
+       nic->hw_ops->reset ( nic );
+err_reset:
+       iounmap ( nic->regs );
+err_ioremap:
+       netdev_nullify ( netdev );
+       netdev_put ( netdev );
+err_unsupported:
+err_alloc:
+       return rc;
+}
+
+/**
+* Remove PCI device
+*
+* @v pci               PCI device
+*/
+static void atl_remove ( struct pci_device *pci ) {
+       struct net_device *netdev = pci_get_drvdata ( pci );
+       struct atl_nic *nic = netdev->priv;
+
+       /* Unregister network device */
+       unregister_netdev ( netdev );
+
+       /* Reset the NIC */
+       nic->hw_ops->reset ( nic );
+
+       /* Free network device */
+       iounmap ( nic->regs );
+       netdev_nullify ( netdev );
+       netdev_put ( netdev );
+}
+
+/** Marvell PCI device IDs */
+static struct pci_device_id atl_nics[] = {
+       /* Atlantic 1 */
+       /* 10G */
+       PCI_ROM ( 0x1D6A, 0x0001, "AQC07", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0xD107, "AQC07", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x07B1, "AQC07", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x87B1, "AQC07", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A1 ),
+
+       /* SFP */
+       PCI_ROM ( 0x1D6A, 0xD100, "AQC00", "Felicity Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x00B1, "AQC00", "Felicity Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x80B1, "AQC00", "Felicity Network Adapter", ATL_FLAG_A1 ),
+
+       /* 5G */
+       PCI_ROM ( 0x1D6A, 0xD108, "AQC08", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x08B1, "AQC08", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x88B1, "AQC08", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x11B1, "AQC11", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x91B1, "AQC11", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A1 ),
+
+       /* 2.5G */
+       PCI_ROM ( 0x1D6A, 0xD109, "AQC09", "Marvell AQtion 2.5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x09B1, "AQC09", "Marvell AQtion 2.5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x89B1, "AQC09", "Marvell AQtion 2.5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x12B1, "AQC12", "Marvell AQtion 2.5Gbit Network Adapter", ATL_FLAG_A1 ),
+       PCI_ROM ( 0x1D6A, 0x92B1, "AQC12", "Marvell AQtion 2.5Gbit Network Adapter", ATL_FLAG_A1 ),
+
+       /* Atlantic 2 */
+       PCI_ROM ( 0x1D6A, 0x00C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x94C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x93C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x04C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x14C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x12C0, "AQC13", "Marvell AQtion 10Gbit Network Adapter", ATL_FLAG_A2 ),
+       PCI_ROM ( 0x1D6A, 0x03C0, "AQC14", "Marvell AQtion 5Gbit Network Adapter", ATL_FLAG_A2 ),
+};
+
+/** Marvell PCI driver */
+struct pci_driver atl_driver __pci_driver = {
+       .ids = atl_nics,
+       .id_count = ( sizeof( atl_nics ) / sizeof ( atl_nics[0] ) ),
+       .probe = atl_probe,
+       .remove = atl_remove,
+};
diff --git a/src/drivers/net/marvell/aqc1xx.h b/src/drivers/net/marvell/aqc1xx.h
new file mode 100644 (file)
index 0000000..26bdd00
--- /dev/null
@@ -0,0 +1,270 @@
+/** @file
+ *
+ * Marvell AQtion family network card driver definitions.
+ *
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _ATLANTIC_H
+#define _ATLANTIC_H
+
+FILE_LICENCE ( BSD2 );
+
+#include <stdint.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/nvs.h>
+
+#define ATL_BAR_SIZE   0x10000
+#define ATL2_BAR_SIZE   0x40000
+#define ATL_RING_SIZE  64
+#define ATL_RING_ALIGN 128
+#define ATL_RX_MAX_LEN 2048
+
+#define ATL_IRQ_TX   0x00000001U
+#define ATL_IRQ_RX   0x00000002U
+
+/*IRQ Status Register*/
+#define ATL_IRQ_STAT_REG 0x00002000U
+
+/* Interrupt Vector Allocation Register */
+#define ATL_IRQ_CTRL                    0x00002300U
+#define ATL_IRQ_CTRL_COR_EN      0x00000080U /*IRQ clear on read */
+#define ATL_IRQ_CTRL_REG_RST_DIS 0x20000000U /*Register reset disable */
+
+/*TX/RX Interruprt Mapping*/
+#define ATL_IRQ_MAP_REG1               0x00002100U /*IRQ mapping register */
+
+#define ATL_IRQ_MAP_REG1_RX0_EN 0x00008000U /*IRQ RX0 enable*/
+#define ATL_IRQ_MAP_REG1_RX0   0x00000100U /*IRQ RX0*/
+
+#define ATL_IRQ_MAP_REG1_TX0_EN 0x80000000U /*IRQ TX0 enable*/
+#define ATL_IRQ_MAP_REG1_TX0   0x00000000U /*IRQ TX0*/
+
+/*TX interrupt ctrl reg*/
+#define ATL_TX_IRQ_CTRL           0x00007B40U
+#define ATL_TX_IRQ_CTRL_WB_EN 0x00000002U
+
+/*RX interrupt ctrl reg*/
+#define ATL_RX_IRQ_CTRL           0x00005A30U
+#define ATL_RX_IRQ_CTRL_WB_EN 0x00000004U
+
+#define ATL_GLB_CTRL  0x00000000U
+
+#define ATL_PCI_CTRL            0x00001000U
+#define ATL_PCI_CTRL_RST_DIS 0x20000000U
+
+#define ATL_RX_CTRL             0x00005000U
+#define ATL_RX_CTRL_RST_DIS 0x20000000U /*RPB reset disable */
+#define ATL_TX_CTRL             0x00007000U
+#define ATL_TX_CTRL_RST_DIS 0x20000000U /*TPB reset disable */
+
+/*RX data path control registers*/
+#define ATL_RPF2_CTRL  0x00005040U
+#define ATL_RPF2_CTRL_EN 0x000F0000U /* RPF2 enable*/
+#define ATL2_RPF_NEW_EN_ADR_EN   0x00000001U /*enable*/
+#define ATL2_RPF_NEW_EN_ADR 0x5104
+
+#define ATL_RPF_CTRL1          0x00005100U
+#define ATL_RPF_CTRL1_BRC_EN    0x00000001U /*Allow broadcast receive*/
+#define ATL_RPF_CTRL1_L2_PROMISC 0x00000008U /*L2 promiscious*/
+#define ATL_RPF_CTRL1_ACTION    0x00001000U /*Action to host*/
+#define ATL_RPF_CTRL1_BRC_TSH  0x00010000U /*Brc threshold 256 units per sec*/
+
+#define ATL_RPF_CTRL2          0x00005280U
+#define ATL_RPF_CTRL2_VLAN_PROMISC 0x00000002U /*VLAN promisc*/
+
+#define ATL_RPB_CTRL_DIS      0x0
+#define ATL_RPB_CTRL            0x00005700U
+#define ATL_RPB_CTRL_EN          0x00000001U /*RPB Enable*/
+#define ATL_RPB_CTRL_FC          0x00000010U /*RPB Enable*/
+#define ATL_RPB_CTRL_TC_MODE 0x00000100U /*RPB Traffic Class Mode*/
+
+#define ATL_RPB0_CTRL1   0x00005710U
+#define ATL_RPB0_CTRL1_SIZE 0x00000140U /*RPB size (in unit 1KB) \*/
+
+#define ATL_RPB0_CTRL2         0x00005714U
+
+/*Buffer Low Threshold (70% of RPB size in unit 32B)*/
+#define ATL_RPB0_CTRL2_LOW_TSH  0x00000C00U
+/*Buffer High Threshold(30% of RPB size in unit 32B)*/
+#define ATL_RPB0_CTRL2_HIGH_TSH 0x1C000000U
+#define ATL_RPB0_CTRL2_FC_EN   0x80000000U /*Flow control Enable*/
+
+#define ATL_RX_DMA_DESC_BUF_SIZE 0x00005b18U
+#define ATL_RX_DMA_DESC_ADDR 0x00005b00U
+
+/*TX data path  control registers*/
+#define ATL_TPO2_CTRL 0x00007040U
+#define ATL_TPO2_EN   0x00010000U /*TPO2 Enable*/
+
+#define ATL_TPB_CTRL_DIS      0x0
+#define ATL_TPB_CTRL            0x00007900U
+#define ATL_TPB_CTRL_EN          0x00000001U /*TPB enable*/
+#define ATL_TPB_CTRL_PAD_EN  0x00000004U /*Tx pad insert enable*/
+#define ATL_TPB_CTRL_TC_MODE 0x00000100U /*Tx traffic Class Mode*/
+
+#define ATL_TPB0_CTRL1   0x00007910U
+#define ATL_TPB0_CTRL1_SIZE 0x000000A0U /*TPB Size (in unit 1KB)*/
+
+#define ATL_TPB0_CTRL2           0x00007914U
+/*Buffer Low  Threshold(30% of RPB size in unit 32B)*/
+#define ATL_TPB0_CTRL2_LOW_TSH  0x00000600U
+/*Buffer High  Threshold(30% of RPB size in unit 32B)*/
+#define ATL_TPB0_CTRL2_HIGH_TSH 0x0E000000U
+
+#define ATL_TX_DMA_DESC_ADDR 0x00007c00U
+
+/*Rings control registers*/
+#define ATL_RING_TX_CTRL       0x00007c08U
+#define ATL_RING_TX_CTRL_EN 0x80000000U /*Tx descriptor Enable*/
+
+#define ATL_RING_RX_CTRL       0x00005b08U
+#define ATL_RING_RX_CTRL_EN 0x80000000U /*Rx descriptor Enable*/
+
+#define ATL_RING_TAIL   0x00007c10U
+#define ATL_RING_TAIL_PTR 0x00005b10U
+
+/*IRQ control registers*/
+#define ATL_ITR_MSKS_DIS      0x0
+#define ATL_ITR_MSKS    0x00002060U
+#define ATL_ITR_MSKS_LSW 0x0000000CU
+#define ATL_ITR_MSKC    0x00002070U
+#define ATL_ITR_MSKC_LSW 0x0000000CU
+
+/*Link advertising*/
+#define ATL_LINK_ADV              0x00000368U
+#define ATL_SHUT_LINK      0x0
+#define ATL_LINK_ADV_AUTONEG   0xF20U
+
+#define ATL_LINK_ST     0x00000370U
+
+/*Semaphores*/
+#define ATL_SEM_RAM 0x000003a8U
+#define ATL_SEM_RAM_RESET 0X1
+
+/*Mailbox*/
+#define ATL_MBOX_ADDR  0x00000360U
+#define ATL_MBOX_CTRL1 0x00000200U
+#define ATL_MBOX_CTRL1_START_MBOX_OPT 0x8000
+
+#define ATL_MBOX_CTRL3 0x00000208U
+#define ATL_MBOX_CTRL5 0x0000020cU
+
+#define ATL_FLAG_A1 0x1
+#define ATL_FLAG_A2 0x2
+
+/*write register*/
+#define ATL_WRITE_REG( VAL, REG )      writel( VAL, nic->regs + (REG) )
+#define ATL_READ_REG( REG )    readl( nic->regs + (REG) ) /*read register*/
+
+struct atl_desc_tx {
+       uint64_t address;
+       uint32_t status;
+       uint32_t flag;
+} __attribute__ (( packed ));
+
+#define ATL_DESC_TX_DX_TYPE_VALUE 0x1
+
+#define  ATL_DESC_TX_DX_EOP_VALUE  0x1
+#define  ATL_DESC_TX_EOP_MASK     0x00200000
+#define  ATL_DESC_TX_EOP_OFFSET   21
+
+#define ATL_DESC_TX_CMD_MASK    0x3FC00000UL
+#define ATL_DESC_TX_CMD_OFFSET  22
+#define ATL_DESC_TX_CMD_VALUE   0x22
+
+#define ATL_DESC_TX_BUF_LEN_MASK   0x000FFFF0
+#define ATL_DESC_TX_BUF_LEN_OFFSET 5
+
+#define ATL_DESC_TX_PAY_LEN_MASK   0xFFFFC000
+#define ATL_DESC_TX_PAY_LEN_OFFSET 14
+
+struct atl_desc_tx_wb {
+       uint64_t rsvd1;
+       uint32_t status;
+       uint32_t rsvd4;
+} __attribute__ (( packed ));
+
+#define ATL_TX_DESC_STATUS_DD  0x00100000UL
+
+struct atl_desc_rx {
+       uint64_t data_addr;
+       uint64_t hdr_addr;
+
+} __attribute__ (( packed ));
+
+struct atl_desc_rx_wb {
+       uint64_t rsvd2;
+       uint16_t status;
+       uint16_t pkt_len;
+       uint32_t rsvd4;
+} __attribute__ (( packed ));
+
+#define ATL_RX_DESC_STATUS_DD  0x0001UL
+#define ATL_RX_DESC_STATUS_EOP 0x0002UL
+struct atl_ring {
+       unsigned int sw_tail;
+       unsigned int sw_head;
+       void *ring;
+       /** Descriptor ring DMA mapping */
+       struct dma_mapping map;
+       unsigned int length;
+};
+
+struct atl_nic;
+
+struct atl_hw_ops {
+       int ( *reset ) ( struct atl_nic *nic );
+       int ( *start ) ( struct atl_nic *nic );
+       int ( *stop ) ( struct atl_nic *nic );
+       int ( *get_link ) ( struct atl_nic *nic );
+       int ( *get_mac ) ( struct atl_nic *, uint8_t *mac );
+};
+
+/** An aQuanita network card */
+struct atl_nic {
+       /** Registers */
+       void *regs;
+       /** Port number (for multi-port devices) */
+       unsigned int port;
+       /** DMA device */
+       struct dma_device *dma;
+       /** Flags */
+       unsigned int flags;
+       struct atl_ring tx_ring;
+       struct atl_ring rx_ring;
+       struct io_buffer *iobufs[ATL_RING_SIZE];
+       uint32_t link_state;
+       uint32_t mbox_addr;
+       struct atl_hw_ops *hw_ops;
+};
+
+struct atl_hw_stats {
+       uint32_t version;
+       uint32_t tid;
+};
+
+#endif /* _AQUANTIA_H */
diff --git a/src/drivers/net/marvell/atl2_hw.c b/src/drivers/net/marvell/atl2_hw.c
new file mode 100644 (file)
index 0000000..8058207
--- /dev/null
@@ -0,0 +1,225 @@
+/** @file
+ *
+ * Marvell AQtion family network card driver, hardware-specific functions.
+ *
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <byteswap.h>
+#include <ipxe/pci.h>
+#include "aqc1xx.h"
+#include "atl2_hw.h"
+
+static int atl2_hw_boot_completed_ ( struct atl_nic *nic ) {
+       uint32_t reset_status = ATL_READ_REG ( ATL2_GLB_RST_CTRL2 );
+
+       return ( reset_status & ATL2_RESET_STATUS_BOOT_COMPLETED_MASK ) ||
+                  ( ATL_READ_REG ( ATL2_HOST_ITR_REQ )
+                  & ATL2_FW_HOST_INTERRUPT_REQUEST_READY );
+}
+
+void atl2_hw_read_shared_in_ ( struct atl_nic *nic, uint32_t offset,
+                                                               uint32_t *data, uint32_t len ) {
+       uint32_t i;
+
+       for (i = 0; i < len; ++i )
+       {
+               data[i] = ATL_READ_REG ( ATL2_MIF_SHARED_BUF_IN + offset + i * 4 );
+       }
+}
+
+void atl2_hw_write_shared_in_ ( struct atl_nic *nic, uint32_t offset,
+                                                         uint32_t *data, uint32_t len ) {
+       uint32_t i;
+
+       for ( i = 0; i < len; ++i )
+       {
+               ATL_WRITE_REG ( data[i], ATL2_MIF_SHARED_BUF_IN + offset + i * 4 );
+       }
+}
+
+int atl2_hw_finish_ack_ ( struct atl_nic *nic, uint32_t ms ) {
+       uint32_t i;
+       int err = 0;
+
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL2_HOST_FINISHED_WRITE )
+       | 1, ATL2_HOST_FINISHED_WRITE );
+
+       for ( i = 0; i < ( ms / 100 ); ++i )
+       {
+               if ( ( ATL_READ_REG ( ATL2_MCP_BUSY_WRITE ) & 1 ) == 0 )
+               {
+                       break;
+               }
+               udelay ( ATL2_DELAY_100 );
+       }
+       if (i == ( ms / 100 ) )
+               err = -ETIME;
+
+       return err;
+}
+
+int atl2_hw_fw_init_ ( struct atl_nic *nic ) {
+       uint32_t val;
+       int err = 0;
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_LINK_CTRL_IN_OFF, &val, 1 );
+       val |= ( ATL2_HOST_MODE_ACTIVE | ( 1U << 13 ) );
+       atl2_hw_write_shared_in_ ( nic, ATL2_LINK_CTRL_IN_OFF, &val, 1 );
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_MTU_IN_OFF, &val, 1 );
+       val = 16352;
+       atl2_hw_write_shared_in_ ( nic, ATL2_MTU_IN_OFF, &val, 1 );
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+       val = 0;
+       atl2_hw_write_shared_in_( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+       err = atl2_hw_finish_ack_ ( nic, 50000000 );
+
+       return err;
+}
+
+int atl2_hw_reset ( struct atl_nic *nic ) {
+       int completed = 0;
+       uint32_t status = 0;
+       uint32_t request;
+       int err = 0;
+       int i;
+
+       request = ATL2_RESET_STATUS_REQ_GSR;
+
+       ATL_WRITE_REG ( request, ATL2_GLB_RST_CTRL2 );
+
+       /* Wait for boot code started every 10us, 200 ms */
+       for ( i = 0; i < 20000; ++i )
+       {
+               status = ATL_READ_REG ( ATL2_GLB_RST_CTRL2 );
+
+               if ( ( ( status & ATL2_RESET_STATUS_BC_STARTED ) &&
+                        ( status != 0xFFFFFFFFu ) ) )
+                       break;
+
+               udelay ( ATL2_DELAY_10 );
+       }
+       if ( i == 20000 )
+       {
+               DBGC ( nic, "Boot code hanged" );
+               err = -EIO;
+               goto err_exit;
+       }
+
+       /* Wait for boot succeed, failed or host request every 10us, 480ms */
+       for ( i = 0; i < 48000; ++i )
+       {
+               completed = atl2_hw_boot_completed_ ( nic );
+               if ( completed )
+                       break;
+
+               udelay ( ATL2_DELAY_10 );
+       }
+
+       if ( !completed )
+       {
+               DBGC ( nic, "FW Restart timed out" );
+               err = -ETIME;
+               goto err_exit;
+       }
+
+       status = ATL_READ_REG ( ATL2_GLB_RST_CTRL2 );
+
+       if ( status & ATL2_RESET_STATUS_BOOT_FAILED_MASK )
+       {
+               err = -EIO;
+               DBGC ( nic, "FW Restart failed" );
+               DBGC ( nic, "status = 0x%x", status );
+               goto err_exit;
+       }
+
+       if ( ATL_READ_REG ( ATL2_HOST_ITR_REQ )
+                       & ATL2_FW_HOST_INTERRUPT_REQUEST_READY )
+       {
+               err = -ENOTSUP;
+               DBGC ( nic, "Dynamic FW load not implemented" );
+               goto err_exit;
+       }
+
+       err = atl2_hw_fw_init_ ( nic );
+
+err_exit:
+       return err;
+}
+
+int atl2_hw_start ( struct atl_nic *nic ) {
+       uint32_t val;
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+       val = 0x4B00FFE1;
+       atl2_hw_write_shared_in_ ( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+
+       return atl2_hw_finish_ack_ ( nic, 100000 );
+}
+
+int atl2_hw_stop ( struct atl_nic *nic ) {
+       uint32_t val;
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+       val = 0;
+       atl2_hw_write_shared_in_ ( nic, ATL2_LINK_OPTS_IN_OFF, &val, 1 );
+
+       return atl2_hw_finish_ack_ ( nic, 100000 );
+}
+
+int atl2_hw_get_link ( struct atl_nic *nic ) {
+       uint32_t val;
+
+       val = ATL_READ_REG ( ATL2_MIF_SHARED_BUF_OUT + ATL2_LINK_STS_OUT_OFF );
+
+       return ( ( val & 0xf ) != 0 ) && ( ( val & 0xF0 ) != 0 );
+}
+
+int atl2_hw_get_mac ( struct atl_nic *nic, uint8_t *mac ) {
+       uint32_t mac_addr[2] = {0};
+
+       atl2_hw_read_shared_in_ ( nic, ATL2_MAC_ADDR_IN_OFF, mac_addr, 2 );
+
+       memcpy ( mac, ( uint8_t * )mac_addr, 6 );
+
+       return 0;
+}
+
+struct atl_hw_ops atl2_hw = {
+       .reset = atl2_hw_reset,
+       .start = atl2_hw_start,
+       .stop = atl2_hw_stop,
+       .get_link = atl2_hw_get_link,
+       .get_mac = atl2_hw_get_mac,
+};
diff --git a/src/drivers/net/marvell/atl2_hw.h b/src/drivers/net/marvell/atl2_hw.h
new file mode 100644 (file)
index 0000000..d044c21
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *   TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ATL2_HW_H
+#define __ATL2_HW_H
+
+FILE_LICENCE ( BSD2 );
+
+#define ATL2_GLB_RST_CTRL2 0x3040
+#define ATL2_HOST_FINISHED_WRITE 0xE00
+#define ATL2_MCP_BUSY_WRITE 0xE04
+#define ATL2_HOST_ITR_REQ 0xF00
+
+
+#define ATL2_RESET_STATUS_REQ_GSR              ( 1U << 0x0 )
+#define ATL2_RESET_STATUS_REQ_HOST_BOOT                ( 1U << 0x8 )
+#define ATL2_RESET_STATUS_REQ_MAC_FAST_BOOT    ( 1U << 0xA )
+#define ATL2_RESET_STATUS_REQ_PHY_FAST_BOOT    ( 1U << 0xB )
+
+#define ATL2_RESET_STATUS_HOST_LOAD_COMPLETED  ( 1U << 0x10 )
+#define ATL2_RESET_STATUS_REQUIRE_HOST_LOAD    ( 1U << 0x11 )
+#define ATL2_RESET_STATUS_BC_STARTED           ( 1U << 0x18 )
+#define ATL2_RESET_STATUS_CRASH_DURING_INIT    ( 1U << 0x1B )
+#define ATL2_RESET_STATUS_BC_FAILED            ( 1U << 0x1C )
+#define ATL2_RESET_STATUS_FW_FAILED            ( 1U << 0x1D )
+#define ATL2_RESET_STATUS_FW_SUCCEED           ( 1U << 0x1F )
+
+#define ATL2_RESET_STATUS_BOOT_FAILED_MASK ( ATL2_RESET_STATUS_CRASH_DURING_INIT | ATL2_RESET_STATUS_BC_FAILED | ATL2_RESET_STATUS_FW_FAILED )
+#define ATL2_RESET_STATUS_BOOT_COMPLETED_MASK ( ATL2_RESET_STATUS_BOOT_FAILED_MASK | ATL2_RESET_STATUS_FW_SUCCEED )
+
+#define ATL2_FW_HOST_INTERRUPT_REQUEST_READY           0x0001
+#define ATL2_FW_HOST_INTERRUPT_MAC_READY               0x0004
+#define ATL2_FW_HOST_INTERRUPT_DATA_HANDLED            0x0100
+#define ATL2_FW_HOST_INTERRUPT_LINK_UP                 0x0200
+#define ATL2_FW_HOST_INTERRUPT_LINK_DOWN               0x0400
+#define ATL2_FW_HOST_INTERRUPT_PHY_FAULT               0x0800
+#define ATL2_FW_HOST_INTERRUPT_MAC_FAULT               0x1000
+#define ATL2_FW_HOST_INTERRUPT_TEMPERATURE_WARNING     0x2000
+#define ATL2_FW_HOST_INTERRUPT_HEARTBEAT               0x4000
+
+#define ATL2_FW_LINK_RATE_INVALID 0
+#define ATL2_FW_LINK_RATE_10M     1
+#define ATL2_FW_LINK_RATE_100M    2
+#define ATL2_FW_LINK_RATE_1G      3
+#define ATL2_FW_LINK_RATE_2G5     4
+#define ATL2_FW_LINK_RATE_5G      5
+#define ATL2_FW_LINK_RATE_10G     6
+
+#define ATL2_HOST_MODE_INVALID      0U
+#define ATL2_HOST_MODE_ACTIVE       1U
+#define ATL2_HOST_MODE_SLEEP_PROXY  2U
+#define ATL2_HOST_MODE_LOW_POWER    3U
+#define ATL2_HOST_MODE_SHUTDOWN     4U
+
+#define ATL2_MIF_SHARED_BUF_IN 0x12000
+#define ATL2_MIF_SHARED_BUF_OUT 0x13000
+
+#define ATL2_MTU_IN_OFF 0x0
+#define ATL2_MAC_ADDR_IN_OFF 0x8
+#define ATL2_LINK_CTRL_IN_OFF 0x10
+#define ATL2_LINK_OPTS_IN_OFF 0x18
+
+#define ATL2_FW_OUT_OFF 0x8
+#define ATL2_LINK_STS_OUT_OFF 0x14
+
+#define ATL2_DELAY_10  10
+#define ATL2_DELAY_100  100
+
+#endif
diff --git a/src/drivers/net/marvell/atl_hw.c b/src/drivers/net/marvell/atl_hw.c
new file mode 100644 (file)
index 0000000..e0843e6
--- /dev/null
@@ -0,0 +1,313 @@
+/** @file
+ *
+ * Marvell AQtion family network card driver, hardware-specific functions.
+ *
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <byteswap.h>
+#include <ipxe/pci.h>
+#include "aqc1xx.h"
+#include "atl_hw.h"
+#include <compiler.h>
+
+
+int atl_hw_reset_flb_ ( struct atl_nic *nic ) {
+       uint32_t val;
+       int k = 0;
+
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_MBOX_ERR_UP_RUN_STALL, ATL_GLB_CTRL2 );
+       mdelay ( ATL_DELAY_50_MNS );
+
+       /* Cleanup SPI */
+       val = ATL_READ_REG ( ATL_GLB_NVR_PROV4 );
+       ATL_WRITE_REG ( val | ATL_GBL_NVR_PROV4_RESET, ATL_GLB_NVR_PROV4 );
+
+       ATL_WRITE_REG( ( ATL_READ_REG ( ATL_GLB_STD_CTRL ) &
+                     ~ATL_GLB_CTRL_RST_DIS ) | ATL_GLB_STD_CTRL_RESET,
+                       ATL_GLB_STD_CTRL );
+
+       /* Kickstart MAC */
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_FW_RESET, ATL_GLB_CTRL2 );
+       ATL_WRITE_REG ( ATL_MIF_PWR_GATING_EN_CTRL_RESET,
+                       ATL_MIF_PWR_GATING_EN_CTRL );
+
+       ATL_WRITE_REG ( ATL_GEN_PROV9_ENABLE, ATL_GEN_PROV9 );
+
+       /* Reset SPI again because of possible interrupted SPI burst */
+       val = ATL_READ_REG ( ATL_GLB_NVR_PROV4 );
+       ATL_WRITE_REG ( val | ATL_GBL_NVR_PROV4_RESET, ATL_GLB_NVR_PROV4 );
+       mdelay ( ATL_DELAY_10_MNS );
+       /* Clear SPI reset state */
+       ATL_WRITE_REG ( val & ~ATL_GBL_NVR_PROV4_RESET, ATL_GLB_NVR_PROV4 );
+
+       /* MAC Kickstart */
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_MAC_KICK_START, ATL_GLB_CTRL2 );
+
+       for (k = 0; k < 1000; k++) {
+               uint32_t flb_status = ATL_READ_REG ( ATL_MPI_DAISY_CHAIN_STS );
+
+               flb_status = flb_status & FLB_LOAD_STS;
+               if ( flb_status )
+                       break;
+               mdelay ( ATL_DELAY_10_MNS );
+       }
+       if ( k == 1000 ) {
+               DBGC (nic, "MAC kickstart failed\n" );
+               return -EIO;
+       }
+
+       /* FW reset */
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_FW_RESET, ATL_GLB_CTRL2 );
+       mdelay ( ATL_DELAY_50_MNS );
+
+       ATL_WRITE_REG ( ATL_GBL_MCP_SEM1_RELEASE, ATL_GLB_MCP_SEM1 );
+
+       /* Global software reset*/
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RX_CTRL ) &
+                       ~ATL_RX_CTRL_RST_DIS, ATL_RX_CTRL );
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_TX_CTRL ) &
+                       ~ATL_TX_CTRL_RST_DIS, ATL_TX_CTRL );
+
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_MAC_PHY_CTRL ) &
+                       ~ATL_MAC_PHY_CTRL_RST_DIS, ATL_MAC_PHY_CTRL );
+
+       ATL_WRITE_REG ( ( ATL_READ_REG ( ATL_GLB_STD_CTRL ) &
+                       ~ATL_GLB_CTRL_RST_DIS ) | ATL_GLB_STD_CTRL_RESET,
+                       ATL_GLB_STD_CTRL );
+
+       for (k = 0; k < 1000; k++) {
+               u32 fw_state = ATL_READ_REG ( ATL_FW_VER );
+
+               if ( fw_state )
+                       break;
+               mdelay ( ATL_DELAY_10_MNS );
+       }
+       if ( k == 1000 ) {
+               DBGC ( nic, "FW kickstart failed\n" );
+               return -EIO;
+       }
+       /* Old FW requires fixed delay after init */
+       mdelay ( ATL_DELAY_15_MNS );
+
+       return 0;
+}
+
+int atl_hw_reset_rbl_ ( struct atl_nic *nic ) {
+       uint32_t val, rbl_status;
+       int k;
+
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_MBOX_ERR_UP_RUN_STALL, ATL_GLB_CTRL2 );
+       ATL_WRITE_REG ( ATL_GBL_MCP_SEM1_RELEASE, ATL_GLB_MCP_SEM1 );
+       ATL_WRITE_REG ( ATL_MIF_PWR_GATING_EN_CTRL_RESET,
+                       ATL_MIF_PWR_GATING_EN_CTRL );
+
+       /* Alter RBL status */
+       ATL_WRITE_REG ( POISON_SIGN, ATL_MPI_BOOT_EXIT_CODE );
+
+       /* Cleanup SPI */
+       val = ATL_READ_REG ( ATL_GLB_NVR_PROV4 );
+       ATL_WRITE_REG ( val | ATL_GBL_NVR_PROV4_RESET, ATL_GLB_NVR_PROV4 );
+
+       /* Global software reset*/
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_RX_CTRL ) & ~ATL_RX_CTRL_RST_DIS,
+                       ATL_RX_CTRL );
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_TX_CTRL ) & ~ATL_TX_CTRL_RST_DIS,
+                       ATL_TX_CTRL );
+       ATL_WRITE_REG ( ATL_READ_REG ( ATL_MAC_PHY_CTRL ) &
+                       ~ATL_MAC_PHY_CTRL_RST_DIS, ATL_MAC_PHY_CTRL );
+
+       ATL_WRITE_REG ( ( ATL_READ_REG ( ATL_GLB_STD_CTRL ) &
+                       ~ATL_GLB_CTRL_RST_DIS ) | ATL_GLB_STD_CTRL_RESET,
+                       ATL_GLB_STD_CTRL );
+
+       ATL_WRITE_REG ( ATL_GLB_CTRL2_MBOX_ERR_UP_RUN_NORMAL, ATL_GLB_CTRL2 );
+
+       /* Wait for RBL boot */
+       for ( k = 0; k < 1000; k++ ) {
+               rbl_status = ATL_READ_REG ( ATL_MPI_BOOT_EXIT_CODE ) & 0xFFFF;
+               if ( rbl_status && rbl_status != POISON_SIGN )
+                       break;
+               mdelay ( ATL_DELAY_10_MNS );
+       }
+       if ( !rbl_status || rbl_status == POISON_SIGN ) {
+               DBGC ( nic, "RBL Restart failed\n" );
+               return -EIO;
+       }
+
+       if ( rbl_status == FW_NOT_SUPPORT )
+               return -ENOTSUP;
+
+       for ( k = 0; k < 1000; k++ ) {
+               u32 fw_state = ATL_READ_REG ( ATL_FW_VER );
+
+               if ( fw_state )
+                       break;
+               mdelay ( ATL_DELAY_10_MNS );
+       }
+       if ( k == 1000 ) {
+               DBGC ( nic, "FW kickstart failed\n" );
+               return -EIO;
+       }
+       /* Old FW requires fixed delay after init */
+       mdelay ( ATL_DELAY_15_MNS );
+
+       return 0;
+}
+
+int atl_hw_reset ( struct atl_nic *nic ) {
+       uint32_t boot_exit_code = 0;
+       uint32_t k;
+       int rbl_enabled;
+       uint32_t fw_ver;
+       uint32_t sem_timeout;
+
+       for ( k = 0; k < 1000; ++k ) {
+               uint32_t flb_status = ATL_READ_REG ( ATL_MPI_DAISY_CHAIN_STS );
+               boot_exit_code = ATL_READ_REG ( ATL_MPI_BOOT_EXIT_CODE );
+               if ( flb_status != ATL_MPI_DAISY_CHAIN_STS_ERROR_STATUS ||
+                       boot_exit_code != 0 )
+                       break;
+       }
+
+       if ( k == 1000 ) {
+               DBGC ( nic, "Neither RBL nor FLB firmware started\n" );
+               return -ENOTSUP;
+       }
+
+       rbl_enabled = ( boot_exit_code != 0 );
+
+       fw_ver = ATL_READ_REG ( ATL_FW_VER );
+       if ( ( ( fw_ver >> 24 ) & 0xFF ) >= 4 ) {
+               sem_timeout = ATL_READ_REG ( ATL_SEM_TIMEOUT );
+               if ( sem_timeout > ATL_SEM_MAX_TIMEOUT )
+                       sem_timeout = ATL_SEM_MAX_TIMEOUT;
+
+               for ( k = 0; k < sem_timeout; ++k ) {
+                       if ( ATL_READ_REG ( ATL_GLB_MCP_SEM4 ) )
+                               break;
+
+                       mdelay ( ATL_DELAY_1_MNS );
+               }
+               for ( k = 0; k < sem_timeout; ++k ) {
+                       if ( ATL_READ_REG ( ATL_GLB_MCP_SEM5 ) )
+                               break;
+
+                       mdelay ( ATL_DELAY_1_MNS );
+               }
+       }
+
+
+       if ( rbl_enabled )
+               return atl_hw_reset_rbl_ ( nic );
+       else
+               return atl_hw_reset_flb_ ( nic );
+}
+
+int atl_hw_start ( struct atl_nic *nic ) {
+       ATL_WRITE_REG ( ATL_LINK_ADV_AUTONEG, ATL_LINK_ADV );
+       return 0;
+}
+
+int atl_hw_stop ( struct atl_nic *nic ) {
+       ATL_WRITE_REG ( ATL_SHUT_LINK, ATL_LINK_ADV );
+       return 0;
+}
+
+int atl_hw_get_link ( struct atl_nic *nic ) {
+       return ( ATL_READ_REG ( ATL_LINK_ST) & ATL_LINK_ADV_AUTONEG ) != 0;
+}
+
+int atl_hw_read_mem ( struct atl_nic *nic, uint32_t addr, uint32_t *buffer,
+                   uint32_t size ) {
+       uint32_t i;
+
+       for ( i = 0; i < 100; ++i ) {
+               if ( ATL_READ_REG( ATL_SEM_RAM ) )
+                       break;
+               mdelay ( ATL_DELAY_1_MNS );
+       }
+       if ( i == 100 ) {
+               DBGC ( nic, "Semaphore Register not set\n" );
+               return -EIO;
+       }
+
+       ATL_WRITE_REG ( addr, ATL_MBOX_CTRL3 );
+
+       for ( i = 0; i < size; ++i, addr += 4 ) {
+               uint32_t j;
+
+               ATL_WRITE_REG ( ATL_MBOX_CTRL1_START_MBOX_OPT, ATL_MBOX_CTRL1 );
+               for ( j = 0; j < 10000; ++j ) {
+                       if ( ATL_READ_REG (ATL_MBOX_CTRL3 ) != addr )
+                               break;
+                       udelay ( ATL_DELAY_10_MNS );
+               }
+               if ( j == 10000 ) {
+                       DBGC ( nic, "Reading from CTRL3 Register Failed\n" );
+                       return -EIO;
+               }
+
+               buffer[i] = ATL_READ_REG ( ATL_MBOX_CTRL5 );
+       }
+
+       ATL_WRITE_REG( ATL_SEM_RAM_RESET, ATL_SEM_RAM );
+
+       return 0;
+}
+
+int atl_hw_get_mac ( struct atl_nic *nic, uint8_t *mac ) {
+       uint32_t mac_addr[2] = {0};
+       int err = 0;
+       uint32_t efuse_addr = ATL_READ_REG ( ATL_GLB_MCP_SP26 );
+
+       if ( efuse_addr != 0) {
+               uint32_t mac_efuse_addr = efuse_addr + 40 * sizeof ( uint32_t );
+               err = atl_hw_read_mem ( nic, mac_efuse_addr, mac_addr, 2 );
+               if ( err != 0 )
+                       return err;
+
+               mac_addr[0] = cpu_to_be32 ( mac_addr[0] );
+               mac_addr[1] = cpu_to_be32 ( mac_addr[1] );
+
+               memcpy ( mac, ( uint8_t * )mac_addr, ATL_MAC_ADDRESS_SIZE );
+       }
+       return 0;
+}
+
+struct atl_hw_ops atl_hw = {
+       .reset = atl_hw_reset,
+       .start = atl_hw_start,
+       .stop = atl_hw_stop,
+       .get_link = atl_hw_get_link,
+       .get_mac = atl_hw_get_mac,
+};
diff --git a/src/drivers/net/marvell/atl_hw.h b/src/drivers/net/marvell/atl_hw.h
new file mode 100644 (file)
index 0000000..efc9f86
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright(C) 2017-2024 Marvell
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *   TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR HOLDER OR
+ *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __ATL_HW_H
+#define __ATL_HW_H
+
+FILE_LICENCE ( BSD2 );
+
+#define ATL_GLB_STD_CTRL 0x0
+#define ATL_GLB_CTRL_RST_DIS 0x4000
+#define ATL_FW_VER 0x18
+
+#define ATL_MPI_DAISY_CHAIN_STS 0x704
+#define ATL_MPI_RX_DAISY_CHAIN_DATA 0x04000000
+#define ATL_MPI_RX_DAISY_CHAIN_SOF  0x02000000
+#define FLB_LOAD_STS 0x10
+
+#define ATL_MPI_BOOT_EXIT_CODE 0x388
+
+#define ATL_SEM_TIMEOUT 0x348
+#define ATL_SEM_MAX_TIMEOUT 3000
+
+#define ATL_GLB_CTRL2 0x404
+#define ATL_GLB_MCP_SEM1 0x3A0
+#define ATL_GBL_MCP_SEM1_RELEASE 0x1
+
+#define ATL_GLB_MCP_SEM4 0x3AC
+#define ATL_GLB_MCP_SEM5 0x3B0
+#define ATL_GLB_MCP_SP26 0x364
+#define ATL_MIF_PWR_GATING_EN_CTRL 0x32A8
+
+#define ATL_GLB_NVR_PROV4       0x53C
+#define ATL_GBL_NVR_PROV4_RESET 0x10
+
+
+#define ATL_GEN_PROV9 0x520
+
+#define ATL_MAC_PHY_CTRL 0x00004000U
+#define ATL_MAC_PHY_CTRL_RST_DIS 0x20000000U
+
+#define ATL_MIF_PWR_GATING_EN_CTRL_RESET      0x0
+#define ATL_GEN_PROV9_ENABLE                  0x1
+#define ATL_GLB_CTRL2_MAC_KICK_START          0x180e0
+#define ATL_GLB_CTRL2_FW_RESET                0x80e0
+#define ATL_GLB_CTRL2_MBOX_ERR_UP_RUN_STALL   0x40e1
+#define ATL_GLB_CTRL2_MBOX_ERR_UP_RUN_NORMAL  0x40e0
+#define ATL_GLB_STD_CTRL_RESET                0x8000
+#define ATL_MPI_DAISY_CHAIN_STS_ERROR_STATUS  0x06000000
+
+#define ATL_DELAY_1_MNS   1
+#define ATL_DELAY_10_MNS  10
+#define ATL_DELAY_15_MNS  15
+#define ATL_DELAY_50_MNS  50
+
+#define ATL_MAC_ADDRESS_SIZE 6
+#define POISON_SIGN 0xDEAD
+#define FW_NOT_SUPPORT 0xF1A7
+
+#endif
index 7615075bc6261f89dc10d99c8d67ac3cdd4a9f4d..42bc17789ef2c17243ef7ecd7266ccafd7371ced 100644 (file)
@@ -225,6 +225,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_pcibridge           ( ERRFILE_DRIVER | 0x00d40000 )
 #define ERRFILE_mnpnet              ( ERRFILE_DRIVER | 0x00d50000 )
 #define ERRFILE_gve                 ( ERRFILE_DRIVER | 0x00d60000 )
+#define ERRFILE_aqc1xx              ( ERRFILE_DRIVER | 0x00d70000 )
+#define ERRFILE_atl_hw              ( ERRFILE_DRIVER | 0x00d80000 )
+#define ERRFILE_atl2_hw                     ( ERRFILE_DRIVER | 0x00d90000 )
 
 #define ERRFILE_aoe                    ( ERRFILE_NET | 0x00000000 )
 #define ERRFILE_arp                    ( ERRFILE_NET | 0x00010000 )