diff options
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot_net.c')
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_net.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 8490e42e9e2d..b34da11acf65 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -330,7 +330,6 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) u8 grp = 0; /* Send everything on CPU group 0 */ unsigned int i, count, last; int port = priv->chip_port; - bool do_tstamp; val = ocelot_read(ocelot, QS_INJ_STATUS); if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) || @@ -345,7 +344,23 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) info.vid = skb_vlan_tag_get(skb); /* Check if timestamping is needed */ - do_tstamp = (ocelot_port_add_txtstamp_skb(ocelot_port, skb) == 0); + if (ocelot->ptp && (shinfo->tx_flags & SKBTX_HW_TSTAMP)) { + info.rew_op = ocelot_port->ptp_cmd; + + if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { + struct sk_buff *clone; + + clone = skb_clone_sk(skb); + if (!clone) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + + ocelot_port_add_txtstamp_skb(ocelot, port, clone); + + info.rew_op |= clone->cb[0] << 3; + } + } if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) { info.rew_op = ocelot_port->ptp_cmd; @@ -383,8 +398,7 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - if (!do_tstamp) - dev_kfree_skb_any(skb); + kfree_skb(skb); return NETDEV_TX_OK; } @@ -642,6 +656,37 @@ static const struct net_device_ops ocelot_port_netdev_ops = { .ndo_do_ioctl = ocelot_ioctl, }; +struct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port) +{ + struct ocelot_port *ocelot_port = ocelot->ports[port]; + struct ocelot_port_private *priv; + + if (!ocelot_port) + return NULL; + + priv = container_of(ocelot_port, struct ocelot_port_private, port); + + return priv->dev; +} + +/* Checks if the net_device instance given to us originates from our driver */ +static bool ocelot_netdevice_dev_check(const struct net_device *dev) +{ + return dev->netdev_ops == &ocelot_port_netdev_ops; +} + +int ocelot_netdev_to_port(struct net_device *dev) +{ + struct ocelot_port_private *priv; + + if (!dev || !ocelot_netdevice_dev_check(dev)) + return -EINVAL; + + priv = netdev_priv(dev); + + return priv->chip_port; +} + static void ocelot_port_get_strings(struct net_device *netdev, u32 sset, u8 *data) { @@ -746,7 +791,7 @@ static int ocelot_port_attr_set(struct net_device *dev, break; case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: ocelot_port_vlan_filtering(ocelot, port, - attr->u.vlan_filtering); + attr->u.vlan_filtering, trans); break; case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED: ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled); @@ -863,12 +908,6 @@ static int ocelot_port_obj_del(struct net_device *dev, return ret; } -/* Checks if the net_device instance given to us originate from our driver. */ -static bool ocelot_netdevice_dev_check(const struct net_device *dev) -{ - return dev->netdev_ops == &ocelot_port_netdev_ops; -} - static int ocelot_netdevice_port_event(struct net_device *dev, unsigned long event, struct netdev_notifier_changeupper_info *info) |