Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from David Miller:

 1) Don't get per-cpu pointer with preemption enabled in nft_set_pipapo,
    fix from Stefano Brivio.

 2) Fix memory leak in ctnetlink, from Pablo Neira Ayuso.

 3) Multiple definitions of MPTCP_PM_MAX_ADDR, from Geliang Tang.

 4) Accidently disabling NAPI in non-error paths of macb_open(), from
    Charles Keepax.

 5) Fix races between alx_stop and alx_remove, from Zekun Shen.

 6) We forget to re-enable SRIOV during resume in bnxt_en driver, from
    Michael Chan.

 7) Fix memory leak in ipv6_mc_destroy_dev(), from Wang Hai.

 8) rxtx stats use wrong index in mvpp2 driver, from Sven Auhagen.

 9) Fix memory leak in mptcp_subflow_create_socket error path, from Wei
    Yongjun.

10) We should not adjust the TCP window advertised when sending dup acks
    in non-SACK mode, because it won't be counted as a dup by the sender
    if the window size changes. From Eric Dumazet.

11) Destroy the right number of queues during remove in mvpp2 driver,
    from Sven Auhagen.

12) Various WOL and PM fixes to e1000 driver, from Chen Yu, Vaibhav
    Gupta, and Arnd Bergmann.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (35 commits)
  e1000e: fix unused-function warning
  e1000: use generic power management
  e1000e: Do not wake up the system via WOL if device wakeup is disabled
  lan743x: add MODULE_DEVICE_TABLE for module loading alias
  mlxsw: spectrum: Adjust headroom buffers for 8x ports
  bareudp: Fixed configuration to avoid having garbage values
  mvpp2: remove module bugfix
  tcp: grow window for OOO packets only for SACK flows
  mptcp: fix memory leak in mptcp_subflow_create_socket()
  netfilter: flowtable: Make nf_flow_table_offload_add/del_cb inline
  net/sched: act_ct: Make tcf_ct_flow_table_restore_skb inline
  net: dsa: sja1105: fix PTP timestamping with large tc-taprio cycles
  mvpp2: ethtool rxtx stats fix
  MAINTAINERS: switch to my private email for Renesas Ethernet drivers
  rocker: fix incorrect error handling in dma_rings_init
  test_objagg: Fix potential memory leak in error handling
  net: ethernet: mtk-star-emac: simplify interrupt handling
  mld: fix memory leak in ipv6_mc_destroy_dev()
  bnxt_en: Return from timer if interface is not in open state.
  bnxt_en: Fix AER reset logic on 57500 chips.
  ...
This commit is contained in:
Linus Torvalds 2020-06-16 17:44:54 -07:00
commit 69119673bd
33 changed files with 309 additions and 314 deletions

View File

@ -11369,14 +11369,6 @@ L: dmaengine@vger.kernel.org
S: Supported S: Supported
F: drivers/dma/at_xdmac.c F: drivers/dma/at_xdmac.c
MICROSEMI ETHERNET SWITCH DRIVER
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/mscc/
F: include/soc/mscc/ocelot*
MICROSEMI MIPS SOCS MICROSEMI MIPS SOCS
M: Alexandre Belloni <alexandre.belloni@bootlin.com> M: Alexandre Belloni <alexandre.belloni@bootlin.com>
M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
@ -12335,6 +12327,18 @@ M: Peter Zijlstra <peterz@infradead.org>
S: Supported S: Supported
F: tools/objtool/ F: tools/objtool/
OCELOT ETHERNET SWITCH DRIVER
M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
M: Vladimir Oltean <vladimir.oltean@nxp.com>
M: Claudiu Manoil <claudiu.manoil@nxp.com>
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/dsa/ocelot/*
F: drivers/net/ethernet/mscc/
F: include/soc/mscc/ocelot*
F: net/dsa/tag_ocelot.c
OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
M: Frederic Barrat <fbarrat@linux.ibm.com> M: Frederic Barrat <fbarrat@linux.ibm.com>
M: Andrew Donnellan <ajd@linux.ibm.com> M: Andrew Donnellan <ajd@linux.ibm.com>
@ -14534,7 +14538,7 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
F: drivers/i2c/busses/i2c-emev2.c F: drivers/i2c/busses/i2c-emev2.c
RENESAS ETHERNET DRIVERS RENESAS ETHERNET DRIVERS
R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> R: Sergei Shtylyov <sergei.shtylyov@gmail.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org L: linux-renesas-soc@vger.kernel.org
F: Documentation/devicetree/bindings/net/renesas,*.txt F: Documentation/devicetree/bindings/net/renesas,*.txt
@ -18254,14 +18258,6 @@ S: Maintained
F: drivers/input/serio/userio.c F: drivers/input/serio/userio.c
F: include/uapi/linux/userio.h F: include/uapi/linux/userio.h
VITESSE FELIX ETHERNET SWITCH DRIVER
M: Vladimir Oltean <vladimir.oltean@nxp.com>
M: Claudiu Manoil <claudiu.manoil@nxp.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/dsa/ocelot/*
F: net/dsa/tag_ocelot.c
VIVID VIRTUAL VIDEO DRIVER VIVID VIRTUAL VIDEO DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl> M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org

View File

@ -552,6 +552,8 @@ static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[],
static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf, static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
memset(conf, 0, sizeof(*conf));
if (!data[IFLA_BAREUDP_PORT]) { if (!data[IFLA_BAREUDP_PORT]) {
NL_SET_ERR_MSG(extack, "port not specified"); NL_SET_ERR_MSG(extack, "port not specified");
return -EINVAL; return -EINVAL;

View File

@ -891,16 +891,16 @@ void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int port,
mutex_lock(&ptp_data->lock); mutex_lock(&ptp_data->lock);
rc = sja1105_ptpclkval_read(priv, &ticks, NULL); rc = sja1105_ptpegr_ts_poll(ds, port, &ts);
if (rc < 0) { if (rc < 0) {
dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc); dev_err(ds->dev, "timed out polling for tstamp\n");
kfree_skb(skb); kfree_skb(skb);
goto out; goto out;
} }
rc = sja1105_ptpegr_ts_poll(ds, port, &ts); rc = sja1105_ptpclkval_read(priv, &ticks, NULL);
if (rc < 0) { if (rc < 0) {
dev_err(ds->dev, "timed out polling for tstamp\n"); dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc);
kfree_skb(skb); kfree_skb(skb);
goto out; goto out;
} }

View File

@ -1249,8 +1249,12 @@ static int __alx_open(struct alx_priv *alx, bool resume)
static void __alx_stop(struct alx_priv *alx) static void __alx_stop(struct alx_priv *alx)
{ {
alx_halt(alx);
alx_free_irq(alx); alx_free_irq(alx);
cancel_work_sync(&alx->link_check_wk);
cancel_work_sync(&alx->reset_wk);
alx_halt(alx);
alx_free_rings(alx); alx_free_rings(alx);
alx_free_napis(alx); alx_free_napis(alx);
} }
@ -1855,9 +1859,6 @@ static void alx_remove(struct pci_dev *pdev)
struct alx_priv *alx = pci_get_drvdata(pdev); struct alx_priv *alx = pci_get_drvdata(pdev);
struct alx_hw *hw = &alx->hw; struct alx_hw *hw = &alx->hw;
cancel_work_sync(&alx->link_check_wk);
cancel_work_sync(&alx->reset_wk);
/* restore permanent mac address */ /* restore permanent mac address */
alx_set_macaddr(hw, hw->perm_addr); alx_set_macaddr(hw, hw->perm_addr);

View File

@ -10037,7 +10037,7 @@ static void bnxt_timer(struct timer_list *t)
struct bnxt *bp = from_timer(bp, t, timer); struct bnxt *bp = from_timer(bp, t, timer);
struct net_device *dev = bp->dev; struct net_device *dev = bp->dev;
if (!netif_running(dev)) if (!netif_running(dev) || !test_bit(BNXT_STATE_OPEN, &bp->state))
return; return;
if (atomic_read(&bp->intr_sem) != 0) if (atomic_read(&bp->intr_sem) != 0)
@ -12133,19 +12133,9 @@ static int bnxt_resume(struct device *device)
goto resume_exit; goto resume_exit;
} }
if (bnxt_hwrm_queue_qportcfg(bp)) { rc = bnxt_hwrm_func_qcaps(bp);
rc = -ENODEV; if (rc)
goto resume_exit; goto resume_exit;
}
if (bp->hwrm_spec_code >= 0x10803) {
if (bnxt_alloc_ctx_mem(bp)) {
rc = -ENODEV;
goto resume_exit;
}
}
if (BNXT_NEW_RM(bp))
bnxt_hwrm_func_resc_qcaps(bp, false);
if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) { if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) {
rc = -ENODEV; rc = -ENODEV;
@ -12161,6 +12151,8 @@ static int bnxt_resume(struct device *device)
resume_exit: resume_exit:
bnxt_ulp_start(bp, rc); bnxt_ulp_start(bp, rc);
if (!rc)
bnxt_reenable_sriov(bp);
rtnl_unlock(); rtnl_unlock();
return rc; return rc;
} }
@ -12204,6 +12196,9 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
bnxt_close(netdev); bnxt_close(netdev);
pci_disable_device(pdev); pci_disable_device(pdev);
bnxt_free_ctx_mem(bp);
kfree(bp->ctx);
bp->ctx = NULL;
rtnl_unlock(); rtnl_unlock();
/* Request a slot slot reset. */ /* Request a slot slot reset. */
@ -12237,12 +12232,16 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev); pci_set_master(pdev);
err = bnxt_hwrm_func_reset(bp); err = bnxt_hwrm_func_reset(bp);
if (!err && netif_running(netdev)) if (!err) {
err = bnxt_open(netdev); err = bnxt_hwrm_func_qcaps(bp);
if (!err && netif_running(netdev))
if (!err) err = bnxt_open(netdev);
result = PCI_ERS_RESULT_RECOVERED; }
bnxt_ulp_start(bp, err); bnxt_ulp_start(bp, err);
if (!err) {
bnxt_reenable_sriov(bp);
result = PCI_ERS_RESULT_RECOVERED;
}
} }
if (result != PCI_ERS_RESULT_RECOVERED) { if (result != PCI_ERS_RESULT_RECOVERED) {

View File

@ -2565,15 +2565,14 @@ static int macb_open(struct net_device *dev)
if (bp->ptp_info) if (bp->ptp_info)
bp->ptp_info->ptp_init(dev); bp->ptp_info->ptp_init(dev);
return 0;
napi_exit: napi_exit:
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
napi_disable(&queue->napi); napi_disable(&queue->napi);
pm_exit: pm_exit:
if (err) { pm_runtime_put_sync(&bp->pdev->dev);
pm_runtime_put_sync(&bp->pdev->dev); return err;
return err;
}
return 0;
} }
static int macb_close(struct net_device *dev) static int macb_close(struct net_device *dev)

View File

@ -842,12 +842,13 @@ static int ibmvnic_login(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(30000); unsigned long timeout = msecs_to_jiffies(30000);
int retry_count = 0; int retry_count = 0;
int retries = 10;
bool retry; bool retry;
int rc; int rc;
do { do {
retry = false; retry = false;
if (retry_count > IBMVNIC_MAX_QUEUES) { if (retry_count > retries) {
netdev_warn(netdev, "Login attempts exceeded\n"); netdev_warn(netdev, "Login attempts exceeded\n");
return -1; return -1;
} }
@ -862,11 +863,23 @@ static int ibmvnic_login(struct net_device *netdev)
if (!wait_for_completion_timeout(&adapter->init_done, if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) { timeout)) {
netdev_warn(netdev, "Login timed out\n"); netdev_warn(netdev, "Login timed out, retrying...\n");
return -1; retry = true;
adapter->init_done_rc = 0;
retry_count++;
continue;
} }
if (adapter->init_done_rc == PARTIALSUCCESS) { if (adapter->init_done_rc == ABORTED) {
netdev_warn(netdev, "Login aborted, retrying...\n");
retry = true;
adapter->init_done_rc = 0;
retry_count++;
/* FW or device may be busy, so
* wait a bit before retrying login
*/
msleep(500);
} else if (adapter->init_done_rc == PARTIALSUCCESS) {
retry_count++; retry_count++;
release_sub_crqs(adapter, 1); release_sub_crqs(adapter, 1);

View File

@ -151,10 +151,8 @@ static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
__be16 proto, u16 vid); __be16 proto, u16 vid);
static void e1000_restore_vlan(struct e1000_adapter *adapter); static void e1000_restore_vlan(struct e1000_adapter *adapter);
#ifdef CONFIG_PM static int __maybe_unused e1000_suspend(struct device *dev);
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int __maybe_unused e1000_resume(struct device *dev);
static int e1000_resume(struct pci_dev *pdev);
#endif
static void e1000_shutdown(struct pci_dev *pdev); static void e1000_shutdown(struct pci_dev *pdev);
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
@ -179,16 +177,16 @@ static const struct pci_error_handlers e1000_err_handler = {
.resume = e1000_io_resume, .resume = e1000_io_resume,
}; };
static SIMPLE_DEV_PM_OPS(e1000_pm_ops, e1000_suspend, e1000_resume);
static struct pci_driver e1000_driver = { static struct pci_driver e1000_driver = {
.name = e1000_driver_name, .name = e1000_driver_name,
.id_table = e1000_pci_tbl, .id_table = e1000_pci_tbl,
.probe = e1000_probe, .probe = e1000_probe,
.remove = e1000_remove, .remove = e1000_remove,
#ifdef CONFIG_PM .driver = {
/* Power Management Hooks */ .pm = &e1000_pm_ops,
.suspend = e1000_suspend, },
.resume = e1000_resume,
#endif
.shutdown = e1000_shutdown, .shutdown = e1000_shutdown,
.err_handler = &e1000_err_handler .err_handler = &e1000_err_handler
}; };
@ -5060,9 +5058,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 ctrl, ctrl_ext, rctl, status; u32 ctrl, ctrl_ext, rctl, status;
u32 wufc = adapter->wol; u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
netif_device_detach(netdev); netif_device_detach(netdev);
@ -5076,12 +5071,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
e1000_down(adapter); e1000_down(adapter);
} }
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
if (retval)
return retval;
#endif
status = er32(STATUS); status = er32(STATUS);
if (status & E1000_STATUS_LU) if (status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC; wufc &= ~E1000_WUFC_LNKC;
@ -5142,37 +5131,26 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
return 0; return 0;
} }
#ifdef CONFIG_PM static int __maybe_unused e1000_suspend(struct device *dev)
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{ {
int retval; int retval;
struct pci_dev *pdev = to_pci_dev(dev);
bool wake; bool wake;
retval = __e1000_shutdown(pdev, &wake); retval = __e1000_shutdown(pdev, &wake);
if (retval) device_set_wakeup_enable(dev, wake);
return retval;
if (wake) { return retval;
pci_prepare_to_sleep(pdev);
} else {
pci_wake_from_d3(pdev, false);
pci_set_power_state(pdev, PCI_D3hot);
}
return 0;
} }
static int e1000_resume(struct pci_dev *pdev) static int __maybe_unused e1000_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 err; u32 err;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
if (adapter->need_ioport) if (adapter->need_ioport)
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
else else
@ -5209,7 +5187,6 @@ static int e1000_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#endif
static void e1000_shutdown(struct pci_dev *pdev) static void e1000_shutdown(struct pci_dev *pdev)
{ {

View File

@ -6349,7 +6349,6 @@ static void e1000e_flush_lpic(struct pci_dev *pdev)
pm_runtime_put_sync(netdev->dev.parent); pm_runtime_put_sync(netdev->dev.parent);
} }
#ifdef CONFIG_PM_SLEEP
/* S0ix implementation */ /* S0ix implementation */
static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter) static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
{ {
@ -6571,7 +6570,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS; mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_data); ew32(CTRL_EXT, mac_data);
} }
#endif /* CONFIG_PM_SLEEP */
static int e1000e_pm_freeze(struct device *dev) static int e1000e_pm_freeze(struct device *dev)
{ {
@ -6611,11 +6609,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 ctrl, ctrl_ext, rctl, status; u32 ctrl, ctrl_ext, rctl, status, wufc;
/* Runtime suspend should only enable wakeup for link changes */
u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
int retval = 0; int retval = 0;
/* Runtime suspend should only enable wakeup for link changes */
if (runtime)
wufc = E1000_WUFC_LNKC;
else if (device_may_wakeup(&pdev->dev))
wufc = adapter->wol;
else
wufc = 0;
status = er32(STATUS); status = er32(STATUS);
if (status & E1000_STATUS_LU) if (status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC; wufc &= ~E1000_WUFC_LNKC;
@ -6672,7 +6676,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
if (adapter->hw.phy.type == e1000_phy_igp_3) { if (adapter->hw.phy.type == e1000_phy_igp_3) {
e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
} else if (hw->mac.type >= e1000_pch_lpt) { } else if (hw->mac.type >= e1000_pch_lpt) {
if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC)))
/* ULP does not support wake from unicast, multicast /* ULP does not support wake from unicast, multicast
* or broadcast. * or broadcast.
*/ */
@ -6869,7 +6873,6 @@ static int e1000e_pm_thaw(struct device *dev)
return rc; return rc;
} }
#ifdef CONFIG_PM
static int __e1000_resume(struct pci_dev *pdev) static int __e1000_resume(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
@ -6935,8 +6938,7 @@ static int __e1000_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP static __maybe_unused int e1000e_pm_suspend(struct device *dev)
static int e1000e_pm_suspend(struct device *dev)
{ {
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
@ -6960,7 +6962,7 @@ static int e1000e_pm_suspend(struct device *dev)
return rc; return rc;
} }
static int e1000e_pm_resume(struct device *dev) static __maybe_unused int e1000e_pm_resume(struct device *dev)
{ {
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
@ -6979,9 +6981,8 @@ static int e1000e_pm_resume(struct device *dev)
return e1000e_pm_thaw(dev); return e1000e_pm_thaw(dev);
} }
#endif /* CONFIG_PM_SLEEP */
static int e1000e_pm_runtime_idle(struct device *dev) static __maybe_unused int e1000e_pm_runtime_idle(struct device *dev)
{ {
struct net_device *netdev = dev_get_drvdata(dev); struct net_device *netdev = dev_get_drvdata(dev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
@ -6997,7 +6998,7 @@ static int e1000e_pm_runtime_idle(struct device *dev)
return -EBUSY; return -EBUSY;
} }
static int e1000e_pm_runtime_resume(struct device *dev) static __maybe_unused int e1000e_pm_runtime_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
@ -7014,7 +7015,7 @@ static int e1000e_pm_runtime_resume(struct device *dev)
return rc; return rc;
} }
static int e1000e_pm_runtime_suspend(struct device *dev) static __maybe_unused int e1000e_pm_runtime_suspend(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
@ -7039,7 +7040,6 @@ static int e1000e_pm_runtime_suspend(struct device *dev)
return 0; return 0;
} }
#endif /* CONFIG_PM */
static void e1000_shutdown(struct pci_dev *pdev) static void e1000_shutdown(struct pci_dev *pdev)
{ {

View File

@ -1544,7 +1544,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port)
for (q = 0; q < port->ntxqs; q++) for (q = 0; q < port->ntxqs; q++)
for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++)
*pstats++ += mvpp2_read_index(port->priv, *pstats++ += mvpp2_read_index(port->priv,
MVPP22_CTRS_TX_CTR(port->id, i), MVPP22_CTRS_TX_CTR(port->id, q),
mvpp2_ethtool_txq_regs[i].offset); mvpp2_ethtool_txq_regs[i].offset);
/* Rxqs are numbered from 0 from the user standpoint, but not from the /* Rxqs are numbered from 0 from the user standpoint, but not from the
@ -1553,7 +1553,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port)
for (q = 0; q < port->nrxqs; q++) for (q = 0; q < port->nrxqs; q++)
for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++)
*pstats++ += mvpp2_read_index(port->priv, *pstats++ += mvpp2_read_index(port->priv,
port->first_rxq + i, port->first_rxq + q,
mvpp2_ethtool_rxq_regs[i].offset); mvpp2_ethtool_rxq_regs[i].offset);
} }
@ -5983,8 +5983,8 @@ static int mvpp2_remove(struct platform_device *pdev)
{ {
struct mvpp2 *priv = platform_get_drvdata(pdev); struct mvpp2 *priv = platform_get_drvdata(pdev);
struct fwnode_handle *fwnode = pdev->dev.fwnode; struct fwnode_handle *fwnode = pdev->dev.fwnode;
int i = 0, poolnum = MVPP2_BM_POOLS_NUM;
struct fwnode_handle *port_fwnode; struct fwnode_handle *port_fwnode;
int i = 0;
mvpp2_dbgfs_cleanup(priv); mvpp2_dbgfs_cleanup(priv);
@ -5998,7 +5998,10 @@ static int mvpp2_remove(struct platform_device *pdev)
destroy_workqueue(priv->stats_queue); destroy_workqueue(priv->stats_queue);
for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { if (priv->percpu_pools)
poolnum = mvpp2_get_nrxqs(priv) * 2;
for (i = 0; i < poolnum; i++) {
struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i]; struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i];
mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool); mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool);

View File

@ -24,7 +24,6 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h>
#define MTK_STAR_DRVNAME "mtk_star_emac" #define MTK_STAR_DRVNAME "mtk_star_emac"
@ -262,7 +261,6 @@ struct mtk_star_priv {
spinlock_t lock; spinlock_t lock;
struct rtnl_link_stats64 stats; struct rtnl_link_stats64 stats;
struct work_struct stats_work;
}; };
static struct device *mtk_star_get_dev(struct mtk_star_priv *priv) static struct device *mtk_star_get_dev(struct mtk_star_priv *priv)
@ -432,42 +430,6 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv)
regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0); regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0);
} }
static void mtk_star_intr_enable_tx(struct mtk_star_priv *priv)
{
regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_BIT_INT_STS_TNTC);
}
static void mtk_star_intr_enable_rx(struct mtk_star_priv *priv)
{
regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_BIT_INT_STS_FNRC);
}
static void mtk_star_intr_enable_stats(struct mtk_star_priv *priv)
{
regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_REG_INT_STS_MIB_CNT_TH);
}
static void mtk_star_intr_disable_tx(struct mtk_star_priv *priv)
{
regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_BIT_INT_STS_TNTC);
}
static void mtk_star_intr_disable_rx(struct mtk_star_priv *priv)
{
regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_BIT_INT_STS_FNRC);
}
static void mtk_star_intr_disable_stats(struct mtk_star_priv *priv)
{
regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
MTK_STAR_REG_INT_STS_MIB_CNT_TH);
}
static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv) static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv)
{ {
unsigned int val; unsigned int val;
@ -663,20 +625,6 @@ static void mtk_star_update_stats(struct mtk_star_priv *priv)
stats->rx_errors += stats->rx_fifo_errors; stats->rx_errors += stats->rx_fifo_errors;
} }
/* This runs in process context and parallel TX and RX paths executing in
* napi context may result in losing some stats data but this should happen
* seldom enough to be acceptable.
*/
static void mtk_star_update_stats_work(struct work_struct *work)
{
struct mtk_star_priv *priv = container_of(work, struct mtk_star_priv,
stats_work);
mtk_star_update_stats(priv);
mtk_star_reset_counters(priv);
mtk_star_intr_enable_stats(priv);
}
static struct sk_buff *mtk_star_alloc_skb(struct net_device *ndev) static struct sk_buff *mtk_star_alloc_skb(struct net_device *ndev)
{ {
uintptr_t tail, offset; uintptr_t tail, offset;
@ -767,42 +715,25 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv)
mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx); mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx);
} }
/* All processing for TX and RX happens in the napi poll callback. */ /* All processing for TX and RX happens in the napi poll callback.
*
* FIXME: The interrupt handling should be more fine-grained with each
* interrupt enabled/disabled independently when needed. Unfortunatly this
* turned out to impact the driver's stability and until we have something
* working properly, we're disabling all interrupts during TX & RX processing
* or when resetting the counter registers.
*/
static irqreturn_t mtk_star_handle_irq(int irq, void *data) static irqreturn_t mtk_star_handle_irq(int irq, void *data)
{ {
struct mtk_star_priv *priv; struct mtk_star_priv *priv;
struct net_device *ndev; struct net_device *ndev;
bool need_napi = false;
unsigned int status;
ndev = data; ndev = data;
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
if (netif_running(ndev)) { if (netif_running(ndev)) {
status = mtk_star_intr_read(priv); mtk_star_intr_disable(priv);
napi_schedule(&priv->napi);
if (status & MTK_STAR_BIT_INT_STS_TNTC) {
mtk_star_intr_disable_tx(priv);
need_napi = true;
}
if (status & MTK_STAR_BIT_INT_STS_FNRC) {
mtk_star_intr_disable_rx(priv);
need_napi = true;
}
if (need_napi)
napi_schedule(&priv->napi);
/* One of the counters reached 0x8000000 - update stats and
* reset all counters.
*/
if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
mtk_star_intr_disable_stats(priv);
schedule_work(&priv->stats_work);
}
mtk_star_intr_ack_all(priv);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
@ -1169,8 +1100,6 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
if (wake && netif_queue_stopped(ndev)) if (wake && netif_queue_stopped(ndev))
netif_wake_queue(ndev); netif_wake_queue(ndev);
mtk_star_intr_enable_tx(priv);
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
} }
@ -1332,20 +1261,32 @@ static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
static int mtk_star_poll(struct napi_struct *napi, int budget) static int mtk_star_poll(struct napi_struct *napi, int budget)
{ {
struct mtk_star_priv *priv; struct mtk_star_priv *priv;
unsigned int status;
int received = 0; int received = 0;
priv = container_of(napi, struct mtk_star_priv, napi); priv = container_of(napi, struct mtk_star_priv, napi);
/* Clean-up all TX descriptors. */ status = mtk_star_intr_read(priv);
mtk_star_tx_complete_all(priv); mtk_star_intr_ack_all(priv);
/* Receive up to $budget packets. */
received = mtk_star_process_rx(priv, budget);
if (received < budget) { if (status & MTK_STAR_BIT_INT_STS_TNTC)
napi_complete_done(napi, received); /* Clean-up all TX descriptors. */
mtk_star_intr_enable_rx(priv); mtk_star_tx_complete_all(priv);
if (status & MTK_STAR_BIT_INT_STS_FNRC)
/* Receive up to $budget packets. */
received = mtk_star_process_rx(priv, budget);
if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
mtk_star_update_stats(priv);
mtk_star_reset_counters(priv);
} }
if (received < budget)
napi_complete_done(napi, received);
mtk_star_intr_enable(priv);
return received; return received;
} }
@ -1532,7 +1473,6 @@ static int mtk_star_probe(struct platform_device *pdev)
ndev->max_mtu = MTK_STAR_MAX_FRAME_SIZE; ndev->max_mtu = MTK_STAR_MAX_FRAME_SIZE;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
INIT_WORK(&priv->stats_work, mtk_star_update_stats_work);
base = devm_platform_ioremap_resource(pdev, 0); base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base)) if (IS_ERR(base))

View File

@ -978,8 +978,10 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
lossy = !(pfc || pause_en); lossy = !(pfc || pause_en);
thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu); thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &thres_cells);
delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay, delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay,
pfc, pause_en); pfc, pause_en);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &delay_cells);
total_cells = thres_cells + delay_cells; total_cells = thres_cells + delay_cells;
taken_headroom_cells += total_cells; taken_headroom_cells += total_cells;

View File

@ -374,6 +374,19 @@ mlxsw_sp_port_vlan_find_by_vid(const struct mlxsw_sp_port *mlxsw_sp_port,
return NULL; return NULL;
} }
static inline void
mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port,
u16 *p_size)
{
/* Ports with eight lanes use two headroom buffers between which the
* configured headroom size is split. Therefore, multiply the calculated
* headroom size by two.
*/
if (mlxsw_sp_port->mapping.width != 8)
return;
*p_size *= 2;
}
enum mlxsw_sp_flood_type { enum mlxsw_sp_flood_type {
MLXSW_SP_FLOOD_TYPE_UC, MLXSW_SP_FLOOD_TYPE_UC,
MLXSW_SP_FLOOD_TYPE_BC, MLXSW_SP_FLOOD_TYPE_BC,

View File

@ -312,6 +312,7 @@ static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port)
if (i == MLXSW_SP_PB_UNUSED) if (i == MLXSW_SP_PB_UNUSED)
continue; continue;
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &size);
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size); mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size);
} }
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl,

View File

@ -782,6 +782,7 @@ mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
speed = 0; speed = 0;
buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu); buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, (u16 *) &buffsize);
mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize); mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
} }

View File

@ -3091,6 +3091,8 @@ static const struct pci_device_id lan743x_pcidev_tbl[] = {
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, lan743x_pcidev_tbl);
static struct pci_driver lan743x_pcidev_driver = { static struct pci_driver lan743x_pcidev_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = lan743x_pcidev_tbl, .id_table = lan743x_pcidev_tbl,

View File

@ -269,7 +269,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t offset, size_t size) loff_t offset, size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
int ret; int ret;
@ -286,7 +286,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t offset, size_t size) loff_t offset, size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
int ret; int ret;
@ -315,7 +315,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t offset, size_t size) loff_t offset, size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
u64 data; u64 data;
int ret; int ret;
@ -337,7 +337,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t offset, size_t size) loff_t offset, size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
u64 data; u64 data;
int ret; int ret;
@ -402,7 +402,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_pm_func_cfg *pm_cfg; struct qlcnic_pm_func_cfg *pm_cfg;
u32 id, action, pci_func; u32 id, action, pci_func;
@ -452,7 +452,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_pm_func_cfg *pm_cfg; struct qlcnic_pm_func_cfg *pm_cfg;
u8 pci_func; u8 pci_func;
@ -545,7 +545,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg *esw_cfg; struct qlcnic_esw_func_cfg *esw_cfg;
struct qlcnic_npar_info *npar; struct qlcnic_npar_info *npar;
@ -629,7 +629,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg *esw_cfg; struct qlcnic_esw_func_cfg *esw_cfg;
u8 pci_func; u8 pci_func;
@ -681,7 +681,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
struct qlcnic_npar_func_cfg *np_cfg; struct qlcnic_npar_func_cfg *np_cfg;
@ -728,7 +728,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_npar_func_cfg *np_cfg; struct qlcnic_npar_func_cfg *np_cfg;
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
@ -775,7 +775,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_statistics port_stats; struct qlcnic_esw_statistics port_stats;
int ret; int ret;
@ -810,7 +810,7 @@ static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_statistics esw_stats; struct qlcnic_esw_statistics esw_stats;
int ret; int ret;
@ -845,7 +845,7 @@ static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
int ret; int ret;
@ -875,7 +875,7 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
int ret; int ret;
@ -904,7 +904,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
char *buf, loff_t offset, char *buf, loff_t offset,
size_t size) size_t size)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_pci_func_cfg *pci_cfg; struct qlcnic_pci_func_cfg *pci_cfg;
struct qlcnic_pci_info *pci_info; struct qlcnic_pci_info *pci_info;
@ -946,7 +946,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
{ {
unsigned char *p_read_buf; unsigned char *p_read_buf;
int ret, count; int ret, count;
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
if (!size) if (!size)
@ -1124,7 +1124,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
int ret; int ret;
static int flash_mode; static int flash_mode;
unsigned long data; unsigned long data;
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
ret = kstrtoul(buf, 16, &data); ret = kstrtoul(buf, 16, &data);

View File

@ -647,10 +647,10 @@ static int rocker_dma_rings_init(struct rocker *rocker)
err_dma_event_ring_bufs_alloc: err_dma_event_ring_bufs_alloc:
rocker_dma_ring_destroy(rocker, &rocker->event_ring); rocker_dma_ring_destroy(rocker, &rocker->event_ring);
err_dma_event_ring_create: err_dma_event_ring_create:
rocker_dma_cmd_ring_waits_free(rocker);
err_dma_cmd_ring_waits_alloc:
rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring, rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
err_dma_cmd_ring_waits_alloc:
rocker_dma_cmd_ring_waits_free(rocker);
err_dma_cmd_ring_bufs_alloc: err_dma_cmd_ring_bufs_alloc:
rocker_dma_ring_destroy(rocker, &rocker->cmd_ring); rocker_dma_ring_destroy(rocker, &rocker->cmd_ring);
return err; return err;

View File

@ -186,7 +186,7 @@
#define XAE_RAF_TXVSTRPMODE_MASK 0x00000180 /* Tx VLAN STRIP mode */ #define XAE_RAF_TXVSTRPMODE_MASK 0x00000180 /* Tx VLAN STRIP mode */
#define XAE_RAF_RXVSTRPMODE_MASK 0x00000600 /* Rx VLAN STRIP mode */ #define XAE_RAF_RXVSTRPMODE_MASK 0x00000600 /* Rx VLAN STRIP mode */
#define XAE_RAF_NEWFNCENBL_MASK 0x00000800 /* New function mode */ #define XAE_RAF_NEWFNCENBL_MASK 0x00000800 /* New function mode */
/* Exteneded Multicast Filtering mode */ /* Extended Multicast Filtering mode */
#define XAE_RAF_EMULTIFLTRENBL_MASK 0x00001000 #define XAE_RAF_EMULTIFLTRENBL_MASK 0x00001000
#define XAE_RAF_STATSRST_MASK 0x00002000 /* Stats. Counter Reset */ #define XAE_RAF_STATSRST_MASK 0x00002000 /* Stats. Counter Reset */
#define XAE_RAF_RXBADFRMEN_MASK 0x00004000 /* Recv Bad Frame Enable */ #define XAE_RAF_RXBADFRMEN_MASK 0x00004000 /* Recv Bad Frame Enable */

View File

@ -161,10 +161,51 @@ struct nf_flow_route {
struct flow_offload *flow_offload_alloc(struct nf_conn *ct); struct flow_offload *flow_offload_alloc(struct nf_conn *ct);
void flow_offload_free(struct flow_offload *flow); void flow_offload_free(struct flow_offload *flow);
int nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table, static inline int
flow_setup_cb_t *cb, void *cb_priv); nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, flow_setup_cb_t *cb, void *cb_priv)
flow_setup_cb_t *cb, void *cb_priv); {
struct flow_block *block = &flow_table->flow_block;
struct flow_block_cb *block_cb;
int err = 0;
down_write(&flow_table->flow_block_lock);
block_cb = flow_block_cb_lookup(block, cb, cb_priv);
if (block_cb) {
err = -EEXIST;
goto unlock;
}
block_cb = flow_block_cb_alloc(cb, cb_priv, cb_priv, NULL);
if (IS_ERR(block_cb)) {
err = PTR_ERR(block_cb);
goto unlock;
}
list_add_tail(&block_cb->list, &block->cb_list);
unlock:
up_write(&flow_table->flow_block_lock);
return err;
}
static inline void
nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
flow_setup_cb_t *cb, void *cb_priv)
{
struct flow_block *block = &flow_table->flow_block;
struct flow_block_cb *block_cb;
down_write(&flow_table->flow_block_lock);
block_cb = flow_block_cb_lookup(block, cb, cb_priv);
if (block_cb) {
list_del(&block_cb->list);
flow_block_cb_free(block_cb);
} else {
WARN_ON(true);
}
up_write(&flow_table->flow_block_lock);
}
int flow_offload_route_init(struct flow_offload *flow, int flow_offload_route_init(struct flow_offload *flow,
const struct nf_flow_route *route); const struct nf_flow_route *route);

View File

@ -66,7 +66,16 @@ static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a)
#endif /* CONFIG_NF_CONNTRACK */ #endif /* CONFIG_NF_CONNTRACK */
#if IS_ENABLED(CONFIG_NET_ACT_CT) #if IS_ENABLED(CONFIG_NET_ACT_CT)
void tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie); static inline void
tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie)
{
enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK;
struct nf_conn *ct;
ct = (struct nf_conn *)(cookie & NFCT_PTRMASK);
nf_conntrack_get(&ct->ct_general);
nf_ct_set(skb, ct, ctinfo);
}
#else #else
static inline void static inline void
tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) { } tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) { }

View File

@ -979,10 +979,10 @@ static int test_hints_case(const struct hints_case *hints_case)
err_world2_obj_get: err_world2_obj_get:
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
world_obj_put(&world2, objagg, hints_case->key_ids[i]); world_obj_put(&world2, objagg, hints_case->key_ids[i]);
objagg_hints_put(hints);
objagg_destroy(objagg2);
i = hints_case->key_ids_count; i = hints_case->key_ids_count;
objagg_destroy(objagg2);
err_check_expect_hints_stats: err_check_expect_hints_stats:
objagg_hints_put(hints);
err_hints_get: err_hints_get:
err_check_expect_stats: err_check_expect_stats:
err_world_obj_get: err_world_obj_get:

View File

@ -4605,7 +4605,11 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb, if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb,
skb, &fragstolen)) { skb, &fragstolen)) {
coalesce_done: coalesce_done:
tcp_grow_window(sk, skb); /* For non sack flows, do not grow window to force DUPACK
* and trigger fast retransmit.
*/
if (tcp_is_sack(tp))
tcp_grow_window(sk, skb);
kfree_skb_partial(skb, fragstolen); kfree_skb_partial(skb, fragstolen);
skb = NULL; skb = NULL;
goto add_sack; goto add_sack;
@ -4689,7 +4693,11 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
tcp_sack_new_ofo_skb(sk, seq, end_seq); tcp_sack_new_ofo_skb(sk, seq, end_seq);
end: end:
if (skb) { if (skb) {
tcp_grow_window(sk, skb); /* For non sack flows, do not grow window to force DUPACK
* and trigger fast retransmit.
*/
if (tcp_is_sack(tp))
tcp_grow_window(sk, skb);
skb_condense(skb); skb_condense(skb);
skb_set_owner_r(skb, sk); skb_set_owner_r(skb, sk);
} }

View File

@ -2615,6 +2615,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
idev->mc_list = i->next; idev->mc_list = i->next;
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
ip6_mc_clear_src(i);
ma_put(i); ma_put(i);
write_lock_bh(&idev->lock); write_lock_bh(&idev->lock);
} }

View File

@ -135,8 +135,6 @@ static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
((nib & 0xF) << 8) | field); ((nib & 0xF) << 8) | field);
} }
#define MPTCP_PM_MAX_ADDR 4
struct mptcp_addr_info { struct mptcp_addr_info {
sa_family_t family; sa_family_t family;
__be16 port; __be16 port;
@ -234,10 +232,7 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk)
{ {
struct mptcp_sock *msk = mptcp_sk(sk); struct mptcp_sock *msk = mptcp_sk(sk);
if (list_empty(&msk->rtx_queue)) return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
return NULL;
return list_first_entry(&msk->rtx_queue, struct mptcp_data_frag, list);
} }
struct mptcp_subflow_request_sock { struct mptcp_subflow_request_sock {

View File

@ -1053,8 +1053,10 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
err = tcp_set_ulp(sf->sk, "mptcp"); err = tcp_set_ulp(sf->sk, "mptcp");
release_sock(sf->sk); release_sock(sf->sk);
if (err) if (err) {
sock_release(sf);
return err; return err;
}
/* the newly created socket really belongs to the owning MPTCP master /* the newly created socket really belongs to the owning MPTCP master
* socket, even if for additional subflows the allocation is performed * socket, even if for additional subflows the allocation is performed

View File

@ -939,7 +939,8 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
filter->mark.mask = 0xffffffff; filter->mark.mask = 0xffffffff;
} }
} else if (cda[CTA_MARK_MASK]) { } else if (cda[CTA_MARK_MASK]) {
return ERR_PTR(-EINVAL); err = -EINVAL;
goto err_filter;
} }
#endif #endif
if (!cda[CTA_FILTER]) if (!cda[CTA_FILTER])
@ -947,15 +948,17 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
err = ctnetlink_parse_zone(cda[CTA_ZONE], &filter->zone); err = ctnetlink_parse_zone(cda[CTA_ZONE], &filter->zone);
if (err < 0) if (err < 0)
return ERR_PTR(err); goto err_filter;
err = ctnetlink_parse_filter(cda[CTA_FILTER], filter); err = ctnetlink_parse_filter(cda[CTA_FILTER], filter);
if (err < 0) if (err < 0)
return ERR_PTR(err); goto err_filter;
if (filter->orig_flags) { if (filter->orig_flags) {
if (!cda[CTA_TUPLE_ORIG]) if (!cda[CTA_TUPLE_ORIG]) {
return ERR_PTR(-EINVAL); err = -EINVAL;
goto err_filter;
}
err = ctnetlink_parse_tuple_filter(cda, &filter->orig, err = ctnetlink_parse_tuple_filter(cda, &filter->orig,
CTA_TUPLE_ORIG, CTA_TUPLE_ORIG,
@ -963,23 +966,32 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
&filter->zone, &filter->zone,
filter->orig_flags); filter->orig_flags);
if (err < 0) if (err < 0)
return ERR_PTR(err); goto err_filter;
} }
if (filter->reply_flags) { if (filter->reply_flags) {
if (!cda[CTA_TUPLE_REPLY]) if (!cda[CTA_TUPLE_REPLY]) {
return ERR_PTR(-EINVAL); err = -EINVAL;
goto err_filter;
}
err = ctnetlink_parse_tuple_filter(cda, &filter->reply, err = ctnetlink_parse_tuple_filter(cda, &filter->reply,
CTA_TUPLE_REPLY, CTA_TUPLE_REPLY,
filter->family, filter->family,
&filter->zone, &filter->zone,
filter->orig_flags); filter->orig_flags);
if (err < 0) if (err < 0) {
return ERR_PTR(err); err = -EINVAL;
goto err_filter;
}
} }
return filter; return filter;
err_filter:
kfree(filter);
return ERR_PTR(err);
} }
static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda) static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda)

View File

@ -387,51 +387,6 @@ static void nf_flow_offload_work_gc(struct work_struct *work)
queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
} }
int nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
flow_setup_cb_t *cb, void *cb_priv)
{
struct flow_block *block = &flow_table->flow_block;
struct flow_block_cb *block_cb;
int err = 0;
down_write(&flow_table->flow_block_lock);
block_cb = flow_block_cb_lookup(block, cb, cb_priv);
if (block_cb) {
err = -EEXIST;
goto unlock;
}
block_cb = flow_block_cb_alloc(cb, cb_priv, cb_priv, NULL);
if (IS_ERR(block_cb)) {
err = PTR_ERR(block_cb);
goto unlock;
}
list_add_tail(&block_cb->list, &block->cb_list);
unlock:
up_write(&flow_table->flow_block_lock);
return err;
}
EXPORT_SYMBOL_GPL(nf_flow_table_offload_add_cb);
void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
flow_setup_cb_t *cb, void *cb_priv)
{
struct flow_block *block = &flow_table->flow_block;
struct flow_block_cb *block_cb;
down_write(&flow_table->flow_block_lock);
block_cb = flow_block_cb_lookup(block, cb, cb_priv);
if (block_cb) {
list_del(&block_cb->list);
flow_block_cb_free(block_cb);
} else {
WARN_ON(true);
}
up_write(&flow_table->flow_block_lock);
}
EXPORT_SYMBOL_GPL(nf_flow_table_offload_del_cb);
static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff, static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
__be16 port, __be16 new_port) __be16 port, __be16 new_port)

View File

@ -6550,12 +6550,22 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
return err; return err;
} }
static void nft_flowtable_hook_release(struct nft_flowtable_hook *flowtable_hook)
{
struct nft_hook *this, *next;
list_for_each_entry_safe(this, next, &flowtable_hook->list, list) {
list_del(&this->list);
kfree(this);
}
}
static int nft_delflowtable_hook(struct nft_ctx *ctx, static int nft_delflowtable_hook(struct nft_ctx *ctx,
struct nft_flowtable *flowtable) struct nft_flowtable *flowtable)
{ {
const struct nlattr * const *nla = ctx->nla; const struct nlattr * const *nla = ctx->nla;
struct nft_flowtable_hook flowtable_hook; struct nft_flowtable_hook flowtable_hook;
struct nft_hook *this, *next, *hook; struct nft_hook *this, *hook;
struct nft_trans *trans; struct nft_trans *trans;
int err; int err;
@ -6564,33 +6574,40 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
if (err < 0) if (err < 0)
return err; return err;
list_for_each_entry_safe(this, next, &flowtable_hook.list, list) { list_for_each_entry(this, &flowtable_hook.list, list) {
hook = nft_hook_list_find(&flowtable->hook_list, this); hook = nft_hook_list_find(&flowtable->hook_list, this);
if (!hook) { if (!hook) {
err = -ENOENT; err = -ENOENT;
goto err_flowtable_del_hook; goto err_flowtable_del_hook;
} }
hook->inactive = true; hook->inactive = true;
list_del(&this->list);
kfree(this);
} }
trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE, trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
sizeof(struct nft_trans_flowtable)); sizeof(struct nft_trans_flowtable));
if (!trans) if (!trans) {
return -ENOMEM; err = -ENOMEM;
goto err_flowtable_del_hook;
}
nft_trans_flowtable(trans) = flowtable; nft_trans_flowtable(trans) = flowtable;
nft_trans_flowtable_update(trans) = true; nft_trans_flowtable_update(trans) = true;
INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans)); INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
nft_flowtable_hook_release(&flowtable_hook);
list_add_tail(&trans->list, &ctx->net->nft.commit_list); list_add_tail(&trans->list, &ctx->net->nft.commit_list);
return 0; return 0;
err_flowtable_del_hook: err_flowtable_del_hook:
list_for_each_entry(hook, &flowtable_hook.list, list) list_for_each_entry(this, &flowtable_hook.list, list) {
hook = nft_hook_list_find(&flowtable->hook_list, this);
if (!hook)
break;
hook->inactive = false; hook->inactive = false;
}
nft_flowtable_hook_release(&flowtable_hook);
return err; return err;
} }

View File

@ -1242,7 +1242,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
end += NFT_PIPAPO_GROUPS_PADDED_SIZE(f); end += NFT_PIPAPO_GROUPS_PADDED_SIZE(f);
} }
if (!*this_cpu_ptr(m->scratch) || bsize_max > m->bsize_max) { if (!*get_cpu_ptr(m->scratch) || bsize_max > m->bsize_max) {
put_cpu_ptr(m->scratch);
err = pipapo_realloc_scratch(m, bsize_max); err = pipapo_realloc_scratch(m, bsize_max);
if (err) if (err)
return err; return err;
@ -1250,6 +1252,8 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
this_cpu_write(nft_pipapo_scratch_index, false); this_cpu_write(nft_pipapo_scratch_index, false);
m->bsize_max = bsize_max; m->bsize_max = bsize_max;
} else {
put_cpu_ptr(m->scratch);
} }
*ext2 = &e->ext; *ext2 = &e->ext;

View File

@ -271,12 +271,14 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
if (nft_rbtree_interval_start(new)) { if (nft_rbtree_interval_start(new)) {
if (nft_rbtree_interval_end(rbe) && if (nft_rbtree_interval_end(rbe) &&
nft_set_elem_active(&rbe->ext, genmask)) nft_set_elem_active(&rbe->ext, genmask) &&
!nft_set_elem_expired(&rbe->ext))
overlap = false; overlap = false;
} else { } else {
overlap = nft_rbtree_interval_end(rbe) && overlap = nft_rbtree_interval_end(rbe) &&
nft_set_elem_active(&rbe->ext, nft_set_elem_active(&rbe->ext,
genmask); genmask) &&
!nft_set_elem_expired(&rbe->ext);
} }
} else if (d > 0) { } else if (d > 0) {
p = &parent->rb_right; p = &parent->rb_right;
@ -284,9 +286,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
if (nft_rbtree_interval_end(new)) { if (nft_rbtree_interval_end(new)) {
overlap = nft_rbtree_interval_end(rbe) && overlap = nft_rbtree_interval_end(rbe) &&
nft_set_elem_active(&rbe->ext, nft_set_elem_active(&rbe->ext,
genmask); genmask) &&
!nft_set_elem_expired(&rbe->ext);
} else if (nft_rbtree_interval_end(rbe) && } else if (nft_rbtree_interval_end(rbe) &&
nft_set_elem_active(&rbe->ext, genmask)) { nft_set_elem_active(&rbe->ext, genmask) &&
!nft_set_elem_expired(&rbe->ext)) {
overlap = true; overlap = true;
} }
} else { } else {
@ -294,15 +298,18 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
nft_rbtree_interval_start(new)) { nft_rbtree_interval_start(new)) {
p = &parent->rb_left; p = &parent->rb_left;
if (nft_set_elem_active(&rbe->ext, genmask)) if (nft_set_elem_active(&rbe->ext, genmask) &&
!nft_set_elem_expired(&rbe->ext))
overlap = false; overlap = false;
} else if (nft_rbtree_interval_start(rbe) && } else if (nft_rbtree_interval_start(rbe) &&
nft_rbtree_interval_end(new)) { nft_rbtree_interval_end(new)) {
p = &parent->rb_right; p = &parent->rb_right;
if (nft_set_elem_active(&rbe->ext, genmask)) if (nft_set_elem_active(&rbe->ext, genmask) &&
!nft_set_elem_expired(&rbe->ext))
overlap = false; overlap = false;
} else if (nft_set_elem_active(&rbe->ext, genmask)) { } else if (nft_set_elem_active(&rbe->ext, genmask) &&
!nft_set_elem_expired(&rbe->ext)) {
*ext = &rbe->ext; *ext = &rbe->ext;
return -EEXIST; return -EEXIST;
} else { } else {

View File

@ -264,7 +264,13 @@ struct rds_ib_device {
int *vector_load; int *vector_load;
}; };
#define ibdev_to_node(ibdev) dev_to_node((ibdev)->dev.parent) static inline int ibdev_to_node(struct ib_device *ibdev)
{
struct device *parent;
parent = ibdev->dev.parent;
return parent ? dev_to_node(parent) : NUMA_NO_NODE;
}
#define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) #define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev)
/* bits for i_ack_flags */ /* bits for i_ack_flags */

View File

@ -1543,17 +1543,6 @@ static void __exit ct_cleanup_module(void)
destroy_workqueue(act_ct_wq); destroy_workqueue(act_ct_wq);
} }
void tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie)
{
enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK;
struct nf_conn *ct;
ct = (struct nf_conn *)(cookie & NFCT_PTRMASK);
nf_conntrack_get(&ct->ct_general);
nf_ct_set(skb, ct, ctinfo);
}
EXPORT_SYMBOL_GPL(tcf_ct_flow_table_restore_skb);
module_init(ct_init_module); module_init(ct_init_module);
module_exit(ct_cleanup_module); module_exit(ct_cleanup_module);
MODULE_AUTHOR("Paul Blakey <paulb@mellanox.com>"); MODULE_AUTHOR("Paul Blakey <paulb@mellanox.com>");