Skip to content

Commit

Permalink
net: txgbe: Add software nodes to support phylink
Browse files Browse the repository at this point in the history
Register software nodes for GPIO, I2C, SFP and PHYLINK. Define the
device properties.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Piotr Raczynski <piotr.raczynski@intel.com>
Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Jiawen Wu authored and Paolo Abeni committed Jun 8, 2023
1 parent 4a56212 commit c3e382a
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/net/ethernet/wangxun/libwx/wx_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,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
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
22 changes: 21 additions & 1 deletion drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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 @@ -516,6 +517,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 +682,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 +726,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 +753,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
89 changes: 89 additions & 0 deletions drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */

#include <linux/gpio/property.h>
#include <linux/i2c.h>
#include <linux/pci.h>

#include "../libwx/wx_type.h"
#include "txgbe_type.h"
#include "txgbe_phy.h"

static int txgbe_swnodes_register(struct txgbe *txgbe)
{
struct txgbe_nodes *nodes = &txgbe->nodes;
struct pci_dev *pdev = txgbe->wx->pdev;
struct software_node *swnodes;
u32 id;

id = (pdev->bus->number << 8) | pdev->devfn;

snprintf(nodes->gpio_name, sizeof(nodes->gpio_name), "txgbe_gpio-%x", id);
snprintf(nodes->i2c_name, sizeof(nodes->i2c_name), "txgbe_i2c-%x", id);
snprintf(nodes->sfp_name, sizeof(nodes->sfp_name), "txgbe_sfp-%x", id);
snprintf(nodes->phylink_name, sizeof(nodes->phylink_name), "txgbe_phylink-%x", id);

swnodes = nodes->swnodes;

/* GPIO 0: tx fault
* GPIO 1: tx disable
* GPIO 2: sfp module absent
* GPIO 3: rx signal lost
* GPIO 4: rate select, 1G(0) 10G(1)
* GPIO 5: rate select, 1G(0) 10G(1)
*/
nodes->gpio_props[0] = PROPERTY_ENTRY_STRING("pinctrl-names", "default");
swnodes[SWNODE_GPIO] = NODE_PROP(nodes->gpio_name, nodes->gpio_props);
nodes->gpio0_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 0, GPIO_ACTIVE_HIGH);
nodes->gpio1_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 1, GPIO_ACTIVE_HIGH);
nodes->gpio2_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 2, GPIO_ACTIVE_LOW);
nodes->gpio3_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 3, GPIO_ACTIVE_HIGH);
nodes->gpio4_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 4, GPIO_ACTIVE_HIGH);
nodes->gpio5_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 5, GPIO_ACTIVE_HIGH);

nodes->i2c_props[0] = PROPERTY_ENTRY_STRING("compatible", "snps,designware-i2c");
nodes->i2c_props[1] = PROPERTY_ENTRY_BOOL("wx,i2c-snps-model");
nodes->i2c_props[2] = PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ);
swnodes[SWNODE_I2C] = NODE_PROP(nodes->i2c_name, nodes->i2c_props);
nodes->i2c_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_I2C]);

nodes->sfp_props[0] = PROPERTY_ENTRY_STRING("compatible", "sff,sfp");
nodes->sfp_props[1] = PROPERTY_ENTRY_REF_ARRAY("i2c-bus", nodes->i2c_ref);
nodes->sfp_props[2] = PROPERTY_ENTRY_REF_ARRAY("tx-fault-gpios", nodes->gpio0_ref);
nodes->sfp_props[3] = PROPERTY_ENTRY_REF_ARRAY("tx-disable-gpios", nodes->gpio1_ref);
nodes->sfp_props[4] = PROPERTY_ENTRY_REF_ARRAY("mod-def0-gpios", nodes->gpio2_ref);
nodes->sfp_props[5] = PROPERTY_ENTRY_REF_ARRAY("los-gpios", nodes->gpio3_ref);
nodes->sfp_props[6] = PROPERTY_ENTRY_REF_ARRAY("rate-select1-gpios", nodes->gpio4_ref);
nodes->sfp_props[7] = PROPERTY_ENTRY_REF_ARRAY("rate-select0-gpios", nodes->gpio5_ref);
swnodes[SWNODE_SFP] = NODE_PROP(nodes->sfp_name, nodes->sfp_props);
nodes->sfp_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_SFP]);

nodes->phylink_props[0] = PROPERTY_ENTRY_STRING("managed", "in-band-status");
nodes->phylink_props[1] = PROPERTY_ENTRY_REF_ARRAY("sfp", nodes->sfp_ref);
swnodes[SWNODE_PHYLINK] = NODE_PROP(nodes->phylink_name, nodes->phylink_props);

nodes->group[SWNODE_GPIO] = &swnodes[SWNODE_GPIO];
nodes->group[SWNODE_I2C] = &swnodes[SWNODE_I2C];
nodes->group[SWNODE_SFP] = &swnodes[SWNODE_SFP];
nodes->group[SWNODE_PHYLINK] = &swnodes[SWNODE_PHYLINK];

return software_node_register_node_group(nodes->group);
}

int txgbe_init_phy(struct txgbe *txgbe)
{
int ret;

ret = txgbe_swnodes_register(txgbe);
if (ret) {
wx_err(txgbe->wx, "failed to register software nodes\n");
return ret;
}

return 0;
}

void txgbe_remove_phy(struct txgbe *txgbe)
{
software_node_unregister_node_group(txgbe->nodes.group);
}
10 changes: 10 additions & 0 deletions drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */

#ifndef _TXGBE_PHY_H_
#define _TXGBE_PHY_H_

int txgbe_init_phy(struct txgbe *txgbe);
void txgbe_remove_phy(struct txgbe *txgbe);

#endif /* _TXGBE_NODE_H_ */
49 changes: 49 additions & 0 deletions drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#ifndef _TXGBE_TYPE_H_
#define _TXGBE_TYPE_H_

#include <linux/property.h>

/* Device IDs */
#define TXGBE_DEV_ID_SP1000 0x1001
#define TXGBE_DEV_ID_WX1820 0x2001
Expand Down Expand Up @@ -100,4 +102,51 @@

extern char txgbe_driver_name[];

static inline struct txgbe *netdev_to_txgbe(struct net_device *netdev)
{
struct wx *wx = netdev_priv(netdev);

return wx->priv;
}

#define NODE_PROP(_NAME, _PROP) \
(const struct software_node) { \
.name = _NAME, \
.properties = _PROP, \
}

enum txgbe_swnodes {
SWNODE_GPIO = 0,
SWNODE_I2C,
SWNODE_SFP,
SWNODE_PHYLINK,
SWNODE_MAX
};

struct txgbe_nodes {
char gpio_name[32];
char i2c_name[32];
char sfp_name[32];
char phylink_name[32];
struct property_entry gpio_props[1];
struct property_entry i2c_props[3];
struct property_entry sfp_props[8];
struct property_entry phylink_props[2];
struct software_node_ref_args i2c_ref[1];
struct software_node_ref_args gpio0_ref[1];
struct software_node_ref_args gpio1_ref[1];
struct software_node_ref_args gpio2_ref[1];
struct software_node_ref_args gpio3_ref[1];
struct software_node_ref_args gpio4_ref[1];
struct software_node_ref_args gpio5_ref[1];
struct software_node_ref_args sfp_ref[1];
struct software_node swnodes[SWNODE_MAX];
const struct software_node *group[SWNODE_MAX + 1];
};

struct txgbe {
struct wx *wx;
struct txgbe_nodes nodes;
};

#endif /* _TXGBE_TYPE_H_ */

0 comments on commit c3e382a

Please sign in to comment.