| /************************************************************************** | |
| * | |
| * Driver datapath common code for Solarflare network cards | |
| * | |
| * Written by Shradha Shah, maintained by <pre-boot-drivers@xilinx.com> | |
| * | |
| * Copyright Fen Systems Ltd. 2005 | |
| * Copyright Level 5 Networks Inc. 2005 | |
| * Copyright 2006-2019 Solarflare Communications Inc. | |
| * Copyright 2019-2020 Xilinx Inc. | |
| * | |
| * This program is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU General Public License as | |
| * published by the Free Software Foundation; either version 2 of the | |
| * License, or any later version. | |
| * | |
| * You can also choose to distribute this program under the terms of | |
| * the Unmodified Binary Distribution Licence (as given in the file | |
| * COPYING.UBDL), provided that you have satisfied its requirements. | |
| * | |
| ***************************************************************************/ | |
| #include <stdint.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <unistd.h> | |
| #include <errno.h> | |
| #include <assert.h> | |
| #include <byteswap.h> | |
| #include <ipxe/io.h> | |
| #include <ipxe/pci.h> | |
| #include <ipxe/malloc.h> | |
| #include <ipxe/iobuf.h> | |
| #include <ipxe/netdevice.h> | |
| #include "efx_common.h" | |
| #include "efx_bitfield.h" | |
| #include "mc_driver_pcol.h" | |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | |
| /******************************************************************************* | |
| * | |
| * | |
| * Low-level hardware access | |
| * | |
| * | |
| ******************************************************************************/ | |
| void | |
| efx_writel(struct efx_nic *efx, efx_dword_t *value, unsigned int reg) | |
| { | |
| DBGCIO(efx, "Writing partial register %x with " EFX_DWORD_FMT "\n", | |
| reg, EFX_DWORD_VAL(*value)); | |
| _efx_writel(efx, value->u32[0], reg); | |
| } | |
| void | |
| efx_readl(struct efx_nic *efx, efx_dword_t *value, unsigned int reg) | |
| { | |
| value->u32[0] = _efx_readl(efx, reg); | |
| DBGCIO(efx, "Read from register %x, got " EFX_DWORD_FMT "\n", | |
| reg, EFX_DWORD_VAL(*value)); | |
| } | |
| /******************************************************************************* | |
| * | |
| * | |
| * Inititialization and Close | |
| * | |
| * | |
| ******************************************************************************/ | |
| void efx_probe(struct net_device *netdev, enum efx_revision revision) | |
| { | |
| struct efx_nic *efx = netdev->priv; | |
| struct pci_device *pci = container_of(netdev->dev, | |
| struct pci_device, dev); | |
| unsigned int reg = PCI_BASE_ADDRESS_0; | |
| uint32_t bar_low; | |
| efx->netdev = netdev; | |
| efx->revision = revision; | |
| /* Find the memory bar to use */ | |
| pci_read_config_dword(pci, reg, &bar_low); | |
| if ((bar_low & PCI_BASE_ADDRESS_IO_MASK) == PCI_BASE_ADDRESS_SPACE_IO) | |
| reg = PCI_BASE_ADDRESS_2; | |
| efx->mmio_start = pci_bar_start(pci, reg); | |
| efx->mmio_len = pci_bar_size(pci, reg); | |
| efx->membase = pci_ioremap(pci, efx->mmio_start, efx->mmio_len); | |
| DBGCP(efx, "BAR of %lx bytes at phys %lx mapped at %p\n", | |
| efx->mmio_len, efx->mmio_start, efx->membase); | |
| /* Enable PCI access */ | |
| adjust_pci_device(pci); | |
| } | |
| void efx_remove(struct net_device *netdev) | |
| { | |
| struct efx_nic *efx = netdev->priv; | |
| iounmap(efx->membase); | |
| efx->membase = NULL; | |
| } |