Compare commits

...

4 Commits
riscv64 ... ena

Author SHA1 Message Date
f88761ef49 [ena] Change reported operating system type to "iPXE"
As described in commit 3b81a4e ("[ena] Provide a host information
page"), we currently report an operating system type of "Linux" in
order to work around broken versions of the ENA firmware that will
fail to create a completion queue if we report the correct operating
system type.

As of September 2024, the ENA team at AWS assures us that the entire
AWS fleet has been upgraded to fix this bug, and that we are now safe
to report the correct operating system type value in the "type" field
of struct ena_host_info.

The ENA team has also clarified that at least some deployed versions
of the ENA firmware still have the defect that requires us to report
an operating system version number of 2 (regardless of operating
system type), and so we continue to report ENA_HOST_INFO_VERSION_WTF
in the "version" field of struct ena_host_info.

Add an explicit warning on the previous known failure path, in case
some deployed versions of the ENA firmware turn out to not have been
upgraded as expected.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-05 14:13:16 +01:00
2b82007571 [gdb] Allow CPU architectures to omit support for GDB
Move the <gdbmach.h> file to <bits/gdbmach.h>, and provide a common
dummy implementation for all architectures that have not yet
implemented support for GDB.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-05 13:00:39 +01:00
804f35cb5a [build] Centralise dummy architecture-specific headers
Simplify the process of adding a new CPU architecture by providing
common implementations of typically empty architecture-specific header
files.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-03 17:32:26 +01:00
c7f2e75519 [aqc1xx] Add support for Marvell AQtion Ethernet controller
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>
2024-09-02 13:45:54 +01:00
63 changed files with 1877 additions and 443 deletions

View 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

View File

@ -366,11 +366,6 @@ MAKEDEPS += arch/$(ARCH)/Makefile
include arch/$(ARCH)/Makefile
endif
# Include architecture-specific include path
ifdef ARCH
INCDIRS += arch/$(ARCH)/include
endif
###############################################################################
#
# Especially ugly workarounds

View File

@ -3,9 +3,9 @@
ASM_TCHAR := %
ASM_TCHAR_OPS := %%
# Include common ARM headers
# Include ARM-specific headers
#
INCDIRS += arch/arm/include
INCDIRS := arch/$(ARCH)/include arch/arm/include $(INCDIRS)
# ARM-specific directories containing source files
#

View File

@ -1,12 +0,0 @@
#ifndef _BITS_ACPI_H
#define _BITS_ACPI_H
/** @file
*
* ARM-specific ACPI API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_ACPI_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_HYPERV_H
#define _BITS_HYPERV_H
/** @file
*
* Hyper-V interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_HYPERV_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_IOMAP_H
#define _BITS_IOMAP_H
/** @file
*
* ARM-specific I/O mapping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_IOMAP_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_MP_H
#define _BITS_MP_H
/** @file
*
* ARM-specific multiprocessor API implementation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MP_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_PCI_IO_H
#define _BITS_PCI_IO_H
/** @file
*
* ARM PCI I/O API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_PCI_IO_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* ARM-specific reboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_REBOOT_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* ARM-specific sanboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SANBOOT_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* ARM-specific SMBIOS API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SMBIOS_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* ARM-specific time API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_TIME_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* ARM-specific user access API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UACCESS_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UART_H
#define _BITS_UART_H
/** @file
*
* 16550-compatible UART
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UART_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* ARM-specific user memory allocation API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UMALLOC_H */

View File

@ -1,19 +0,0 @@
#ifndef _BITS_TCPIP_H
#define _BITS_TCPIP_H
/** @file
*
* Transport-network layer interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static inline __attribute__ (( always_inline )) uint16_t
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
/* Not yet optimised */
return generic_tcpip_continue_chksum ( partial, data, len );
}
#endif /* _BITS_TCPIP_H */

View File

@ -1,45 +0,0 @@
#ifndef GDBMACH_H
#define GDBMACH_H
/** @file
*
* GDB architecture specifics
*
* This file declares functions for manipulating the machine state and
* debugging context.
*
*/
#include <stdint.h>
typedef unsigned long gdbreg_t;
/* Register snapshot */
enum {
/* Not yet implemented */
GDBMACH_NREGS,
};
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
/* Not yet implemented */
( void ) regs;
( void ) pc;
}
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
/* Not yet implemented */
( void ) regs;
( void ) step;
}
static inline void gdbmach_breakpoint ( void ) {
/* Not yet implemented */
}
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* GDBMACH_H */

View File

@ -18,6 +18,9 @@ endif
# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
CFLAGS += -fshort-wchar
# Include LoongArch64-specific headers
INCDIRS := arch/$(ARCH)/include $(INCDIRS)
# LoongArch64-specific directories containing source files
SRCDIRS += arch/loong64/core
SRCDIRS += arch/loong64/interface/efi

View File

@ -1,12 +0,0 @@
#ifndef _BITS_ACPI_H
#define _BITS_ACPI_H
/** @file
*
* LoongArch64-specific ACPI API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_ACPI_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_HYPERV_H
#define _BITS_HYPERV_H
/** @file
*
* Hyper-V interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_HYPERV_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_IOMAP_H
#define _BITS_IOMAP_H
/** @file
*
* LoongArch64-specific I/O mapping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_IOMAP_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_MP_H
#define _BITS_MP_H
/** @file
*
* LoongArch64-specific multiprocessor API implementation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MP_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_PCI_IO_H
#define _BITS_PCI_IO_H
/** @file
*
* LoongArch64-specific PCI I/O API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_PCI_IO_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* LoongArch64-specific reboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_REBOOT_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* LoongArch64-specific sanboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SANBOOT_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* LoongArch64-specific SMBIOS API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SMBIOS_H */

View File

@ -1,19 +0,0 @@
#ifndef _BITS_TCPIP_H
#define _BITS_TCPIP_H
/** @file
*
* Transport-network layer interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static inline __attribute__ (( always_inline )) uint16_t
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
/* Not yet optimised */
return generic_tcpip_continue_chksum ( partial, data, len );
}
#endif /* _BITS_TCPIP_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* LoongArch64-specific time API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_TIME_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* LoongArch64-specific user access API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UACCESS_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UART_H
#define _BITS_UART_H
/** @file
*
* 16550-compatible UART
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UART_H */

View File

@ -1,12 +0,0 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* LoongArch64-specific user memory allocation API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UMALLOC_H */

View File

@ -1,45 +0,0 @@
#ifndef GDBMACH_H
#define GDBMACH_H
/** @file
*
* GDB architecture specifics
*
* This file declares functions for manipulating the machine state and
* debugging context.
*
*/
#include <stdint.h>
typedef unsigned long gdbreg_t;
/* Register snapshot */
enum {
/* Not yet implemented */
GDBMACH_NREGS,
};
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
/* Not yet implemented */
( void ) regs;
( void ) pc;
}
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
/* Not yet implemented */
( void ) regs;
( void ) step;
}
static inline void gdbmach_breakpoint ( void ) {
/* Not yet implemented */
}
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* GDBMACH_H */

View File

@ -3,9 +3,9 @@
ASM_TCHAR := @
ASM_TCHAR_OPS := @
# Include common x86 headers
# Include x86-specific headers
#
INCDIRS += arch/x86/include
INCDIRS := arch/$(ARCH)/include arch/x86/include $(INCDIRS)
# x86-specific directories containing source files
#

View File

@ -31,7 +31,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uaccess.h>
#include <ipxe/gdbstub.h>
#include <librm.h>
#include <gdbmach.h>
/** @file
*

View File

@ -36,7 +36,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ctype.h>
#include <byteswap.h>
#include <ipxe/gdbstub.h>
#include "gdbmach.h"
enum {
POSIX_EINVAL = 0x1c, /* used to report bad arguments to GDB */

View File

@ -560,8 +560,11 @@ static int ena_create_cq ( struct ena_nic *ena, struct ena_cq *cq ) {
req->create_cq.address = cpu_to_le64 ( virt_to_bus ( cq->cqe.raw ) );
/* Issue request */
if ( ( rc = ena_admin ( ena, req, &rsp ) ) != 0 )
if ( ( rc = ena_admin ( ena, req, &rsp ) ) != 0 ) {
DBGC ( ena, "ENA %p CQ%d creation failed (broken firmware?)\n",
ena, cq->id );
goto err_admin;
}
/* Parse response */
cq->id = le16_to_cpu ( rsp->create_cq.id );
@ -1163,7 +1166,7 @@ static int ena_probe ( struct pci_device *pci ) {
}
ena->info = info;
memset ( info, 0, PAGE_SIZE );
info->type = cpu_to_le32 ( ENA_HOST_INFO_TYPE_LINUX );
info->type = cpu_to_le32 ( ENA_HOST_INFO_TYPE_IPXE );
snprintf ( info->dist_str, sizeof ( info->dist_str ), "%s",
( product_name[0] ? product_name : product_short_name ) );
snprintf ( info->kernel_str, sizeof ( info->kernel_str ), "%s",

View File

@ -191,14 +191,17 @@ struct ena_host_info {
uint32_t features;
} __attribute__ (( packed ));
/** Linux operating system type
/** Operating system type
*
* There is a defined "iPXE" operating system type (with value 5).
* However, some very broken versions of the ENA firmware will refuse
* to allow a completion queue to be created if the "iPXE" type is
* used.
* Some very broken older versions of the ENA firmware will refuse to
* allow a completion queue to be created if "iPXE" (type 5) is used,
* and require us to pretend that we are "Linux" (type 1) instead.
*
* The ENA team at AWS assures us that the entire AWS fleet has been
* upgraded to fix this bug, and that we are now safe to use the
* correct operating system type value.
*/
#define ENA_HOST_INFO_TYPE_LINUX 1
#define ENA_HOST_INFO_TYPE_IPXE 5
/** Driver version
*

View File

@ -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,
};

View File

@ -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 */

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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

15
src/include/bits/acpi.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_ACPI_H
#define _BITS_ACPI_H
/** @file
*
* Dummy architecture-specific ACPI API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_ACPI_H */

View File

@ -1,12 +1,12 @@
#ifndef GDBMACH_H
#define GDBMACH_H
#ifndef _BITS_GDBMACH_H
#define _BITS_GDBMACH_H
/** @file
*
* GDB architecture specifics
* Dummy GDB architecture specifics
*
* This file declares functions for manipulating the machine state and
* debugging context.
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
@ -42,4 +42,4 @@ extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* GDBMACH_H */
#endif /* _BITS_GDBMACH_H */

15
src/include/bits/hyperv.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_HYPERV_H
#define _BITS_HYPERV_H
/** @file
*
* Dummy architecture-specific Hyper-V interface
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_HYPERV_H */

15
src/include/bits/iomap.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_IOMAP_H
#define _BITS_IOMAP_H
/** @file
*
* Dummy architecture-specific I/O mapping API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_IOMAP_H */

15
src/include/bits/mp.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_MP_H
#define _BITS_MP_H
/** @file
*
* Dummy architecture-specific multiprocessor API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MP_H */

15
src/include/bits/nap.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_NAP_H
#define _BITS_NAP_H
/** @file
*
* Dummy architecture-specific CPU sleeping API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_NAP_H */

15
src/include/bits/pci_io.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_PCI_IO_H
#define _BITS_PCI_IO_H
/** @file
*
* Dummy architecture-specific PCI I/O API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_PCI_IO_H */

15
src/include/bits/reboot.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* Dummy architecture-specific reboot API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_REBOOT_H */

View File

@ -0,0 +1,15 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* Dummy architecture-specific sanboot API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SANBOOT_H */

15
src/include/bits/smbios.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* Dummy architecture-specific SMBIOS API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SMBIOS_H */

32
src/include/bits/tcpip.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _BITS_TCPIP_H
#define _BITS_TCPIP_H
/** @file
*
* Generic architecture-specific transport-network layer interface
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/**
* Calculate continued TCP/IP checkum
*
* @v partial Checksum of already-summed data, in network byte order
* @v data Data buffer
* @v len Length of data buffer
* @ret cksum Updated checksum, in network byte order
*/
static inline __attribute__ (( always_inline )) uint16_t
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
/* Not yet optimised */
return generic_tcpip_continue_chksum ( partial, data, len );
}
#endif /* _BITS_TCPIP_H */

15
src/include/bits/time.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* Dummy architecture-specific time API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_TIME_H */

View File

@ -0,0 +1,15 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* Dummy architecture-specific user access API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UACCESS_H */

15
src/include/bits/uart.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _BITS_UART_H
#define _BITS_UART_H
/** @file
*
* Dummy architecture-specific UART
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UART_H */

View File

@ -0,0 +1,15 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* Dummy architecture-specific user memory allocation API implementations
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UMALLOC_H */

View File

@ -3,7 +3,10 @@
/** @file
*
* Xen interface
* Dummy architecture-specific Xen interface
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

View 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 )

View File

@ -11,7 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
#include <gdbmach.h>
#include <bits/gdbmach.h>
/**
* A transport mechanism for the GDB protocol