Skip to content

Commit

Permalink
Merge branch 'txgbe-phylink-support'
Browse files Browse the repository at this point in the history
Jiawen Wu says:

====================
TXGBE PHYLINK support

Implement I2C, SFP, GPIO and PHYLINK to setup TXGBE link.

Because our I2C and PCS are based on Synopsys Designware IP-core, extend
the i2c-designware and pcs-xpcs driver to realize our functions.
====================

Link: https://lore.kernel.org/r/20230606092107.764621-1-jiawenwu@trustnetic.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Paolo Abeni committed Jun 8, 2023
2 parents 4a56212 + 08f08f9 commit b62d9e2
Show file tree
Hide file tree
Showing 11 changed files with 881 additions and 33 deletions.
10 changes: 10 additions & 0 deletions drivers/net/ethernet/wangxun/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ config NGBE
config TXGBE
tristate "Wangxun(R) 10GbE PCI Express adapters support"
depends on PCI
depends on COMMON_CLK
select REGMAP
select I2C
select I2C_DESIGNWARE_PLATFORM
select PHYLINK
select HWMON if TXGBE=y
select SFP
select GPIOLIB
select GPIOLIB_IRQCHIP
select PCS_XPCS
select LIBWX
help
This driver supports Wangxun(R) 10GbE PCI Express family of
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/wangxun/libwx/wx_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2048,7 +2048,8 @@ void wx_free_irq(struct wx *wx)
free_irq(entry->vector, q_vector);
}

free_irq(wx->msix_entries[vector].vector, wx);
if (wx->mac.type == wx_mac_em)
free_irq(wx->msix_entries[vector].vector, wx);
}
EXPORT_SYMBOL(wx_free_irq);

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/wangxun/libwx/wx_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@
#define WX_GPIO_INTMASK 0x14834
#define WX_GPIO_INTTYPE_LEVEL 0x14838
#define WX_GPIO_POLARITY 0x1483C
#define WX_GPIO_INTSTATUS 0x14844
#define WX_GPIO_EOI 0x1484C
#define WX_GPIO_EXT 0x14850

/*********************** Transmit DMA registers **************************/
/* transmit global control */
Expand Down Expand Up @@ -814,6 +816,7 @@ enum wx_isb_idx {
struct wx {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];

void *priv;
u8 __iomem *hw_addr;
struct pci_dev *pdev;
struct net_device *netdev;
Expand Down Expand Up @@ -846,6 +849,7 @@ struct wx {
bool wol_enabled;
bool ncsi_enabled;
bool gpio_ctrl;
raw_spinlock_t gpio_lock;

/* Tx fast path data */
int num_tx_queues;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/wangxun/txgbe/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ obj-$(CONFIG_TXGBE) += txgbe.o

txgbe-objs := txgbe_main.o \
txgbe_hw.o \
txgbe_phy.o \
txgbe_ethtool.o
28 changes: 28 additions & 0 deletions drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,39 @@
#include <linux/netdevice.h>

#include "../libwx/wx_ethtool.h"
#include "../libwx/wx_type.h"
#include "txgbe_type.h"
#include "txgbe_ethtool.h"

static int txgbe_nway_reset(struct net_device *netdev)
{
struct txgbe *txgbe = netdev_to_txgbe(netdev);

return phylink_ethtool_nway_reset(txgbe->phylink);
}

static int txgbe_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct txgbe *txgbe = netdev_to_txgbe(netdev);

return phylink_ethtool_ksettings_get(txgbe->phylink, cmd);
}

static int txgbe_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
struct txgbe *txgbe = netdev_to_txgbe(netdev);

return phylink_ethtool_ksettings_set(txgbe->phylink, cmd);
}

static const struct ethtool_ops txgbe_ethtool_ops = {
.get_drvinfo = wx_get_drvinfo,
.nway_reset = txgbe_nway_reset,
.get_link = ethtool_op_get_link,
.get_link_ksettings = txgbe_get_link_ksettings,
.set_link_ksettings = txgbe_set_link_ksettings,
};

void txgbe_set_ethtool_ops(struct net_device *netdev)
Expand Down
65 changes: 33 additions & 32 deletions drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/netdevice.h>
#include <linux/string.h>
#include <linux/etherdevice.h>
#include <linux/phylink.h>
#include <net/ip.h>
#include <linux/if_vlan.h>

Expand All @@ -15,6 +16,7 @@
#include "../libwx/wx_hw.h"
#include "txgbe_type.h"
#include "txgbe_hw.h"
#include "txgbe_phy.h"
#include "txgbe_ethtool.h"

char txgbe_driver_name[] = "txgbe";
Expand Down Expand Up @@ -81,6 +83,8 @@ static int txgbe_enumerate_functions(struct wx *wx)
**/
static void txgbe_irq_enable(struct wx *wx, bool queues)
{
wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK);

/* unmask interrupt */
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
if (queues)
Expand Down Expand Up @@ -128,17 +132,6 @@ static irqreturn_t txgbe_intr(int __always_unused irq, void *data)
return IRQ_HANDLED;
}

static irqreturn_t txgbe_msix_other(int __always_unused irq, void *data)
{
struct wx *wx = data;

/* re-enable the original interrupt state */
if (netif_running(wx->netdev))
txgbe_irq_enable(wx, false);

return IRQ_HANDLED;
}

/**
* txgbe_request_msix_irqs - Initialize MSI-X interrupts
* @wx: board private structure
Expand Down Expand Up @@ -170,13 +163,6 @@ static int txgbe_request_msix_irqs(struct wx *wx)
}
}

err = request_irq(wx->msix_entries[vector].vector,
txgbe_msix_other, 0, netdev->name, wx);
if (err) {
wx_err(wx, "request_irq for msix_other failed: %d\n", err);
goto free_queue_irqs;
}

return 0;

free_queue_irqs:
Expand Down Expand Up @@ -219,7 +205,8 @@ static int txgbe_request_irq(struct wx *wx)

static void txgbe_up_complete(struct wx *wx)
{
u32 reg;
struct net_device *netdev = wx->netdev;
struct txgbe *txgbe;

wx_control_hw(wx, true);
wx_configure_vectors(wx);
Expand All @@ -228,24 +215,17 @@ static void txgbe_up_complete(struct wx *wx)
smp_mb__before_atomic();
wx_napi_enable_all(wx);

txgbe = netdev_to_txgbe(netdev);
phylink_start(txgbe->phylink);

/* clear any pending interrupts, may auto mask */
rd32(wx, WX_PX_IC(0));
rd32(wx, WX_PX_IC(1));
rd32(wx, WX_PX_MISC_IC);
txgbe_irq_enable(wx, true);

/* Configure MAC Rx and Tx when link is up */
reg = rd32(wx, WX_MAC_RX_CFG);
wr32(wx, WX_MAC_RX_CFG, reg);
wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR);
reg = rd32(wx, WX_MAC_WDG_TIMEOUT);
wr32(wx, WX_MAC_WDG_TIMEOUT, reg);
reg = rd32(wx, WX_MAC_TX_CFG);
wr32(wx, WX_MAC_TX_CFG, (reg & ~WX_MAC_TX_CFG_SPEED_MASK) | WX_MAC_TX_CFG_SPEED_10G);

/* enable transmits */
netif_tx_start_all_queues(wx->netdev);
netif_carrier_on(wx->netdev);
netif_tx_start_all_queues(netdev);
}

static void txgbe_reset(struct wx *wx)
Expand Down Expand Up @@ -280,7 +260,6 @@ static void txgbe_disable_device(struct wx *wx)
wx_disable_rx_queue(wx, wx->rx_ring[i]);

netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);
netif_tx_disable(netdev);

wx_irq_disable(wx);
Expand Down Expand Up @@ -311,8 +290,11 @@ static void txgbe_disable_device(struct wx *wx)

static void txgbe_down(struct wx *wx)
{
struct txgbe *txgbe = netdev_to_txgbe(wx->netdev);

txgbe_disable_device(wx);
txgbe_reset(wx);
phylink_stop(txgbe->phylink);

wx_clean_all_tx_rings(wx);
wx_clean_all_rx_rings(wx);
Expand Down Expand Up @@ -516,6 +498,7 @@ static int txgbe_probe(struct pci_dev *pdev,
struct net_device *netdev;
int err, expected_gts;
struct wx *wx = NULL;
struct txgbe *txgbe;

u16 eeprom_verh = 0, eeprom_verl = 0, offset = 0;
u16 eeprom_cfg_blkh = 0, eeprom_cfg_blkl = 0;
Expand Down Expand Up @@ -680,10 +663,23 @@ static int txgbe_probe(struct pci_dev *pdev,
"0x%08x", etrack_id);
}

err = register_netdev(netdev);
txgbe = devm_kzalloc(&pdev->dev, sizeof(*txgbe), GFP_KERNEL);
if (!txgbe) {
err = -ENOMEM;
goto err_release_hw;
}

txgbe->wx = wx;
wx->priv = txgbe;

err = txgbe_init_phy(txgbe);
if (err)
goto err_release_hw;

err = register_netdev(netdev);
if (err)
goto err_remove_phy;

pci_set_drvdata(pdev, wx);

netif_tx_stop_all_queues(netdev);
Expand Down Expand Up @@ -711,6 +707,8 @@ static int txgbe_probe(struct pci_dev *pdev,

return 0;

err_remove_phy:
txgbe_remove_phy(txgbe);
err_release_hw:
wx_clear_interrupt_scheme(wx);
wx_control_hw(wx, false);
Expand All @@ -736,11 +734,14 @@ static int txgbe_probe(struct pci_dev *pdev,
static void txgbe_remove(struct pci_dev *pdev)
{
struct wx *wx = pci_get_drvdata(pdev);
struct txgbe *txgbe = wx->priv;
struct net_device *netdev;

netdev = wx->netdev;
unregister_netdev(netdev);

txgbe_remove_phy(txgbe);

pci_release_selected_regions(pdev,
pci_select_bars(pdev, IORESOURCE_MEM));

Expand Down
Loading

0 comments on commit b62d9e2

Please sign in to comment.