aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/microchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/microchip')
-rw-r--r--drivers/net/ethernet/microchip/Kconfig10
-rw-r--r--drivers/net/ethernet/microchip/encx24j600-regmap.c7
-rw-r--r--drivers/net/ethernet/microchip/encx24j600.c12
-rw-r--r--drivers/net/ethernet/microchip/lan743x_ethtool.c6
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.c183
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.h6
-rw-r--r--drivers/net/ethernet/microchip/lan743x_ptp.c2
7 files changed, 141 insertions, 85 deletions
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 45fe41f3d9f3..31f9a82dc113 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_MICROCHIP
bool "Microchip devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config ENC28J60
tristate "ENC28J60 support"
depends on SPI
select CRC32
- ---help---
+ help
Support for the Microchip EN28J60 ethernet chip.
To compile this driver as a module, choose M here. The module will be
@@ -29,14 +29,14 @@ config ENC28J60
config ENC28J60_WRITEVERIFY
bool "Enable write verify"
depends on ENC28J60
- ---help---
+ help
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
config ENCX24J600
tristate "ENCX24J600 support"
depends on SPI
- ---help---
+ help
Support for the Microchip ENC424J600/624J600 ethernet chip.
To compile this driver as a module, choose M here. The module will be
@@ -47,7 +47,7 @@ config LAN743X
depends on PCI
select PHYLIB
select CRC16
- ---help---
+ help
Support for the Microchip LAN743x PCI Express Gigabit Ethernet chip
To compile this driver as a module, choose M here. The module will be
diff --git a/drivers/net/ethernet/microchip/encx24j600-regmap.c b/drivers/net/ethernet/microchip/encx24j600-regmap.c
index 1f496fac7033..796e46a53926 100644
--- a/drivers/net/ethernet/microchip/encx24j600-regmap.c
+++ b/drivers/net/ethernet/microchip/encx24j600-regmap.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/**
+/*
* Register map access API - ENCX24J600 support
*
* Copyright 2015 Gridpoint
@@ -17,11 +17,6 @@
#include "encx24j600_hw.h"
-static inline bool is_bits_set(int value, int mask)
-{
- return (value & mask) == mask;
-}
-
static int encx24j600_switch_bank(struct encx24j600_context *ctx,
int bank)
{
diff --git a/drivers/net/ethernet/microchip/encx24j600.c b/drivers/net/ethernet/microchip/encx24j600.c
index b25a13da900a..2c0dcd7acf3f 100644
--- a/drivers/net/ethernet/microchip/encx24j600.c
+++ b/drivers/net/ethernet/microchip/encx24j600.c
@@ -604,9 +604,8 @@ static void encx24j600_set_rxfilter_mode(struct encx24j600_priv *priv)
}
}
-static int encx24j600_hw_init(struct encx24j600_priv *priv)
+static void encx24j600_hw_init(struct encx24j600_priv *priv)
{
- int ret = 0;
u16 macon2;
priv->hw_enabled = false;
@@ -649,8 +648,6 @@ static int encx24j600_hw_init(struct encx24j600_priv *priv)
if (netif_msg_hw(priv))
encx24j600_dump_config(priv, "Hw is initialized");
-
- return ret;
}
static void encx24j600_hw_enable(struct encx24j600_priv *priv)
@@ -1042,12 +1039,7 @@ static int encx24j600_spi_probe(struct spi_device *spi)
}
/* Initialize the device HW to the consistent state */
- if (encx24j600_hw_init(priv)) {
- netif_err(priv, probe, ndev,
- DRV_NAME ": HW initialization error\n");
- ret = -EIO;
- goto out_free;
- }
+ encx24j600_hw_init(priv);
kthread_init_worker(&priv->kworker);
kthread_init_work(&priv->tx_work, encx24j600_tx_proc);
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 3a0b289d9771..dcde496da7fb 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -2,11 +2,11 @@
/* Copyright (C) 2018 Microchip Technology Inc. */
#include <linux/netdevice.h>
-#include "lan743x_main.h"
-#include "lan743x_ethtool.h"
#include <linux/net_tstamp.h>
#include <linux/pci.h>
#include <linux/phy.h>
+#include "lan743x_main.h"
+#include "lan743x_ethtool.h"
/* eeprom */
#define LAN743X_EEPROM_MAGIC (0x74A5)
@@ -548,7 +548,7 @@ static int lan743x_ethtool_get_rxnfc(struct net_device *netdev,
case TCP_V4_FLOW:case UDP_V4_FLOW:
case TCP_V6_FLOW:case UDP_V6_FLOW:
rxnfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case IPV4_FLOW: case IPV6_FLOW:
rxnfc->data |= RXH_IP_SRC | RXH_IP_DST;
return 0;
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index a43140f7b5eb..a1938842f828 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -8,7 +8,10 @@
#include <linux/crc32.h>
#include <linux/microchipphy.h>
#include <linux/net_tstamp.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <linux/rtnetlink.h>
#include <linux/iopoll.h>
#include <linux/crc16.h>
@@ -155,9 +158,8 @@ static void lan743x_tx_isr(void *context, u32 int_sts, u32 flags)
struct lan743x_tx *tx = context;
struct lan743x_adapter *adapter = tx->adapter;
bool enable_flag = true;
- u32 int_en = 0;
- int_en = lan743x_csr_read(adapter, INT_EN_SET);
+ lan743x_csr_read(adapter, INT_EN_SET);
if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR) {
lan743x_csr_write(adapter, INT_EN_CLR,
INT_BIT_DMA_TX_(tx->channel_number));
@@ -798,32 +800,35 @@ static int lan743x_mac_init(struct lan743x_adapter *adapter)
netdev = adapter->netdev;
- /* setup auto duplex, and speed detection */
+ /* disable auto duplex, and speed detection. Phylib does that */
data = lan743x_csr_read(adapter, MAC_CR);
- data |= MAC_CR_ADD_ | MAC_CR_ASD_;
+ data &= ~(MAC_CR_ADD_ | MAC_CR_ASD_);
data |= MAC_CR_CNTR_RST_;
lan743x_csr_write(adapter, MAC_CR, data);
- mac_addr_hi = lan743x_csr_read(adapter, MAC_RX_ADDRH);
- mac_addr_lo = lan743x_csr_read(adapter, MAC_RX_ADDRL);
- adapter->mac_address[0] = mac_addr_lo & 0xFF;
- adapter->mac_address[1] = (mac_addr_lo >> 8) & 0xFF;
- adapter->mac_address[2] = (mac_addr_lo >> 16) & 0xFF;
- adapter->mac_address[3] = (mac_addr_lo >> 24) & 0xFF;
- adapter->mac_address[4] = mac_addr_hi & 0xFF;
- adapter->mac_address[5] = (mac_addr_hi >> 8) & 0xFF;
+ if (!is_valid_ether_addr(adapter->mac_address)) {
+ mac_addr_hi = lan743x_csr_read(adapter, MAC_RX_ADDRH);
+ mac_addr_lo = lan743x_csr_read(adapter, MAC_RX_ADDRL);
+ adapter->mac_address[0] = mac_addr_lo & 0xFF;
+ adapter->mac_address[1] = (mac_addr_lo >> 8) & 0xFF;
+ adapter->mac_address[2] = (mac_addr_lo >> 16) & 0xFF;
+ adapter->mac_address[3] = (mac_addr_lo >> 24) & 0xFF;
+ adapter->mac_address[4] = mac_addr_hi & 0xFF;
+ adapter->mac_address[5] = (mac_addr_hi >> 8) & 0xFF;
+
+ if (((mac_addr_hi & 0x0000FFFF) == 0x0000FFFF) &&
+ mac_addr_lo == 0xFFFFFFFF) {
+ mac_address_valid = false;
+ } else if (!is_valid_ether_addr(adapter->mac_address)) {
+ mac_address_valid = false;
+ }
- if (((mac_addr_hi & 0x0000FFFF) == 0x0000FFFF) &&
- mac_addr_lo == 0xFFFFFFFF) {
- mac_address_valid = false;
- } else if (!is_valid_ether_addr(adapter->mac_address)) {
- mac_address_valid = false;
+ if (!mac_address_valid)
+ eth_random_addr(adapter->mac_address);
}
-
- if (!mac_address_valid)
- eth_random_addr(adapter->mac_address);
lan743x_mac_set_address(adapter, adapter->mac_address);
ether_addr_copy(netdev->dev_addr, adapter->mac_address);
+
return 0;
}
@@ -946,6 +951,7 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
struct phy_device *phydev = netdev->phydev;
+ u32 data;
phy_print_status(phydev);
if (phydev->state == PHY_RUNNING) {
@@ -953,6 +959,39 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
int remote_advertisement = 0;
int local_advertisement = 0;
+ data = lan743x_csr_read(adapter, MAC_CR);
+
+ /* set interface mode */
+ if (phy_interface_mode_is_rgmii(adapter->phy_mode))
+ /* RGMII */
+ data &= ~MAC_CR_MII_EN_;
+ else
+ /* GMII */
+ data |= MAC_CR_MII_EN_;
+
+ /* set duplex mode */
+ if (phydev->duplex)
+ data |= MAC_CR_DPX_;
+ else
+ data &= ~MAC_CR_DPX_;
+
+ /* set bus speed */
+ switch (phydev->speed) {
+ case SPEED_10:
+ data &= ~MAC_CR_CFG_H_;
+ data &= ~MAC_CR_CFG_L_;
+ break;
+ case SPEED_100:
+ data &= ~MAC_CR_CFG_H_;
+ data |= MAC_CR_CFG_L_;
+ break;
+ case SPEED_1000:
+ data |= MAC_CR_CFG_H_;
+ data &= ~MAC_CR_CFG_L_;
+ break;
+ }
+ lan743x_csr_write(adapter, MAC_CR, data);
+
memset(&ksettings, 0, sizeof(ksettings));
phy_ethtool_get_link_ksettings(netdev, &ksettings);
local_advertisement =
@@ -980,20 +1019,44 @@ static void lan743x_phy_close(struct lan743x_adapter *adapter)
static int lan743x_phy_open(struct lan743x_adapter *adapter)
{
struct lan743x_phy *phy = &adapter->phy;
+ struct device_node *phynode;
struct phy_device *phydev;
struct net_device *netdev;
int ret = -EIO;
netdev = adapter->netdev;
- phydev = phy_find_first(adapter->mdiobus);
- if (!phydev)
- goto return_error;
+ phynode = of_node_get(adapter->pdev->dev.of_node);
+ adapter->phy_mode = PHY_INTERFACE_MODE_GMII;
+
+ if (phynode) {
+ of_get_phy_mode(phynode, &adapter->phy_mode);
+
+ if (of_phy_is_fixed_link(phynode)) {
+ ret = of_phy_register_fixed_link(phynode);
+ if (ret) {
+ netdev_err(netdev,
+ "cannot register fixed PHY\n");
+ of_node_put(phynode);
+ goto return_error;
+ }
+ }
+ phydev = of_phy_connect(netdev, phynode,
+ lan743x_phy_link_status_change, 0,
+ adapter->phy_mode);
+ of_node_put(phynode);
+ if (!phydev)
+ goto return_error;
+ } else {
+ phydev = phy_find_first(adapter->mdiobus);
+ if (!phydev)
+ goto return_error;
- ret = phy_connect_direct(netdev, phydev,
- lan743x_phy_link_status_change,
- PHY_INTERFACE_MODE_GMII);
- if (ret)
- goto return_error;
+ ret = phy_connect_direct(netdev, phydev,
+ lan743x_phy_link_status_change,
+ adapter->phy_mode);
+ if (ret)
+ goto return_error;
+ }
/* MAC doesn't support 1000T Half */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
@@ -1635,10 +1698,9 @@ static int lan743x_tx_napi_poll(struct napi_struct *napi, int weight)
bool start_transmitter = false;
unsigned long irq_flags = 0;
u32 ioc_bit = 0;
- u32 int_sts = 0;
ioc_bit = DMAC_INT_BIT_TX_IOC_(tx->channel_number);
- int_sts = lan743x_csr_read(adapter, DMAC_INT_STS);
+ lan743x_csr_read(adapter, DMAC_INT_STS);
if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C)
lan743x_csr_write(adapter, DMAC_INT_STS, ioc_bit);
spin_lock_irqsave(&tx->ring_lock, irq_flags);
@@ -1678,10 +1740,9 @@ done:
static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
{
if (tx->head_cpu_ptr) {
- pci_free_consistent(tx->adapter->pdev,
- sizeof(*tx->head_cpu_ptr),
- (void *)(tx->head_cpu_ptr),
- tx->head_dma_ptr);
+ dma_free_coherent(&tx->adapter->pdev->dev,
+ sizeof(*tx->head_cpu_ptr), tx->head_cpu_ptr,
+ tx->head_dma_ptr);
tx->head_cpu_ptr = NULL;
tx->head_dma_ptr = 0;
}
@@ -1689,10 +1750,9 @@ static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
tx->buffer_info = NULL;
if (tx->ring_cpu_ptr) {
- pci_free_consistent(tx->adapter->pdev,
- tx->ring_allocation_size,
- tx->ring_cpu_ptr,
- tx->ring_dma_ptr);
+ dma_free_coherent(&tx->adapter->pdev->dev,
+ tx->ring_allocation_size, tx->ring_cpu_ptr,
+ tx->ring_dma_ptr);
tx->ring_allocation_size = 0;
tx->ring_cpu_ptr = NULL;
tx->ring_dma_ptr = 0;
@@ -1716,8 +1776,8 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx)
sizeof(struct lan743x_tx_descriptor),
PAGE_SIZE);
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
- ring_allocation_size, &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&tx->adapter->pdev->dev,
+ ring_allocation_size, &dma_ptr, GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -1734,8 +1794,9 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx)
}
tx->buffer_info = (struct lan743x_tx_buffer_info *)cpu_ptr;
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
- sizeof(*tx->head_cpu_ptr), &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&tx->adapter->pdev->dev,
+ sizeof(*tx->head_cpu_ptr), &dma_ptr,
+ GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -1983,14 +2044,13 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
{
struct skb_shared_hwtstamps *hwtstamps = NULL;
int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
+ int current_head_index = *rx->head_cpu_ptr;
struct lan743x_rx_buffer_info *buffer_info;
struct lan743x_rx_descriptor *descriptor;
- int current_head_index = -1;
int extension_index = -1;
int first_index = -1;
int last_index = -1;
- current_head_index = *rx->head_cpu_ptr;
if (current_head_index < 0 || current_head_index >= rx->ring_size)
goto done;
@@ -2217,10 +2277,9 @@ static void lan743x_rx_ring_cleanup(struct lan743x_rx *rx)
}
if (rx->head_cpu_ptr) {
- pci_free_consistent(rx->adapter->pdev,
- sizeof(*rx->head_cpu_ptr),
- rx->head_cpu_ptr,
- rx->head_dma_ptr);
+ dma_free_coherent(&rx->adapter->pdev->dev,
+ sizeof(*rx->head_cpu_ptr), rx->head_cpu_ptr,
+ rx->head_dma_ptr);
rx->head_cpu_ptr = NULL;
rx->head_dma_ptr = 0;
}
@@ -2229,10 +2288,9 @@ static void lan743x_rx_ring_cleanup(struct lan743x_rx *rx)
rx->buffer_info = NULL;
if (rx->ring_cpu_ptr) {
- pci_free_consistent(rx->adapter->pdev,
- rx->ring_allocation_size,
- rx->ring_cpu_ptr,
- rx->ring_dma_ptr);
+ dma_free_coherent(&rx->adapter->pdev->dev,
+ rx->ring_allocation_size, rx->ring_cpu_ptr,
+ rx->ring_dma_ptr);
rx->ring_allocation_size = 0;
rx->ring_cpu_ptr = NULL;
rx->ring_dma_ptr = 0;
@@ -2263,8 +2321,8 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx)
sizeof(struct lan743x_rx_descriptor),
PAGE_SIZE);
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
- ring_allocation_size, &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&rx->adapter->pdev->dev,
+ ring_allocation_size, &dma_ptr, GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -2281,8 +2339,9 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx)
}
rx->buffer_info = (struct lan743x_rx_buffer_info *)cpu_ptr;
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
- sizeof(*rx->head_cpu_ptr), &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&rx->adapter->pdev->dev,
+ sizeof(*rx->head_cpu_ptr), &dma_ptr,
+ GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -2756,6 +2815,7 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
{
struct lan743x_adapter *adapter = NULL;
struct net_device *netdev = NULL;
+ const void *mac_addr;
int ret = -ENODEV;
netdev = devm_alloc_etherdev(&pdev->dev,
@@ -2772,6 +2832,10 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
+ mac_addr = of_get_mac_address(pdev->dev.of_node);
+ if (!IS_ERR(mac_addr))
+ ether_addr_copy(adapter->mac_address, mac_addr);
+
ret = lan743x_pci_init(adapter, pdev);
if (ret)
goto return_error;
@@ -2972,7 +3036,6 @@ static int lan743x_pm_suspend(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct lan743x_adapter *adapter = netdev_priv(netdev);
- int ret;
lan743x_pcidev_shutdown(pdev);
@@ -2985,9 +3048,7 @@ static int lan743x_pm_suspend(struct device *dev)
lan743x_pm_set_wol(adapter);
/* Host sets PME_En, put D3hot */
- ret = pci_prepare_to_sleep(pdev);
-
- return 0;
+ return pci_prepare_to_sleep(pdev);;
}
static int lan743x_pm_resume(struct device *dev)
@@ -3030,6 +3091,8 @@ static const struct pci_device_id lan743x_pcidev_tbl[] = {
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, lan743x_pcidev_tbl);
+
static struct pci_driver lan743x_pcidev_driver = {
.name = DRIVER_NAME,
.id_table = lan743x_pcidev_tbl,
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 3b02eeae5f45..c61a40411317 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -4,6 +4,7 @@
#ifndef _LAN743X_H
#define _LAN743X_H
+#include <linux/phy.h>
#include "lan743x_ptp.h"
#define DRIVER_AUTHOR "Bryan Whitehead <[email protected]>"
@@ -104,10 +105,14 @@
((value << 0) & FCT_FLOW_CTL_ON_THRESHOLD_)
#define MAC_CR (0x100)
+#define MAC_CR_MII_EN_ BIT(19)
#define MAC_CR_EEE_EN_ BIT(17)
#define MAC_CR_ADD_ BIT(12)
#define MAC_CR_ASD_ BIT(11)
#define MAC_CR_CNTR_RST_ BIT(5)
+#define MAC_CR_DPX_ BIT(3)
+#define MAC_CR_CFG_H_ BIT(2)
+#define MAC_CR_CFG_L_ BIT(1)
#define MAC_CR_RST_ BIT(0)
#define MAC_RX (0x104)
@@ -698,6 +703,7 @@ struct lan743x_rx {
struct lan743x_adapter {
struct net_device *netdev;
struct mii_bus *mdiobus;
+ phy_interface_t phy_mode;
int msg_enable;
#ifdef CONFIG_PM
u32 wolopts;
diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
index 9399f6a98748..ab6d719d40f0 100644
--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
@@ -2,12 +2,12 @@
/* Copyright (C) 2018 Microchip Technology Inc. */
#include <linux/netdevice.h>
-#include "lan743x_main.h"
#include <linux/ptp_clock_kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/net_tstamp.h>
+#include "lan743x_main.h"
#include "lan743x_ptp.h"