Skip to content

Commit 7e89350

Browse files
committed
Merge branch 'dpaa2-switch-next'
Ioana Ciornei says: ==================== dpaa2-switch: integrate the MAC endpoint support This patch set integrates the already available MAC support into the dpaa2-switch driver as well. The first 4 patches are fixing up some minor problems or optimizing the code, while the remaining ones are actually integrating the dpaa2-mac support into the switch driver by calling the dpaa2_mac_* provided functions. While at it, we also export the MAC statistics in ethtool like we do for dpaa2-eth. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b820c11 + f0653a8 commit 7e89350

File tree

8 files changed

+177
-64
lines changed

8 files changed

+177
-64
lines changed

drivers/bus/fsl-mc/fsl-mc-bus.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
914914
}
915915
EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
916916

917-
struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev)
917+
struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
918+
u16 if_id)
918919
{
919920
struct fsl_mc_device *mc_bus_dev, *endpoint;
920921
struct fsl_mc_obj_desc endpoint_desc = {{ 0 }};
@@ -925,6 +926,7 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev)
925926
mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
926927
strcpy(endpoint1.type, mc_dev->obj_desc.type);
927928
endpoint1.id = mc_dev->obj_desc.id;
929+
endpoint1.if_id = if_id;
928930

929931
err = dprc_get_connection(mc_bus_dev->mc_io, 0,
930932
mc_bus_dev->mc_handle,

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-eth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4138,7 +4138,7 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
41384138
int err;
41394139

41404140
dpni_dev = to_fsl_mc_device(priv->net_dev->dev.parent);
4141-
dpmac_dev = fsl_mc_get_endpoint(dpni_dev);
4141+
dpmac_dev = fsl_mc_get_endpoint(dpni_dev, 0);
41424142

41434143
if (PTR_ERR(dpmac_dev) == -EPROBE_DEFER)
41444144
return PTR_ERR(dpmac_dev);

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

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ static struct {
1515
enum dpsw_counter id;
1616
char name[ETH_GSTRING_LEN];
1717
} dpaa2_switch_ethtool_counters[] = {
18-
{DPSW_CNT_ING_FRAME, "rx frames"},
19-
{DPSW_CNT_ING_BYTE, "rx bytes"},
20-
{DPSW_CNT_ING_FLTR_FRAME, "rx filtered frames"},
21-
{DPSW_CNT_ING_FRAME_DISCARD, "rx discarded frames"},
22-
{DPSW_CNT_ING_BCAST_FRAME, "rx b-cast frames"},
23-
{DPSW_CNT_ING_BCAST_BYTES, "rx b-cast bytes"},
24-
{DPSW_CNT_ING_MCAST_FRAME, "rx m-cast frames"},
25-
{DPSW_CNT_ING_MCAST_BYTE, "rx m-cast bytes"},
26-
{DPSW_CNT_EGR_FRAME, "tx frames"},
27-
{DPSW_CNT_EGR_BYTE, "tx bytes"},
28-
{DPSW_CNT_EGR_FRAME_DISCARD, "tx discarded frames"},
29-
{DPSW_CNT_ING_NO_BUFF_DISCARD, "rx discarded no buffer frames"},
18+
{DPSW_CNT_ING_FRAME, "[hw] rx frames"},
19+
{DPSW_CNT_ING_BYTE, "[hw] rx bytes"},
20+
{DPSW_CNT_ING_FLTR_FRAME, "[hw] rx filtered frames"},
21+
{DPSW_CNT_ING_FRAME_DISCARD, "[hw] rx discarded frames"},
22+
{DPSW_CNT_ING_BCAST_FRAME, "[hw] rx bcast frames"},
23+
{DPSW_CNT_ING_BCAST_BYTES, "[hw] rx bcast bytes"},
24+
{DPSW_CNT_ING_MCAST_FRAME, "[hw] rx mcast frames"},
25+
{DPSW_CNT_ING_MCAST_BYTE, "[hw] rx mcast bytes"},
26+
{DPSW_CNT_EGR_FRAME, "[hw] tx frames"},
27+
{DPSW_CNT_EGR_BYTE, "[hw] tx bytes"},
28+
{DPSW_CNT_EGR_FRAME_DISCARD, "[hw] tx discarded frames"},
29+
{DPSW_CNT_ING_NO_BUFF_DISCARD, "[hw] rx nobuffer discards"},
3030
};
3131

3232
#define DPAA2_SWITCH_NUM_COUNTERS ARRAY_SIZE(dpaa2_switch_ethtool_counters)
@@ -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) {
@@ -134,11 +142,17 @@ dpaa2_switch_set_link_ksettings(struct net_device *netdev,
134142
return err;
135143
}
136144

137-
static int dpaa2_switch_ethtool_get_sset_count(struct net_device *dev, int sset)
145+
static int
146+
dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
138147
{
148+
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
149+
int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;
150+
139151
switch (sset) {
140152
case ETH_SS_STATS:
141-
return DPAA2_SWITCH_NUM_COUNTERS;
153+
if (port_priv->mac)
154+
num_ss_stats += dpaa2_mac_get_sset_count();
155+
return num_ss_stats;
142156
default:
143157
return -EOPNOTSUPP;
144158
}
@@ -147,14 +161,19 @@ static int dpaa2_switch_ethtool_get_sset_count(struct net_device *dev, int sset)
147161
static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
148162
u32 stringset, u8 *data)
149163
{
164+
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
165+
u8 *p = data;
150166
int i;
151167

152168
switch (stringset) {
153169
case ETH_SS_STATS:
154-
for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++)
155-
memcpy(data + i * ETH_GSTRING_LEN,
156-
dpaa2_switch_ethtool_counters[i].name,
170+
for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) {
171+
memcpy(p, dpaa2_switch_ethtool_counters[i].name,
157172
ETH_GSTRING_LEN);
173+
p += ETH_GSTRING_LEN;
174+
}
175+
if (port_priv->mac)
176+
dpaa2_mac_get_strings(p);
158177
break;
159178
}
160179
}
@@ -176,6 +195,9 @@ static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev,
176195
netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n",
177196
dpaa2_switch_ethtool_counters[i].name, err);
178197
}
198+
199+
if (port_priv->mac)
200+
dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
179201
}
180202

181203
const struct ethtool_ops dpaa2_switch_port_ethtool_ops = {

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

Lines changed: 108 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -594,12 +594,18 @@ static int dpaa2_switch_port_change_mtu(struct net_device *netdev, int mtu)
594594
return 0;
595595
}
596596

597-
static int dpaa2_switch_port_carrier_state_sync(struct net_device *netdev)
597+
static int dpaa2_switch_port_link_state_update(struct net_device *netdev)
598598
{
599599
struct ethsw_port_priv *port_priv = netdev_priv(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,
@@ -692,23 +700,12 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
692700
return err;
693701
}
694702

695-
/* sync carrier state */
696-
err = dpaa2_switch_port_carrier_state_sync(netdev);
697-
if (err) {
698-
netdev_err(netdev,
699-
"dpaa2_switch_port_carrier_state_sync err %d\n", err);
700-
goto err_carrier_sync;
701-
}
702-
703703
dpaa2_switch_enable_ctrl_if_napi(ethsw);
704704

705-
return 0;
705+
if (dpaa2_switch_port_is_type_phy(port_priv))
706+
phylink_start(port_priv->mac->phylink);
706707

707-
err_carrier_sync:
708-
dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
709-
port_priv->ethsw_data->dpsw_handle,
710-
port_priv->idx);
711-
return err;
708+
return 0;
712709
}
713710

714711
static int dpaa2_switch_port_stop(struct net_device *netdev)
@@ -717,6 +714,13 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
717714
struct ethsw_core *ethsw = port_priv->ethsw_data;
718715
int err;
719716

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+
720724
err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
721725
port_priv->ethsw_data->dpsw_handle,
722726
port_priv->idx);
@@ -1419,41 +1423,103 @@ bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
14191423
return netdev->netdev_ops == &dpaa2_switch_port_ops;
14201424
}
14211425

1422-
static void dpaa2_switch_links_state_update(struct ethsw_core *ethsw)
1426+
static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
14231427
{
1424-
int i;
1428+
struct fsl_mc_device *dpsw_port_dev, *dpmac_dev;
1429+
struct dpaa2_mac *mac;
1430+
int err;
14251431

1426-
for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
1427-
dpaa2_switch_port_carrier_state_sync(ethsw->ports[i]->netdev);
1428-
dpaa2_switch_port_set_mac_addr(ethsw->ports[i]);
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+
}
14291462
}
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;
14301485
}
14311486

14321487
static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
14331488
{
14341489
struct device *dev = (struct device *)arg;
14351490
struct ethsw_core *ethsw = dev_get_drvdata(dev);
1436-
1437-
/* Mask the events and the if_id reserved bits to be cleared on read */
1438-
u32 status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
1439-
int err;
1491+
struct ethsw_port_priv *port_priv;
1492+
u32 status = ~0;
1493+
int err, if_id;
14401494

14411495
err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
14421496
DPSW_IRQ_INDEX_IF, &status);
14431497
if (err) {
14441498
dev_err(dev, "Can't get irq status (err %d)\n", err);
1445-
1446-
err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
1447-
DPSW_IRQ_INDEX_IF, 0xFFFFFFFF);
1448-
if (err)
1449-
dev_err(dev, "Can't clear irq status (err %d)\n", err);
14501499
goto out;
14511500
}
14521501

1453-
if (status & DPSW_IRQ_EVENT_LINK_CHANGED)
1454-
dpaa2_switch_links_state_update(ethsw);
1502+
if_id = (status & 0xFFFF0000) >> 16;
1503+
port_priv = ethsw->ports[if_id];
1504+
1505+
if (status & DPSW_IRQ_EVENT_LINK_CHANGED) {
1506+
dpaa2_switch_port_link_state_update(port_priv->netdev);
1507+
dpaa2_switch_port_set_mac_addr(port_priv);
1508+
}
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+
}
14551516

14561517
out:
1518+
err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
1519+
DPSW_IRQ_INDEX_IF, status);
1520+
if (err)
1521+
dev_err(dev, "Can't clear irq status (err %d)\n", err);
1522+
14571523
return IRQ_HANDLED;
14581524
}
14591525

@@ -3133,6 +3199,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev)
31333199
for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
31343200
port_priv = ethsw->ports[i];
31353201
unregister_netdev(port_priv->netdev);
3202+
dpaa2_switch_port_disconnect_mac(port_priv);
31363203
free_netdev(port_priv->netdev);
31373204
}
31383205

@@ -3212,6 +3279,10 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
32123279
goto err_port_probe;
32133280
port_priv->learn_ena = false;
32143281

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

32173288
err_port_probe:
@@ -3288,12 +3359,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev)
32883359
&ethsw->fq[i].napi, dpaa2_switch_poll,
32893360
NAPI_POLL_WEIGHT);
32903361

3291-
err = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle);
3292-
if (err) {
3293-
dev_err(ethsw->dev, "dpsw_enable err %d\n", err);
3294-
goto err_free_netdev;
3295-
}
3296-
32973362
/* Setup IRQs */
32983363
err = dpaa2_switch_setup_irqs(sw_dev);
32993364
if (err)

0 commit comments

Comments
 (0)