Merge tag 'mac80211-for-net-2020-09-21' of git://git.kernel.org/pub/scm/linux/kernel...
authorDavid S. Miller <davem@davemloft.net>
Mon, 21 Sep 2020 21:54:35 +0000 (14:54 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 21 Sep 2020 21:54:35 +0000 (14:54 -0700)
Johannes Berg says:

====================
Just a few fixes:
 * fix using HE on 2.4 GHz
 * AQL (airtime queue limit) estimation & VHT160 fix
 * do not oversize A-MPDUs if local capability is smaller than peer's
 * fix radiotap on 6 GHz to not put 2.4 GHz flag
 * fix Kconfig for lib80211
 * little fixlet for 6 GHz channel number / frequency conversion
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
27 files changed:
MAINTAINERS
drivers/net/dsa/ocelot/felix.c
drivers/net/dsa/ocelot/seville_vsc9953.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
drivers/net/ethernet/huawei/hinic/hinic_tx.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/mscc/ocelot_vsc7514.c
drivers/net/ethernet/sfc/ef100.c
include/net/sctp/structs.h
include/soc/mscc/ocelot.h
lib/test_rhashtable.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/bridge_loop_avoidance.h
net/batman-adv/multicast.c
net/batman-adv/multicast.h
net/batman-adv/routing.c
net/batman-adv/soft-interface.c
net/dsa/tag_ocelot.c
net/ipv6/Kconfig
net/ipv6/route.c
net/sctp/socket.c

index 923c69a..ad9a35b 100644 (file)
@@ -8331,7 +8331,7 @@ F:        arch/powerpc/platforms/powernv/copy-paste.h
 F:     arch/powerpc/platforms/powernv/vas*
 
 IBM Power Virtual Ethernet Device Driver
-M:     Thomas Falcon <tlfalcon@linux.ibm.com>
+M:     Cristobal Forno <cforno12@linux.ibm.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/ibm/ibmveth.*
index 04bfa6e..01427cd 100644 (file)
@@ -585,7 +585,10 @@ static int felix_setup(struct dsa_switch *ds)
        if (err)
                return err;
 
-       ocelot_init(ocelot);
+       err = ocelot_init(ocelot);
+       if (err)
+               return err;
+
        if (ocelot->ptp) {
                err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
                if (err) {
@@ -640,10 +643,13 @@ static void felix_teardown(struct dsa_switch *ds)
 {
        struct ocelot *ocelot = ds->priv;
        struct felix *felix = ocelot_to_felix(ocelot);
+       int port;
 
        if (felix->info->mdio_bus_free)
                felix->info->mdio_bus_free(ocelot);
 
+       for (port = 0; port < ocelot->num_phys_ports; port++)
+               ocelot_deinit_port(ocelot, port);
        ocelot_deinit_timestamp(ocelot);
        /* stop workqueue thread */
        ocelot_deinit(ocelot);
index 625b189..0fdeff2 100644 (file)
@@ -1008,7 +1008,7 @@ static const struct felix_info seville_info_vsc9953 = {
        .vcap_is2_keys          = vsc9953_vcap_is2_keys,
        .vcap_is2_actions       = vsc9953_vcap_is2_actions,
        .vcap                   = vsc9953_vcap_props,
-       .shared_queue_sz        = 128 * 1024,
+       .shared_queue_sz        = 2048 * 1024,
        .num_mact_rows          = 2048,
        .num_ports              = 10,
        .mdio_bus_alloc         = vsc9953_mdio_bus_alloc,
index 8eb73fe..7b7e8b7 100644 (file)
@@ -3782,6 +3782,7 @@ static int bnxt_hwrm_func_qstat_ext(struct bnxt *bp,
                return -EOPNOTSUPP;
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QSTATS_EXT, -1, -1);
+       req.fid = cpu_to_le16(0xffff);
        req.flags = FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK;
        mutex_lock(&bp->hwrm_cmd_lock);
        rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
@@ -3852,7 +3853,7 @@ static void bnxt_init_stats(struct bnxt *bp)
                tx_masks = stats->hw_masks;
                tx_count = sizeof(struct tx_port_stats_ext) / 8;
 
-               flags = FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK;
+               flags = PORT_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK;
                rc = bnxt_hwrm_port_qstats_ext(bp, flags);
                if (rc) {
                        mask = (1ULL << 40) - 1;
@@ -9311,18 +9312,16 @@ static ssize_t bnxt_show_temp(struct device *dev,
        struct hwrm_temp_monitor_query_output *resp;
        struct bnxt *bp = dev_get_drvdata(dev);
        u32 len = 0;
+       int rc;
 
        resp = bp->hwrm_cmd_resp_addr;
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1);
        mutex_lock(&bp->hwrm_cmd_lock);
-       if (!_hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT))
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (!rc)
                len = sprintf(buf, "%u\n", resp->temp * 1000); /* display millidegree */
        mutex_unlock(&bp->hwrm_cmd_lock);
-
-       if (len)
-               return len;
-
-       return sprintf(buf, "unknown\n");
+       return rc ?: len;
 }
 static SENSOR_DEVICE_ATTR(temp1_input, 0444, bnxt_show_temp, NULL, 0);
 
@@ -9342,7 +9341,16 @@ static void bnxt_hwmon_close(struct bnxt *bp)
 
 static void bnxt_hwmon_open(struct bnxt *bp)
 {
+       struct hwrm_temp_monitor_query_input req = {0};
        struct pci_dev *pdev = bp->pdev;
+       int rc;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1);
+       rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (rc == -EACCES || rc == -EOPNOTSUPP) {
+               bnxt_hwmon_close(bp);
+               return;
+       }
 
        if (bp->hwmon_dev)
                return;
@@ -12090,7 +12098,7 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
 static void bnxt_vpd_read_info(struct bnxt *bp)
 {
        struct pci_dev *pdev = bp->pdev;
-       int i, len, pos, ro_size;
+       int i, len, pos, ro_size, size;
        ssize_t vpd_size;
        u8 *vpd_data;
 
@@ -12125,7 +12133,8 @@ static void bnxt_vpd_read_info(struct bnxt *bp)
        if (len + pos > vpd_size)
                goto read_sn;
 
-       strlcpy(bp->board_partno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN));
+       size = min(len, BNXT_VPD_FLD_LEN - 1);
+       memcpy(bp->board_partno, &vpd_data[pos], size);
 
 read_sn:
        pos = pci_vpd_find_info_keyword(vpd_data, i, ro_size,
@@ -12138,7 +12147,8 @@ read_sn:
        if (len + pos > vpd_size)
                goto exit;
 
-       strlcpy(bp->board_serialno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN));
+       size = min(len, BNXT_VPD_FLD_LEN - 1);
+       memcpy(bp->board_serialno, &vpd_data[pos], size);
 exit:
        kfree(vpd_data);
 }
index d092833..fecdfd8 100644 (file)
@@ -1322,6 +1322,9 @@ static int bnxt_get_regs_len(struct net_device *dev)
        struct bnxt *bp = netdev_priv(dev);
        int reg_len;
 
+       if (!BNXT_PF(bp))
+               return -EOPNOTSUPP;
+
        reg_len = BNXT_PXP_REG_LEN;
 
        if (bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED)
@@ -1788,9 +1791,12 @@ static int bnxt_set_pauseparam(struct net_device *dev,
        if (!BNXT_PHY_CFG_ABLE(bp))
                return -EOPNOTSUPP;
 
+       mutex_lock(&bp->link_lock);
        if (epause->autoneg) {
-               if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
-                       return -EINVAL;
+               if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
+                       rc = -EINVAL;
+                       goto pause_exit;
+               }
 
                link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
                if (bp->hwrm_spec_code >= 0x10201)
@@ -1811,11 +1817,11 @@ static int bnxt_set_pauseparam(struct net_device *dev,
        if (epause->tx_pause)
                link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX;
 
-       if (netif_running(dev)) {
-               mutex_lock(&bp->link_lock);
+       if (netif_running(dev))
                rc = bnxt_hwrm_set_pause(bp);
-               mutex_unlock(&bp->link_lock);
-       }
+
+pause_exit:
+       mutex_unlock(&bp->link_lock);
        return rc;
 }
 
@@ -2552,8 +2558,7 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_eee *edata)
        struct bnxt *bp = netdev_priv(dev);
        struct ethtool_eee *eee = &bp->eee;
        struct bnxt_link_info *link_info = &bp->link_info;
-       u32 advertising =
-                _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0);
+       u32 advertising;
        int rc = 0;
 
        if (!BNXT_PHY_CFG_ABLE(bp))
@@ -2562,19 +2567,23 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_eee *edata)
        if (!(bp->flags & BNXT_FLAG_EEE_CAP))
                return -EOPNOTSUPP;
 
+       mutex_lock(&bp->link_lock);
+       advertising = _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0);
        if (!edata->eee_enabled)
                goto eee_ok;
 
        if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
                netdev_warn(dev, "EEE requires autoneg\n");
-               return -EINVAL;
+               rc = -EINVAL;
+               goto eee_exit;
        }
        if (edata->tx_lpi_enabled) {
                if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi ||
                                       edata->tx_lpi_timer < bp->lpi_tmr_lo)) {
                        netdev_warn(dev, "Valid LPI timer range is %d and %d microsecs\n",
                                    bp->lpi_tmr_lo, bp->lpi_tmr_hi);
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto eee_exit;
                } else if (!bp->lpi_tmr_hi) {
                        edata->tx_lpi_timer = eee->tx_lpi_timer;
                }
@@ -2584,7 +2593,8 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_eee *edata)
        } else if (edata->advertised & ~advertising) {
                netdev_warn(dev, "EEE advertised %x must be a subset of autoneg advertised speeds %x\n",
                            edata->advertised, advertising);
-               return -EINVAL;
+               rc = -EINVAL;
+               goto eee_exit;
        }
 
        eee->advertised = edata->advertised;
@@ -2596,6 +2606,8 @@ eee_ok:
        if (netif_running(dev))
                rc = bnxt_hwrm_set_link_setting(bp, false, true);
 
+eee_exit:
+       mutex_unlock(&bp->link_lock);
        return rc;
 }
 
index 3ea51dd..a24b20f 100644 (file)
@@ -66,8 +66,8 @@ struct dpmac_cmd_get_counter {
 };
 
 struct dpmac_rsp_get_counter {
-       u64 pad;
-       u64 counter;
+       __le64 pad;
+       __le64 counter;
 };
 
 #endif /* _FSL_DPMAC_CMD_H */
index ed3829a..a769273 100644 (file)
@@ -334,7 +334,7 @@ static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
  * bit6-11 for ppe0-5
  * bit12-17 for roce0-5
  * bit18-19 for com/dfx
- * @enable: false - request reset , true - drop reset
+ * @dereset: false - request reset , true - drop reset
  */
 static void
 hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
@@ -357,7 +357,7 @@ hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
  * bit6-11 for ppe0-5
  * bit12-17 for roce0-5
  * bit18-19 for com/dfx
- * @enable: false - request reset , true - drop reset
+ * @dereset: false - request reset , true - drop reset
  */
 static void
 hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
index 6bb65ad..c340d9a 100644 (file)
@@ -1654,6 +1654,7 @@ static void hinic_diag_test(struct net_device *netdev,
        }
 
        netif_carrier_off(netdev);
+       netif_tx_disable(netdev);
 
        err = do_lp_test(nic_dev, eth_test->flags, LP_DEFAULT_TIME,
                         &test_index);
@@ -1662,9 +1663,12 @@ static void hinic_diag_test(struct net_device *netdev,
                data[test_index] = 1;
        }
 
+       netif_tx_wake_all_queues(netdev);
+
        err = hinic_port_link_state(nic_dev, &link_state);
        if (!err && link_state == HINIC_LINK_STATE_UP)
                netif_carrier_on(netdev);
+
 }
 
 static int hinic_set_phys_id(struct net_device *netdev,
index 2b418b5..c1f81e9 100644 (file)
@@ -717,8 +717,8 @@ static int free_tx_poll(struct napi_struct *napi, int budget)
                netdev_txq = netdev_get_tx_queue(txq->netdev, qp->q_id);
 
                __netif_tx_lock(netdev_txq, smp_processor_id());
-
-               netif_wake_subqueue(nic_dev->netdev, qp->q_id);
+               if (!netif_testing(nic_dev->netdev))
+                       netif_wake_subqueue(nic_dev->netdev, qp->q_id);
 
                __netif_tx_unlock(netdev_txq);
 
index 69a9000..c4345e3 100644 (file)
@@ -2383,8 +2383,12 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                        mvneta_swbm_rx_frame(pp, rx_desc, rxq, &xdp_buf,
                                             &size, page, &ps);
                } else {
-                       if (unlikely(!xdp_buf.data_hard_start))
+                       if (unlikely(!xdp_buf.data_hard_start)) {
+                               rx_desc->buf_phys_addr = 0;
+                               page_pool_put_full_page(rxq->page_pool, page,
+                                                       true);
                                continue;
+                       }
 
                        mvneta_swbm_add_rx_fragment(pp, rx_desc, rxq, &xdp_buf,
                                                    &size, page);
index 5abb7d2..8518e1d 100644 (file)
@@ -421,10 +421,15 @@ int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
 
        if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
            ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
+               spin_lock(&ocelot_port->ts_id_lock);
+
                shinfo->tx_flags |= SKBTX_IN_PROGRESS;
                /* Store timestamp ID in cb[0] of sk_buff */
-               skb->cb[0] = ocelot_port->ts_id % 4;
+               skb->cb[0] = ocelot_port->ts_id;
+               ocelot_port->ts_id = (ocelot_port->ts_id + 1) % 4;
                skb_queue_tail(&ocelot_port->tx_skbs, skb);
+
+               spin_unlock(&ocelot_port->ts_id_lock);
                return 0;
        }
        return -ENODATA;
@@ -1300,6 +1305,7 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
        struct ocelot_port *ocelot_port = ocelot->ports[port];
 
        skb_queue_head_init(&ocelot_port->tx_skbs);
+       spin_lock_init(&ocelot_port->ts_id_lock);
 
        /* Basic L2 initialization */
 
@@ -1544,18 +1550,18 @@ EXPORT_SYMBOL(ocelot_init);
 
 void ocelot_deinit(struct ocelot *ocelot)
 {
-       struct ocelot_port *port;
-       int i;
-
        cancel_delayed_work(&ocelot->stats_work);
        destroy_workqueue(ocelot->stats_queue);
        mutex_destroy(&ocelot->stats_lock);
-
-       for (i = 0; i < ocelot->num_phys_ports; i++) {
-               port = ocelot->ports[i];
-               skb_queue_purge(&port->tx_skbs);
-       }
 }
 EXPORT_SYMBOL(ocelot_deinit);
 
+void ocelot_deinit_port(struct ocelot *ocelot, int port)
+{
+       struct ocelot_port *ocelot_port = ocelot->ports[port];
+
+       skb_queue_purge(&ocelot_port->tx_skbs);
+}
+EXPORT_SYMBOL(ocelot_deinit_port);
+
 MODULE_LICENSE("Dual MIT/GPL");
index 0668d23..8490e42 100644 (file)
@@ -330,6 +330,7 @@ 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))) ||
@@ -344,10 +345,12 @@ 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)
-                       info.rew_op |= (ocelot_port->ts_id  % 4) << 3;
+                       info.rew_op |= skb->cb[0] << 3;
        }
 
        ocelot_gen_ifh(ifh, &info);
@@ -380,12 +383,9 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
-       if (!ocelot_port_add_txtstamp_skb(ocelot_port, skb)) {
-               ocelot_port->ts_id++;
-               return NETDEV_TX_OK;
-       }
+       if (!do_tstamp)
+               dev_kfree_skb_any(skb);
 
-       dev_kfree_skb_any(skb);
        return NETDEV_TX_OK;
 }
 
index 65408bc..e02fb8b 100644 (file)
@@ -896,11 +896,137 @@ static struct ptp_clock_info ocelot_ptp_clock_info = {
        .enable         = ocelot_ptp_enable,
 };
 
+static void mscc_ocelot_release_ports(struct ocelot *ocelot)
+{
+       int port;
+
+       for (port = 0; port < ocelot->num_phys_ports; port++) {
+               struct ocelot_port_private *priv;
+               struct ocelot_port *ocelot_port;
+
+               ocelot_port = ocelot->ports[port];
+               if (!ocelot_port)
+                       continue;
+
+               ocelot_deinit_port(ocelot, port);
+
+               priv = container_of(ocelot_port, struct ocelot_port_private,
+                                   port);
+
+               unregister_netdev(priv->dev);
+               free_netdev(priv->dev);
+       }
+}
+
+static int mscc_ocelot_init_ports(struct platform_device *pdev,
+                                 struct device_node *ports)
+{
+       struct ocelot *ocelot = platform_get_drvdata(pdev);
+       struct device_node *portnp;
+       int err;
+
+       ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
+                                    sizeof(struct ocelot_port *), GFP_KERNEL);
+       if (!ocelot->ports)
+               return -ENOMEM;
+
+       /* No NPI port */
+       ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
+                            OCELOT_TAG_PREFIX_NONE);
+
+       for_each_available_child_of_node(ports, portnp) {
+               struct ocelot_port_private *priv;
+               struct ocelot_port *ocelot_port;
+               struct device_node *phy_node;
+               phy_interface_t phy_mode;
+               struct phy_device *phy;
+               struct regmap *target;
+               struct resource *res;
+               struct phy *serdes;
+               char res_name[8];
+               u32 port;
+
+               if (of_property_read_u32(portnp, "reg", &port))
+                       continue;
+
+               snprintf(res_name, sizeof(res_name), "port%d", port);
+
+               res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                  res_name);
+               target = ocelot_regmap_init(ocelot, res);
+               if (IS_ERR(target))
+                       continue;
+
+               phy_node = of_parse_phandle(portnp, "phy-handle", 0);
+               if (!phy_node)
+                       continue;
+
+               phy = of_phy_find_device(phy_node);
+               of_node_put(phy_node);
+               if (!phy)
+                       continue;
+
+               err = ocelot_probe_port(ocelot, port, target, phy);
+               if (err) {
+                       of_node_put(portnp);
+                       return err;
+               }
+
+               ocelot_port = ocelot->ports[port];
+               priv = container_of(ocelot_port, struct ocelot_port_private,
+                                   port);
+
+               of_get_phy_mode(portnp, &phy_mode);
+
+               ocelot_port->phy_mode = phy_mode;
+
+               switch (ocelot_port->phy_mode) {
+               case PHY_INTERFACE_MODE_NA:
+                       continue;
+               case PHY_INTERFACE_MODE_SGMII:
+                       break;
+               case PHY_INTERFACE_MODE_QSGMII:
+                       /* Ensure clock signals and speed is set on all
+                        * QSGMII links
+                        */
+                       ocelot_port_writel(ocelot_port,
+                                          DEV_CLOCK_CFG_LINK_SPEED
+                                          (OCELOT_SPEED_1000),
+                                          DEV_CLOCK_CFG);
+                       break;
+               default:
+                       dev_err(ocelot->dev,
+                               "invalid phy mode for port%d, (Q)SGMII only\n",
+                               port);
+                       of_node_put(portnp);
+                       return -EINVAL;
+               }
+
+               serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
+               if (IS_ERR(serdes)) {
+                       err = PTR_ERR(serdes);
+                       if (err == -EPROBE_DEFER)
+                               dev_dbg(ocelot->dev, "deferring probe\n");
+                       else
+                               dev_err(ocelot->dev,
+                                       "missing SerDes phys for port%d\n",
+                                       port);
+
+                       of_node_put(portnp);
+                       return err;
+               }
+
+               priv->serdes = serdes;
+       }
+
+       return 0;
+}
+
 static int mscc_ocelot_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
-       struct device_node *ports, *portnp;
        int err, irq_xtr, irq_ptp_rdy;
+       struct device_node *ports;
        struct ocelot *ocelot;
        struct regmap *hsio;
        unsigned int i;
@@ -985,20 +1111,24 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 
        ports = of_get_child_by_name(np, "ethernet-ports");
        if (!ports) {
-               dev_err(&pdev->dev, "no ethernet-ports child node found\n");
+               dev_err(ocelot->dev, "no ethernet-ports child node found\n");
                return -ENODEV;
        }
 
        ocelot->num_phys_ports = of_get_child_count(ports);
 
-       ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
-                                    sizeof(struct ocelot_port *), GFP_KERNEL);
-
        ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
        ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
        ocelot->vcap = vsc7514_vcap_props;
 
-       ocelot_init(ocelot);
+       err = ocelot_init(ocelot);
+       if (err)
+               goto out_put_ports;
+
+       err = mscc_ocelot_init_ports(pdev, ports);
+       if (err)
+               goto out_put_ports;
+
        if (ocelot->ptp) {
                err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
                if (err) {
@@ -1008,96 +1138,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
                }
        }
 
-       /* No NPI port */
-       ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
-                            OCELOT_TAG_PREFIX_NONE);
-
-       for_each_available_child_of_node(ports, portnp) {
-               struct ocelot_port_private *priv;
-               struct ocelot_port *ocelot_port;
-               struct device_node *phy_node;
-               phy_interface_t phy_mode;
-               struct phy_device *phy;
-               struct regmap *target;
-               struct resource *res;
-               struct phy *serdes;
-               char res_name[8];
-               u32 port;
-
-               if (of_property_read_u32(portnp, "reg", &port))
-                       continue;
-
-               snprintf(res_name, sizeof(res_name), "port%d", port);
-
-               res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-                                                  res_name);
-               target = ocelot_regmap_init(ocelot, res);
-               if (IS_ERR(target))
-                       continue;
-
-               phy_node = of_parse_phandle(portnp, "phy-handle", 0);
-               if (!phy_node)
-                       continue;
-
-               phy = of_phy_find_device(phy_node);
-               of_node_put(phy_node);
-               if (!phy)
-                       continue;
-
-               err = ocelot_probe_port(ocelot, port, target, phy);
-               if (err) {
-                       of_node_put(portnp);
-                       goto out_put_ports;
-               }
-
-               ocelot_port = ocelot->ports[port];
-               priv = container_of(ocelot_port, struct ocelot_port_private,
-                                   port);
-
-               of_get_phy_mode(portnp, &phy_mode);
-
-               ocelot_port->phy_mode = phy_mode;
-
-               switch (ocelot_port->phy_mode) {
-               case PHY_INTERFACE_MODE_NA:
-                       continue;
-               case PHY_INTERFACE_MODE_SGMII:
-                       break;
-               case PHY_INTERFACE_MODE_QSGMII:
-                       /* Ensure clock signals and speed is set on all
-                        * QSGMII links
-                        */
-                       ocelot_port_writel(ocelot_port,
-                                          DEV_CLOCK_CFG_LINK_SPEED
-                                          (OCELOT_SPEED_1000),
-                                          DEV_CLOCK_CFG);
-                       break;
-               default:
-                       dev_err(ocelot->dev,
-                               "invalid phy mode for port%d, (Q)SGMII only\n",
-                               port);
-                       of_node_put(portnp);
-                       err = -EINVAL;
-                       goto out_put_ports;
-               }
-
-               serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
-               if (IS_ERR(serdes)) {
-                       err = PTR_ERR(serdes);
-                       if (err == -EPROBE_DEFER)
-                               dev_dbg(ocelot->dev, "deferring probe\n");
-                       else
-                               dev_err(ocelot->dev,
-                                       "missing SerDes phys for port%d\n",
-                                       port);
-
-                       of_node_put(portnp);
-                       goto out_put_ports;
-               }
-
-               priv->serdes = serdes;
-       }
-
        register_netdevice_notifier(&ocelot_netdevice_nb);
        register_switchdev_notifier(&ocelot_switchdev_nb);
        register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
@@ -1114,6 +1154,7 @@ static int mscc_ocelot_remove(struct platform_device *pdev)
        struct ocelot *ocelot = platform_get_drvdata(pdev);
 
        ocelot_deinit_timestamp(ocelot);
+       mscc_ocelot_release_ports(ocelot);
        ocelot_deinit(ocelot);
        unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
        unregister_switchdev_notifier(&ocelot_switchdev_nb);
index c54b7f8..ffdb367 100644 (file)
@@ -490,6 +490,7 @@ static int ef100_pci_probe(struct pci_dev *pci_dev,
        if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) {
                netif_err(efx, probe, efx->net_dev,
                          "Func control window overruns BAR\n");
+               rc = -EIO;
                goto fail;
        }
 
index b33f1ae..0bdff38 100644 (file)
@@ -226,12 +226,14 @@ struct sctp_sock {
                data_ready_signalled:1;
 
        atomic_t pd_mode;
+
+       /* Fields after this point will be skipped on copies, like on accept
+        * and peeloff operations
+        */
+
        /* Receive to here while partial delivery is in effect. */
        struct sk_buff_head pd_lobby;
 
-       /* These must be the last fields, as they will skipped on copies,
-        * like on accept and peeloff operations
-        */
        struct list_head auto_asconf_list;
        int do_auto_asconf;
 };
index da369b1..0ac4e7f 100644 (file)
@@ -566,6 +566,7 @@ struct ocelot_port {
        u8                              ptp_cmd;
        struct sk_buff_head             tx_skbs;
        u8                              ts_id;
+       spinlock_t                      ts_id_lock;
 
        phy_interface_t                 phy_mode;
 
@@ -677,6 +678,7 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
 int ocelot_init(struct ocelot *ocelot);
 void ocelot_deinit(struct ocelot *ocelot);
 void ocelot_init_port(struct ocelot *ocelot, int port);
+void ocelot_deinit_port(struct ocelot *ocelot, int port);
 
 /* DSA callbacks */
 void ocelot_port_enable(struct ocelot *ocelot, int port,
index c5a6fef..76c607e 100644 (file)
@@ -434,7 +434,7 @@ static int __init test_rhltable(unsigned int entries)
                } else {
                        if (WARN(err != -ENOENT, "removed non-existent element, error %d not %d",
                                 err, -ENOENT))
-                       continue;
+                               continue;
                }
        }
 
index 8500f56..c350ab6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/lockdep.h>
 #include <linux/netdevice.h>
 #include <linux/netlink.h>
+#include <linux/preempt.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
 #include <linux/seq_file.h>
@@ -83,11 +84,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
  */
 static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
 {
-       const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
+       const struct batadv_bla_backbone_gw *gw;
        u32 hash = 0;
 
-       hash = jhash(&claim->addr, sizeof(claim->addr), hash);
-       hash = jhash(&claim->vid, sizeof(claim->vid), hash);
+       gw = (struct batadv_bla_backbone_gw *)data;
+       hash = jhash(&gw->orig, sizeof(gw->orig), hash);
+       hash = jhash(&gw->vid, sizeof(gw->vid), hash);
 
        return hash % size;
 }
@@ -1579,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
 }
 
 /**
- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
+ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
  * @bat_priv: the bat priv with all the soft interface information
- * @skb: contains the bcast_packet to be checked
+ * @skb: contains the multicast packet to be checked
+ * @payload_ptr: pointer to position inside the head buffer of the skb
+ *  marking the start of the data to be CRC'ed
+ * @orig: originator mac address, NULL if unknown
  *
- * check if it is on our broadcast list. Another gateway might
- * have sent the same packet because it is connected to the same backbone,
- * so we have to remove this duplicate.
+ * Check if it is on our broadcast list. Another gateway might have sent the
+ * same packet because it is connected to the same backbone, so we have to
+ * remove this duplicate.
  *
  * This is performed by checking the CRC, which will tell us
  * with a good chance that it is the same packet. If it is furthermore
@@ -1594,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
  *
  * Return: true if a packet is in the duplicate list, false otherwise.
  */
-bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
-                                   struct sk_buff *skb)
+static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
+                                    struct sk_buff *skb, u8 *payload_ptr,
+                                    const u8 *orig)
 {
-       int i, curr;
-       __be32 crc;
-       struct batadv_bcast_packet *bcast_packet;
        struct batadv_bcast_duplist_entry *entry;
        bool ret = false;
-
-       bcast_packet = (struct batadv_bcast_packet *)skb->data;
+       int i, curr;
+       __be32 crc;
 
        /* calculate the crc ... */
-       crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
+       crc = batadv_skb_crc32(skb, payload_ptr);
 
        spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
 
@@ -1625,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
                if (entry->crc != crc)
                        continue;
 
-               if (batadv_compare_eth(entry->orig, bcast_packet->orig))
-                       continue;
+               /* are the originators both known and not anonymous? */
+               if (orig && !is_zero_ether_addr(orig) &&
+                   !is_zero_ether_addr(entry->orig)) {
+                       /* If known, check if the new frame came from
+                        * the same originator:
+                        * We are safe to take identical frames from the
+                        * same orig, if known, as multiplications in
+                        * the mesh are detected via the (orig, seqno) pair.
+                        * So we can be a bit more liberal here and allow
+                        * identical frames from the same orig which the source
+                        * host might have sent multiple times on purpose.
+                        */
+                       if (batadv_compare_eth(entry->orig, orig))
+                               continue;
+               }
 
                /* this entry seems to match: same crc, not too old,
                 * and from another gw. therefore return true to forbid it.
@@ -1642,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
        entry = &bat_priv->bla.bcast_duplist[curr];
        entry->crc = crc;
        entry->entrytime = jiffies;
-       ether_addr_copy(entry->orig, bcast_packet->orig);
+
+       /* known originator */
+       if (orig)
+               ether_addr_copy(entry->orig, orig);
+       /* anonymous originator */
+       else
+               eth_zero_addr(entry->orig);
+
        bat_priv->bla.bcast_duplist_curr = curr;
 
 out:
@@ -1652,6 +1675,48 @@ out:
 }
 
 /**
+ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: contains the multicast packet to be checked, decapsulated from a
+ *  unicast_packet
+ *
+ * Check if it is on our broadcast list. Another gateway might have sent the
+ * same packet because it is connected to the same backbone, so we have to
+ * remove this duplicate.
+ *
+ * Return: true if a packet is in the duplicate list, false otherwise.
+ */
+static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
+                                          struct sk_buff *skb)
+{
+       return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
+}
+
+/**
+ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: contains the bcast_packet to be checked
+ *
+ * Check if it is on our broadcast list. Another gateway might have sent the
+ * same packet because it is connected to the same backbone, so we have to
+ * remove this duplicate.
+ *
+ * Return: true if a packet is in the duplicate list, false otherwise.
+ */
+bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+                                   struct sk_buff *skb)
+{
+       struct batadv_bcast_packet *bcast_packet;
+       u8 *payload_ptr;
+
+       bcast_packet = (struct batadv_bcast_packet *)skb->data;
+       payload_ptr = (u8 *)(bcast_packet + 1);
+
+       return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
+                                       bcast_packet->orig);
+}
+
+/**
  * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
  *  the VLAN identified by vid.
  * @bat_priv: the bat priv with all the soft interface information
@@ -1812,7 +1877,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: the frame to be checked
  * @vid: the VLAN ID of the frame
- * @is_bcast: the packet came in a broadcast packet type.
+ * @packet_type: the batman packet type this frame came in
  *
  * batadv_bla_rx avoidance checks if:
  *  * we have to race for a claim
@@ -1824,7 +1889,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
  * further process the skb.
  */
 bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
-                  unsigned short vid, bool is_bcast)
+                  unsigned short vid, int packet_type)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
        struct ethhdr *ethhdr;
@@ -1846,9 +1911,32 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                goto handled;
 
        if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
-               /* don't allow broadcasts while requests are in flight */
-               if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
-                       goto handled;
+               /* don't allow multicast packets while requests are in flight */
+               if (is_multicast_ether_addr(ethhdr->h_dest))
+                       /* Both broadcast flooding or multicast-via-unicasts
+                        * delivery might send to multiple backbone gateways
+                        * sharing the same LAN and therefore need to coordinate
+                        * which backbone gateway forwards into the LAN,
+                        * by claiming the payload source address.
+                        *
+                        * Broadcast flooding and multicast-via-unicasts
+                        * delivery use the following two batman packet types.
+                        * Note: explicitly exclude BATADV_UNICAST_4ADDR,
+                        * as the DHCP gateway feature will send explicitly
+                        * to only one BLA gateway, so the claiming process
+                        * should be avoided there.
+                        */
+                       if (packet_type == BATADV_BCAST ||
+                           packet_type == BATADV_UNICAST)
+                               goto handled;
+
+       /* potential duplicates from foreign BLA backbone gateways via
+        * multicast-in-unicast packets
+        */
+       if (is_multicast_ether_addr(ethhdr->h_dest) &&
+           packet_type == BATADV_UNICAST &&
+           batadv_bla_check_ucast_duplist(bat_priv, skb))
+               goto handled;
 
        ether_addr_copy(search_claim.addr, ethhdr->h_source);
        search_claim.vid = vid;
@@ -1883,13 +1971,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                goto allow;
        }
 
-       /* if it is a broadcast ... */
-       if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
+       /* if it is a multicast ... */
+       if (is_multicast_ether_addr(ethhdr->h_dest) &&
+           (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
                /* ... drop it. the responsible gateway is in charge.
                 *
-                * We need to check is_bcast because with the gateway
+                * We need to check packet type because with the gateway
                 * feature, broadcasts (like DHCP requests) may be sent
-                * using a unicast packet type.
+                * using a unicast 4 address packet type. See comment above.
                 */
                goto handled;
        } else {
index 41edb2c..a81c41b 100644 (file)
@@ -35,7 +35,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
 
 #ifdef CONFIG_BATMAN_ADV_BLA
 bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
-                  unsigned short vid, bool is_bcast);
+                  unsigned short vid, int packet_type);
 bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                   unsigned short vid);
 bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
@@ -66,7 +66,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
 
 static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
                                 struct sk_buff *skb, unsigned short vid,
-                                bool is_bcast)
+                                int packet_type)
 {
        return false;
 }
index bdc4a1f..ca24a2e 100644 (file)
@@ -51,6 +51,7 @@
 #include <uapi/linux/batadv_packet.h>
 #include <uapi/linux/batman_adv.h>
 
+#include "bridge_loop_avoidance.h"
 #include "hard-interface.h"
 #include "hash.h"
 #include "log.h"
@@ -1435,6 +1436,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
 }
 
 /**
+ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the multicast packet to send
+ * @vid: the vlan identifier
+ * @orig_node: the originator to send the packet to
+ *
+ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
+ */
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
+                               struct sk_buff *skb,
+                               unsigned short vid,
+                               struct batadv_orig_node *orig_node)
+{
+       /* Avoid sending multicast-in-unicast packets to other BLA
+        * gateways - they already got the frame from the LAN side
+        * we share with them.
+        * TODO: Refactor to take BLA into account earlier, to avoid
+        * reducing the mcast_fanout count.
+        */
+       if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
+               dev_kfree_skb(skb);
+               return NET_XMIT_SUCCESS;
+       }
+
+       return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
+                                      orig_node, vid);
+}
+
+/**
  * batadv_mcast_forw_tt() - forwards a packet to multicast listeners
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: the multicast packet to transmit
@@ -1471,8 +1501,8 @@ batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
                        break;
                }
 
-               batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
-                                       orig_entry->orig_node, vid);
+               batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
+                                           orig_entry->orig_node);
        }
        rcu_read_unlock();
 
@@ -1513,8 +1543,7 @@ batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
                        break;
                }
 
-               batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
-                                       orig_node, vid);
+               batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
        }
        rcu_read_unlock();
        return ret;
@@ -1551,8 +1580,7 @@ batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
                        break;
                }
 
-               batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
-                                       orig_node, vid);
+               batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
        }
        rcu_read_unlock();
        return ret;
@@ -1618,8 +1646,7 @@ batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,
                        break;
                }
 
-               batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
-                                       orig_node, vid);
+               batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
        }
        rcu_read_unlock();
        return ret;
@@ -1656,8 +1683,7 @@ batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,
                        break;
                }
 
-               batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
-                                       orig_node, vid);
+               batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
        }
        rcu_read_unlock();
        return ret;
index ebf8259..3e114bc 100644 (file)
@@ -46,6 +46,11 @@ enum batadv_forw_mode
 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
                       struct batadv_orig_node **mcast_single_orig);
 
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
+                               struct sk_buff *skb,
+                               unsigned short vid,
+                               struct batadv_orig_node *orig_node);
+
 int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
                           unsigned short vid);
 
@@ -72,6 +77,16 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
 }
 
 static inline int
+batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
+                           struct sk_buff *skb,
+                           unsigned short vid,
+                           struct batadv_orig_node *orig_node)
+{
+       kfree_skb(skb);
+       return NET_XMIT_DROP;
+}
+
+static inline int
 batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
                       unsigned short vid)
 {
index 27cdf5e..9e5c71e 100644 (file)
@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
        vid = batadv_get_vid(skb, hdr_len);
        ethhdr = (struct ethhdr *)(skb->data + hdr_len);
 
+       /* do not reroute multicast frames in a unicast header */
+       if (is_multicast_ether_addr(ethhdr->h_dest))
+               return true;
+
        /* check if the destination client was served by this node and it is now
         * roaming. In this case, it means that the node has got a ROAM_ADV
         * message and that it knows the new destination in the mesh to re-route
index 23833a0..cdde943 100644 (file)
@@ -364,9 +364,8 @@ send:
                                goto dropped;
                        ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
                } else if (mcast_single_orig) {
-                       ret = batadv_send_skb_unicast(bat_priv, skb,
-                                                     BATADV_UNICAST, 0,
-                                                     mcast_single_orig, vid);
+                       ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
+                                                         mcast_single_orig);
                } else if (forw_mode == BATADV_FORW_SOME) {
                        ret = batadv_mcast_forw_send(bat_priv, skb, vid);
                } else {
@@ -425,10 +424,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
        struct vlan_ethhdr *vhdr;
        struct ethhdr *ethhdr;
        unsigned short vid;
-       bool is_bcast;
+       int packet_type;
 
        batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
-       is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
+       packet_type = batadv_bcast_packet->packet_type;
 
        skb_pull_rcsum(skb, hdr_size);
        skb_reset_mac_header(skb);
@@ -471,7 +470,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
        /* Let the bridge loop avoidance check the packet. If will
         * not handle it, we can safely push it up.
         */
-       if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
+       if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
                goto out;
 
        if (orig_node)
index 42f327c..b4fc05c 100644 (file)
@@ -160,11 +160,14 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
        packing(injection, &qos_class, 19,  17, OCELOT_TAG_LEN, PACK, 0);
 
        if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+               struct sk_buff *clone = DSA_SKB_CB(skb)->clone;
+
                rew_op = ocelot_port->ptp_cmd;
-               if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
-                       rew_op |= (ocelot_port->ts_id  % 4) << 3;
-                       ocelot_port->ts_id++;
-               }
+               /* Retrieve timestamp ID populated inside skb->cb[0] of the
+                * clone by ocelot_port_add_txtstamp_skb
+                */
+               if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
+                       rew_op |= clone->cb[0] << 3;
 
                packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
        }
index 76bff79..747f56e 100644 (file)
@@ -303,6 +303,7 @@ config IPV6_SEG6_LWTUNNEL
 config IPV6_SEG6_HMAC
        bool "IPv6: Segment Routing HMAC support"
        depends on IPV6
+       select CRYPTO
        select CRYPTO_HMAC
        select CRYPTO_SHA1
        select CRYPTO_SHA256
index 5e7e25e..fb075d9 100644 (file)
@@ -4202,7 +4202,7 @@ static struct fib6_info *rt6_add_route_info(struct net *net,
                .fc_nlinfo.nl_net = net,
        };
 
-       cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO,
+       cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO;
        cfg.fc_dst = *prefix;
        cfg.fc_gateway = *gwaddr;
 
index 836615f..53d0a41 100644 (file)
@@ -9220,13 +9220,10 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
 static inline void sctp_copy_descendant(struct sock *sk_to,
                                        const struct sock *sk_from)
 {
-       int ancestor_size = sizeof(struct inet_sock) +
-                           sizeof(struct sctp_sock) -
-                           offsetof(struct sctp_sock, pd_lobby);
-
-       if (sk_from->sk_family == PF_INET6)
-               ancestor_size += sizeof(struct ipv6_pinfo);
+       size_t ancestor_size = sizeof(struct inet_sock);
 
+       ancestor_size += sk_from->sk_prot->obj_size;
+       ancestor_size -= offsetof(struct sctp_sock, pd_lobby);
        __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
 }