Skip to content

Commit 84cba72

Browse files
IoanaCiorneidavem330
authored andcommitted
dpaa2-switch: integrate the MAC endpoint support
Integrate the common MAC endpoint management support into the dpaa2-switch driver as well. Nothing special happens here, just that the already available dpaa2-mac functions are also called from dpaa2-switch. Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 27cfdad commit 84cba72

File tree

5 files changed

+130
-7
lines changed

5 files changed

+130
-7
lines changed

drivers/net/ethernet/freescale/dpaa2/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o dpaa2-mac.o dpmac.o dpa
1111
fsl-dpaa2-eth-${CONFIG_FSL_DPAA2_ETH_DCB} += dpaa2-eth-dcb.o
1212
fsl-dpaa2-eth-${CONFIG_DEBUG_FS} += dpaa2-eth-debugfs.o
1313
fsl-dpaa2-ptp-objs := dpaa2-ptp.o dprtc.o
14-
fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o dpaa2-switch-flower.o
14+
fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o dpaa2-switch-flower.o dpaa2-mac.o dpmac.o
1515

1616
# Needed by the tracing framework
1717
CFLAGS_dpaa2-eth.o := -I$(src)

drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ dpaa2_switch_get_link_ksettings(struct net_device *netdev,
6262
struct dpsw_link_state state = {0};
6363
int err = 0;
6464

65+
if (dpaa2_switch_port_is_type_phy(port_priv))
66+
return phylink_ethtool_ksettings_get(port_priv->mac->phylink,
67+
link_ksettings);
68+
6569
err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
6670
port_priv->ethsw_data->dpsw_handle,
6771
port_priv->idx,
@@ -95,6 +99,10 @@ dpaa2_switch_set_link_ksettings(struct net_device *netdev,
9599
bool if_running;
96100
int err = 0, ret;
97101

102+
if (dpaa2_switch_port_is_type_phy(port_priv))
103+
return phylink_ethtool_ksettings_set(port_priv->mac->phylink,
104+
link_ksettings);
105+
98106
/* Interface needs to be down to change link settings */
99107
if_running = netif_running(netdev);
100108
if (if_running) {

drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,12 @@ static int dpaa2_switch_port_link_state_update(struct net_device *netdev)
600600
struct dpsw_link_state state;
601601
int err;
602602

603+
/* When we manage the MAC/PHY using phylink there is no need
604+
* to manually update the netif_carrier.
605+
*/
606+
if (dpaa2_switch_port_is_type_phy(port_priv))
607+
return 0;
608+
603609
/* Interrupts are received even though no one issued an 'ifconfig up'
604610
* on the switch interface. Ignore these link state update interrupts
605611
*/
@@ -677,12 +683,14 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
677683
struct ethsw_core *ethsw = port_priv->ethsw_data;
678684
int err;
679685

680-
/* Explicitly set carrier off, otherwise
681-
* netif_carrier_ok() will return true and cause 'ip link show'
682-
* to report the LOWER_UP flag, even though the link
683-
* notification wasn't even received.
684-
*/
685-
netif_carrier_off(netdev);
686+
if (!dpaa2_switch_port_is_type_phy(port_priv)) {
687+
/* Explicitly set carrier off, otherwise
688+
* netif_carrier_ok() will return true and cause 'ip link show'
689+
* to report the LOWER_UP flag, even though the link
690+
* notification wasn't even received.
691+
*/
692+
netif_carrier_off(netdev);
693+
}
686694

687695
err = dpsw_if_enable(port_priv->ethsw_data->mc_io, 0,
688696
port_priv->ethsw_data->dpsw_handle,
@@ -694,6 +702,9 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
694702

695703
dpaa2_switch_enable_ctrl_if_napi(ethsw);
696704

705+
if (dpaa2_switch_port_is_type_phy(port_priv))
706+
phylink_start(port_priv->mac->phylink);
707+
697708
return 0;
698709
}
699710

@@ -703,6 +714,13 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
703714
struct ethsw_core *ethsw = port_priv->ethsw_data;
704715
int err;
705716

717+
if (dpaa2_switch_port_is_type_phy(port_priv)) {
718+
phylink_stop(port_priv->mac->phylink);
719+
} else {
720+
netif_tx_stop_all_queues(netdev);
721+
netif_carrier_off(netdev);
722+
}
723+
706724
err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
707725
port_priv->ethsw_data->dpsw_handle,
708726
port_priv->idx);
@@ -1405,6 +1423,67 @@ bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
14051423
return netdev->netdev_ops == &dpaa2_switch_port_ops;
14061424
}
14071425

1426+
static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
1427+
{
1428+
struct fsl_mc_device *dpsw_port_dev, *dpmac_dev;
1429+
struct dpaa2_mac *mac;
1430+
int err;
1431+
1432+
dpsw_port_dev = to_fsl_mc_device(port_priv->netdev->dev.parent);
1433+
dpmac_dev = fsl_mc_get_endpoint(dpsw_port_dev, port_priv->idx);
1434+
1435+
if (PTR_ERR(dpmac_dev) == -EPROBE_DEFER)
1436+
return PTR_ERR(dpmac_dev);
1437+
1438+
if (IS_ERR(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type)
1439+
return 0;
1440+
1441+
mac = kzalloc(sizeof(*mac), GFP_KERNEL);
1442+
if (!mac)
1443+
return -ENOMEM;
1444+
1445+
mac->mc_dev = dpmac_dev;
1446+
mac->mc_io = port_priv->ethsw_data->mc_io;
1447+
mac->net_dev = port_priv->netdev;
1448+
1449+
err = dpaa2_mac_open(mac);
1450+
if (err)
1451+
goto err_free_mac;
1452+
port_priv->mac = mac;
1453+
1454+
if (dpaa2_switch_port_is_type_phy(port_priv)) {
1455+
err = dpaa2_mac_connect(mac);
1456+
if (err) {
1457+
netdev_err(port_priv->netdev,
1458+
"Error connecting to the MAC endpoint %pe\n",
1459+
ERR_PTR(err));
1460+
goto err_close_mac;
1461+
}
1462+
}
1463+
1464+
return 0;
1465+
1466+
err_close_mac:
1467+
dpaa2_mac_close(mac);
1468+
port_priv->mac = NULL;
1469+
err_free_mac:
1470+
kfree(mac);
1471+
return err;
1472+
}
1473+
1474+
static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
1475+
{
1476+
if (dpaa2_switch_port_is_type_phy(port_priv))
1477+
dpaa2_mac_disconnect(port_priv->mac);
1478+
1479+
if (!dpaa2_switch_port_has_mac(port_priv))
1480+
return;
1481+
1482+
dpaa2_mac_close(port_priv->mac);
1483+
kfree(port_priv->mac);
1484+
port_priv->mac = NULL;
1485+
}
1486+
14081487
static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
14091488
{
14101489
struct device *dev = (struct device *)arg;
@@ -1427,6 +1506,14 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
14271506
dpaa2_switch_port_link_state_update(port_priv->netdev);
14281507
dpaa2_switch_port_set_mac_addr(port_priv);
14291508
}
1509+
1510+
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
1511+
if (dpaa2_switch_port_has_mac(port_priv))
1512+
dpaa2_switch_port_disconnect_mac(port_priv);
1513+
else
1514+
dpaa2_switch_port_connect_mac(port_priv);
1515+
}
1516+
14301517
out:
14311518
err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
14321519
DPSW_IRQ_INDEX_IF, status);
@@ -3112,6 +3199,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev)
31123199
for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
31133200
port_priv = ethsw->ports[i];
31143201
unregister_netdev(port_priv->netdev);
3202+
dpaa2_switch_port_disconnect_mac(port_priv);
31153203
free_netdev(port_priv->netdev);
31163204
}
31173205

@@ -3191,6 +3279,10 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
31913279
goto err_port_probe;
31923280
port_priv->learn_ena = false;
31933281

3282+
err = dpaa2_switch_port_connect_mac(port_priv);
3283+
if (err)
3284+
goto err_port_probe;
3285+
31943286
return 0;
31953287

31963288
err_port_probe:

drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <net/pkt_cls.h>
2222
#include <soc/fsl/dpaa2-io.h>
2323

24+
#include "dpaa2-mac.h"
2425
#include "dpsw.h"
2526

2627
/* Number of IRQs supported */
@@ -159,6 +160,7 @@ struct ethsw_port_priv {
159160
bool learn_ena;
160161

161162
struct dpaa2_switch_filter_block *filter_block;
163+
struct dpaa2_mac *mac;
162164
};
163165

164166
/* Switch data */
@@ -225,6 +227,22 @@ static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
225227
return true;
226228
}
227229

230+
static inline bool
231+
dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
232+
{
233+
if (port_priv->mac &&
234+
(port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
235+
port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
236+
return true;
237+
238+
return false;
239+
}
240+
241+
static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
242+
{
243+
return port_priv->mac ? true : false;
244+
}
245+
228246
bool dpaa2_switch_port_dev_check(const struct net_device *netdev);
229247

230248
int dpaa2_switch_port_vlans_add(struct net_device *netdev,

drivers/net/ethernet/freescale/dpaa2/dpsw.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ int dpsw_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token);
9898
*/
9999
#define DPSW_IRQ_EVENT_LINK_CHANGED 0x0001
100100

101+
/**
102+
* DPSW_IRQ_EVENT_ENDPOINT_CHANGED - Indicates a change in endpoint
103+
*/
104+
#define DPSW_IRQ_EVENT_ENDPOINT_CHANGED 0x0002
105+
101106
/**
102107
* struct dpsw_irq_cfg - IRQ configuration
103108
* @addr: Address that must be written to signal a message-based interrupt

0 commit comments

Comments
 (0)