summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c')
-rw-r--r--drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
index b6c06adb8656..1b84d495d14e 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -159,7 +159,8 @@ static int txgbe_mdio_pcs_init(struct txgbe *txgbe)
static struct phylink_pcs *txgbe_phylink_mac_select(struct phylink_config *config,
phy_interface_t interface)
{
- struct txgbe *txgbe = netdev_to_txgbe(to_net_dev(config->dev));
+ struct wx *wx = phylink_to_wx(config);
+ struct txgbe *txgbe = wx->priv;
if (interface == PHY_INTERFACE_MODE_10GBASER)
return &txgbe->xpcs->pcs;
@@ -175,7 +176,7 @@ static void txgbe_mac_config(struct phylink_config *config, unsigned int mode,
static void txgbe_mac_link_down(struct phylink_config *config,
unsigned int mode, phy_interface_t interface)
{
- struct wx *wx = netdev_priv(to_net_dev(config->dev));
+ struct wx *wx = phylink_to_wx(config);
wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
}
@@ -186,9 +187,11 @@ static void txgbe_mac_link_up(struct phylink_config *config,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
- struct wx *wx = netdev_priv(to_net_dev(config->dev));
+ struct wx *wx = phylink_to_wx(config);
u32 txcfg, wdg;
+ wx_fc_enable(wx, tx_pause, rx_pause);
+
txcfg = rd32(wx, WX_MAC_TX_CFG);
txcfg &= ~WX_MAC_TX_CFG_SPEED_MASK;
@@ -217,7 +220,7 @@ static void txgbe_mac_link_up(struct phylink_config *config,
static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
- struct wx *wx = netdev_priv(to_net_dev(config->dev));
+ struct wx *wx = phylink_to_wx(config);
wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
@@ -228,7 +231,7 @@ static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode,
static int txgbe_mac_finish(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
- struct wx *wx = netdev_priv(to_net_dev(config->dev));
+ struct wx *wx = phylink_to_wx(config);
txgbe_enable_sec_tx_path(wx);
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
@@ -253,10 +256,7 @@ static int txgbe_phylink_init(struct txgbe *txgbe)
phy_interface_t phy_mode;
struct phylink *phylink;
- config = devm_kzalloc(&wx->pdev->dev, sizeof(*config), GFP_KERNEL);
- if (!config)
- return -ENOMEM;
-
+ config = &wx->phylink_config;
config->dev = &wx->netdev->dev;
config->type = PHYLINK_NETDEV;
config->mac_capabilities = MAC_10000FD | MAC_1000FD | MAC_100FD |
@@ -287,7 +287,7 @@ static int txgbe_phylink_init(struct txgbe *txgbe)
}
}
- txgbe->phylink = phylink;
+ wx->phylink = phylink;
return 0;
}
@@ -483,11 +483,11 @@ static void txgbe_irq_handler(struct irq_desc *desc)
TXGBE_PX_MISC_ETH_AN)) {
u32 reg = rd32(wx, TXGBE_CFG_PORT_ST);
- phylink_mac_change(txgbe->phylink, !!(reg & TXGBE_CFG_PORT_ST_LINK_UP));
+ phylink_mac_change(wx->phylink, !!(reg & TXGBE_CFG_PORT_ST_LINK_UP));
}
/* unmask interrupt */
- wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
+ wx_intr_enable(wx, TXGBE_INTR_MISC);
}
static int txgbe_gpio_init(struct txgbe *txgbe)
@@ -531,7 +531,12 @@ static int txgbe_gpio_init(struct txgbe *txgbe)
sizeof(*girq->parents), GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
- girq->parents[0] = wx->msix_entries[wx->num_q_vectors].vector;
+
+ /* now only suuported on MSI-X interrupt */
+ if (!wx->msix_entry)
+ return -EPERM;
+
+ girq->parents[0] = wx->msix_entry->vector;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
@@ -701,6 +706,7 @@ static int txgbe_ext_phy_init(struct txgbe *txgbe)
int txgbe_init_phy(struct txgbe *txgbe)
{
+ struct wx *wx = txgbe->wx;
int ret;
if (txgbe->wx->media_type == sp_media_copper)
@@ -708,46 +714,48 @@ int txgbe_init_phy(struct txgbe *txgbe)
ret = txgbe_swnodes_register(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to register software nodes\n");
+ wx_err(wx, "failed to register software nodes\n");
return ret;
}
ret = txgbe_mdio_pcs_init(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to init mdio pcs: %d\n", ret);
+ wx_err(wx, "failed to init mdio pcs: %d\n", ret);
goto err_unregister_swnode;
}
ret = txgbe_phylink_init(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to init phylink\n");
+ wx_err(wx, "failed to init phylink\n");
goto err_destroy_xpcs;
}
ret = txgbe_gpio_init(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to init gpio\n");
+ wx_err(wx, "failed to init gpio\n");
goto err_destroy_phylink;
}
ret = txgbe_clock_register(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to register clock: %d\n", ret);
+ wx_err(wx, "failed to register clock: %d\n", ret);
goto err_destroy_phylink;
}
ret = txgbe_i2c_register(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to init i2c interface: %d\n", ret);
+ wx_err(wx, "failed to init i2c interface: %d\n", ret);
goto err_unregister_clk;
}
ret = txgbe_sfp_register(txgbe);
if (ret) {
- wx_err(txgbe->wx, "failed to register sfp\n");
+ wx_err(wx, "failed to register sfp\n");
goto err_unregister_i2c;
}
+ wx->msix_in_use = true;
+
return 0;
err_unregister_i2c:
@@ -756,7 +764,7 @@ err_unregister_clk:
clkdev_drop(txgbe->clock);
clk_unregister(txgbe->clk);
err_destroy_phylink:
- phylink_destroy(txgbe->phylink);
+ phylink_destroy(wx->phylink);
err_destroy_xpcs:
xpcs_destroy(txgbe->xpcs);
err_unregister_swnode:
@@ -768,8 +776,8 @@ err_unregister_swnode:
void txgbe_remove_phy(struct txgbe *txgbe)
{
if (txgbe->wx->media_type == sp_media_copper) {
- phylink_disconnect_phy(txgbe->phylink);
- phylink_destroy(txgbe->phylink);
+ phylink_disconnect_phy(txgbe->wx->phylink);
+ phylink_destroy(txgbe->wx->phylink);
return;
}
@@ -777,7 +785,8 @@ void txgbe_remove_phy(struct txgbe *txgbe)
platform_device_unregister(txgbe->i2c_dev);
clkdev_drop(txgbe->clock);
clk_unregister(txgbe->clk);
- phylink_destroy(txgbe->phylink);
+ phylink_destroy(txgbe->wx->phylink);
xpcs_destroy(txgbe->xpcs);
software_node_unregister_node_group(txgbe->nodes.group);
+ txgbe->wx->msix_in_use = false;
}