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

Pull networking fixes and cleanups from David Miller:

 1) Revert bogus nla_ok() change, from Alexey Dobriyan.

 2) Various bpf validator fixes from Daniel Borkmann.

 3) Add some necessary SET_NETDEV_DEV() calls to hsis_femac and hip04
    drivers, from Dongpo Li.

 4) Several ethtool ksettings conversions from Philippe Reynes.

 5) Fix bugs in inet port management wrt. soreuseport, from Tom Herbert.

 6) XDP support for virtio_net, from John Fastabend.

 7) Fix NAT handling within a vrf, from David Ahern.

 8) Endianness fixes in dpaa_eth driver, from Claudiu Manoil

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (63 commits)
  net: mv643xx_eth: fix build failure
  isdn: Constify some function parameters
  mlxsw: spectrum: Mark split ports as such
  cgroup: Fix CGROUP_BPF config
  qed: fix old-style function definition
  net: ipv6: check route protocol when deleting routes
  r6040: move spinlock in r6040_close as SOFTIRQ-unsafe lock order detected
  irda: w83977af_ir: cleanup an indent issue
  net: sfc: use new api ethtool_{get|set}_link_ksettings
  net: davicom: dm9000: use new api ethtool_{get|set}_link_ksettings
  net: cirrus: ep93xx: use new api ethtool_{get|set}_link_ksettings
  net: chelsio: cxgb3: use new api ethtool_{get|set}_link_ksettings
  net: chelsio: cxgb2: use new api ethtool_{get|set}_link_ksettings
  bpf: fix mark_reg_unknown_value for spilled regs on map value marking
  bpf: fix overflow in prog accounting
  bpf: dynamically allocate digest scratch buffer
  gtp: Fix initialization of Flags octet in GTPv1 header
  gtp: gtp_check_src_ms_ipv4() always return success
  net/x25: use designated initializers
  isdn: use designated initializers
  ...
This commit is contained in:
Linus Torvalds 2016-12-17 20:17:04 -08:00
commit 52f40e9d65
71 changed files with 1206 additions and 446 deletions

View File

@ -5163,6 +5163,12 @@ S: Maintained
F: drivers/net/ethernet/freescale/fman
F: Documentation/devicetree/bindings/powerpc/fsl/fman.txt
FREESCALE QORIQ DPAA ETHERNET DRIVER
M: Madalin Bucur <madalin.bucur@nxp.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/freescale/dpaa
FREESCALE SOC DRIVERS
M: Scott Wood <oss@buserror.net>
L: linuxppc-dev@lists.ozlabs.org

View File

@ -2565,22 +2565,22 @@ static int gigaset_post_reset(struct usb_interface *intf)
static const struct gigaset_ops gigops = {
gigaset_write_cmd,
gigaset_write_room,
gigaset_chars_in_buffer,
gigaset_brkchars,
gigaset_init_bchannel,
gigaset_close_bchannel,
gigaset_initbcshw,
gigaset_freebcshw,
gigaset_reinitbcshw,
gigaset_initcshw,
gigaset_freecshw,
gigaset_set_modem_ctrl,
gigaset_baud_rate,
gigaset_set_line_ctrl,
gigaset_isoc_send_skb,
gigaset_isoc_input,
.write_cmd = gigaset_write_cmd,
.write_room = gigaset_write_room,
.chars_in_buffer = gigaset_chars_in_buffer,
.brkchars = gigaset_brkchars,
.init_bchannel = gigaset_init_bchannel,
.close_bchannel = gigaset_close_bchannel,
.initbcshw = gigaset_initbcshw,
.freebcshw = gigaset_freebcshw,
.reinitbcshw = gigaset_reinitbcshw,
.initcshw = gigaset_initcshw,
.freecshw = gigaset_freecshw,
.set_modem_ctrl = gigaset_set_modem_ctrl,
.baud_rate = gigaset_baud_rate,
.set_line_ctrl = gigaset_set_line_ctrl,
.send_skb = gigaset_isoc_send_skb,
.handle_input = gigaset_isoc_input,
};
/* bas_gigaset_init

View File

@ -445,22 +445,22 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
}
static const struct gigaset_ops ops = {
gigaset_write_cmd,
gigaset_write_room,
gigaset_chars_in_buffer,
gigaset_brkchars,
gigaset_init_bchannel,
gigaset_close_bchannel,
gigaset_initbcshw,
gigaset_freebcshw,
gigaset_reinitbcshw,
gigaset_initcshw,
gigaset_freecshw,
gigaset_set_modem_ctrl,
gigaset_baud_rate,
gigaset_set_line_ctrl,
gigaset_m10x_send_skb, /* asyncdata.c */
gigaset_m10x_input, /* asyncdata.c */
.write_cmd = gigaset_write_cmd,
.write_room = gigaset_write_room,
.chars_in_buffer = gigaset_chars_in_buffer,
.brkchars = gigaset_brkchars,
.init_bchannel = gigaset_init_bchannel,
.close_bchannel = gigaset_close_bchannel,
.initbcshw = gigaset_initbcshw,
.freebcshw = gigaset_freebcshw,
.reinitbcshw = gigaset_reinitbcshw,
.initcshw = gigaset_initcshw,
.freecshw = gigaset_freecshw,
.set_modem_ctrl = gigaset_set_modem_ctrl,
.baud_rate = gigaset_baud_rate,
.set_line_ctrl = gigaset_set_line_ctrl,
.send_skb = gigaset_m10x_send_skb, /* asyncdata.c */
.handle_input = gigaset_m10x_input, /* asyncdata.c */
};

View File

@ -862,22 +862,22 @@ static int gigaset_pre_reset(struct usb_interface *intf)
}
static const struct gigaset_ops ops = {
gigaset_write_cmd,
gigaset_write_room,
gigaset_chars_in_buffer,
gigaset_brkchars,
gigaset_init_bchannel,
gigaset_close_bchannel,
gigaset_initbcshw,
gigaset_freebcshw,
gigaset_reinitbcshw,
gigaset_initcshw,
gigaset_freecshw,
gigaset_set_modem_ctrl,
gigaset_baud_rate,
gigaset_set_line_ctrl,
gigaset_m10x_send_skb,
gigaset_m10x_input,
.write_cmd = gigaset_write_cmd,
.write_room = gigaset_write_room,
.chars_in_buffer = gigaset_chars_in_buffer,
.brkchars = gigaset_brkchars,
.init_bchannel = gigaset_init_bchannel,
.close_bchannel = gigaset_close_bchannel,
.initbcshw = gigaset_initbcshw,
.freebcshw = gigaset_freebcshw,
.reinitbcshw = gigaset_reinitbcshw,
.initcshw = gigaset_initcshw,
.freecshw = gigaset_freecshw,
.set_modem_ctrl = gigaset_set_modem_ctrl,
.baud_rate = gigaset_baud_rate,
.set_line_ctrl = gigaset_set_line_ctrl,
.send_skb = gigaset_m10x_send_skb,
.handle_input = gigaset_m10x_input,
};
/*

View File

@ -659,7 +659,7 @@ int jiftime(char *s, long mark)
static u_char tmpbuf[HISAX_STATUS_BUFSIZE];
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt,
va_list args)
{
/* if head == NULL the fmt contains the full info */
@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
u_char *p;
isdn_ctrl ic;
int len;
const u_char *data;
if (!cs) {
printk(KERN_WARNING "HiSax: No CardStatus for message");
return;
}
spin_lock_irqsave(&cs->statlock, flags);
p = tmpbuf;
if (head) {
p = tmpbuf;
p += jiftime(p, jiffies);
p += sprintf(p, " %s", head);
p += vsprintf(p, fmt, args);
*p++ = '\n';
*p = 0;
len = p - tmpbuf;
p = tmpbuf;
data = tmpbuf;
} else {
p = fmt;
data = fmt;
len = strlen(fmt);
}
if (len > HISAX_STATUS_BUFSIZE) {
@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
if (i >= len)
i = len;
len -= i;
memcpy(cs->status_write, p, i);
memcpy(cs->status_write, data, i);
cs->status_write += i;
if (cs->status_write > cs->status_end)
cs->status_write = cs->status_buf;
p += i;
if (len) {
memcpy(cs->status_write, p, len);
memcpy(cs->status_write, data + i, len);
cs->status_write += len;
}
#ifdef KERNELSTACK_DEBUG
@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
}
}
void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...)
void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...)
{
va_list args;

View File

@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark);
int HiSax_command(isdn_ctrl *ic);
int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
__printf(3, 4)
void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...);
__printf(3, 0)
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args);
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args);
void HiSax_reportcard(int cardnr, int sel);
int QuickHex(char *txt, u_char *p, int cnt);
void LogFrame(struct IsdnCardState *cs, u_char *p, int size);

View File

@ -80,9 +80,9 @@ static int isdn_concap_dl_disconn_req(struct concap_proto *concap)
}
struct concap_device_ops isdn_concap_reliable_dl_dops = {
&isdn_concap_dl_data_req,
&isdn_concap_dl_connect_req,
&isdn_concap_dl_disconn_req
.data_req = &isdn_concap_dl_data_req,
.connect_req = &isdn_concap_dl_connect_req,
.disconn_req = &isdn_concap_dl_disconn_req
};
/* The following should better go into a dedicated source file such that

View File

@ -53,14 +53,14 @@ static int isdn_x25iface_disconn_ind(struct concap_proto *);
static struct concap_proto_ops ix25_pops = {
&isdn_x25iface_proto_new,
&isdn_x25iface_proto_del,
&isdn_x25iface_proto_restart,
&isdn_x25iface_proto_close,
&isdn_x25iface_xmit,
&isdn_x25iface_receive,
&isdn_x25iface_connect_ind,
&isdn_x25iface_disconn_ind
.proto_new = &isdn_x25iface_proto_new,
.proto_del = &isdn_x25iface_proto_del,
.restart = &isdn_x25iface_proto_restart,
.close = &isdn_x25iface_proto_close,
.encap_and_xmit = &isdn_x25iface_xmit,
.data_ind = &isdn_x25iface_receive,
.connect_ind = &isdn_x25iface_connect_ind,
.disconn_ind = &isdn_x25iface_disconn_ind
};
/* error message helper function */

View File

@ -1775,6 +1775,9 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
continue;
if (!ds->ports[port].netdev)
continue;
if (vlan.data[i] ==
GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
continue;
@ -1783,6 +1786,9 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
chip->ports[port].bridge_dev)
break; /* same bridge, check next VLAN */
if (!chip->ports[i].bridge_dev)
continue;
netdev_warn(ds->ports[port].netdev,
"hardware VLAN %d already used by %s\n",
vlan.vid,

View File

@ -627,6 +627,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
spin_lock_init(&vp->lock);
setup_timer(&vp->timer, corkscrew_timer, (unsigned long) dev);
/* Read the station address from the EEPROM. */
EL3WINDOW(0);
for (i = 0; i < 0x18; i++) {
@ -707,6 +709,7 @@ static int corkscrew_open(struct net_device *dev)
{
int ioaddr = dev->base_addr;
struct corkscrew_private *vp = netdev_priv(dev);
bool armtimer = false;
__u32 config;
int i;
@ -731,12 +734,7 @@ static int corkscrew_open(struct net_device *dev)
if (corkscrew_debug > 1)
pr_debug("%s: Initial media type %s.\n",
dev->name, media_tbl[dev->if_port].name);
init_timer(&vp->timer);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
vp->timer.data = (unsigned long) dev;
vp->timer.function = corkscrew_timer; /* timer handler */
add_timer(&vp->timer);
armtimer = true;
} else
dev->if_port = vp->default_media;
@ -776,6 +774,9 @@ static int corkscrew_open(struct net_device *dev)
return -EAGAIN;
}
if (armtimer)
mod_timer(&vp->timer, jiffies + media_tbl[dev->if_port].wait);
if (corkscrew_debug > 1) {
EL3WINDOW(4);
pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
@ -1426,7 +1427,7 @@ static int corkscrew_close(struct net_device *dev)
dev->name, rx_nocopy, rx_copy, queued_packet);
}
del_timer(&vp->timer);
del_timer_sync(&vp->timer);
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);

View File

@ -1676,10 +1676,10 @@ bna_cb_ioceth_reset(void *arg)
}
static struct bfa_ioc_cbfn bna_ioceth_cbfn = {
bna_cb_ioceth_enable,
bna_cb_ioceth_disable,
bna_cb_ioceth_hbfail,
bna_cb_ioceth_reset
.enable_cbfn = bna_cb_ioceth_enable,
.disable_cbfn = bna_cb_ioceth_disable,
.hbfail_cbfn = bna_cb_ioceth_hbfail,
.reset_cbfn = bna_cb_ioceth_reset
};
static void bna_attr_init(struct bna_ioceth *ioceth)

View File

@ -31,4 +31,13 @@ config MACB
To compile this driver as a module, choose M here: the module
will be called macb.
config MACB_PCI
tristate "Cadence PCI MACB/GEM support"
depends on MACB && PCI && COMMON_CLK
---help---
This is PCI wrapper for MACB driver.
To compile this driver as a module, choose M here: the module
will be called macb_pci.
endif # NET_CADENCE

View File

@ -3,3 +3,4 @@
#
obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_MACB_PCI) += macb_pci.o

View File

@ -404,6 +404,8 @@ static int macb_mii_probe(struct net_device *dev)
phy_irq = gpio_to_irq(pdata->phy_irq_pin);
phydev->irq = (phy_irq < 0) ? PHY_POLL : phy_irq;
}
} else {
phydev->irq = PHY_POLL;
}
/* attach the mac to the phy */
@ -482,6 +484,9 @@ static int macb_mii_init(struct macb *bp)
goto err_out_unregister_bus;
}
} else {
for (i = 0; i < PHY_MAX_ADDR; i++)
bp->mii_bus->irq[i] = PHY_POLL;
if (pdata)
bp->mii_bus->phy_mask = pdata->phy_mask;
@ -2523,16 +2528,24 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
struct clk **hclk, struct clk **tx_clk,
struct clk **rx_clk)
{
struct macb_platform_data *pdata;
int err;
*pclk = devm_clk_get(&pdev->dev, "pclk");
pdata = dev_get_platdata(&pdev->dev);
if (pdata) {
*pclk = pdata->pclk;
*hclk = pdata->hclk;
} else {
*pclk = devm_clk_get(&pdev->dev, "pclk");
*hclk = devm_clk_get(&pdev->dev, "hclk");
}
if (IS_ERR(*pclk)) {
err = PTR_ERR(*pclk);
dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err);
return err;
}
*hclk = devm_clk_get(&pdev->dev, "hclk");
if (IS_ERR(*hclk)) {
err = PTR_ERR(*hclk);
dev_err(&pdev->dev, "failed to get hclk (%u)\n", err);
@ -3107,15 +3120,23 @@ static const struct of_device_id macb_dt_ids[] = {
MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */
static const struct macb_config default_gem_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
.jumbo_max_len = 10240,
};
static int macb_probe(struct platform_device *pdev)
{
const struct macb_config *macb_config = &default_gem_config;
int (*clk_init)(struct platform_device *, struct clk **,
struct clk **, struct clk **, struct clk **)
= macb_clk_init;
int (*init)(struct platform_device *) = macb_init;
= macb_config->clk_init;
int (*init)(struct platform_device *) = macb_config->init;
struct device_node *np = pdev->dev.of_node;
struct device_node *phy_node;
const struct macb_config *macb_config = NULL;
struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
unsigned int queue_mask, num_queues;
struct macb_platform_data *pdata;

View File

@ -0,0 +1,153 @@
/**
* macb_pci.c - Cadence GEM PCI wrapper.
*
* Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
*
* Authors: Rafal Ozieblo <rafalo@cadence.com>
* Bartosz Folta <bfolta@cadence.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_data/macb.h>
#include <linux/platform_device.h>
#include "macb.h"
#define PCI_DRIVER_NAME "macb_pci"
#define PLAT_DRIVER_NAME "macb"
#define CDNS_VENDOR_ID 0x17cd
#define CDNS_DEVICE_ID 0xe007
#define GEM_PCLK_RATE 50000000
#define GEM_HCLK_RATE 50000000
static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int err;
struct platform_device *plat_dev;
struct platform_device_info plat_info;
struct macb_platform_data plat_data;
struct resource res[2];
/* sanity check */
if (!id)
return -EINVAL;
/* enable pci device */
err = pci_enable_device(pdev);
if (err < 0) {
dev_err(&pdev->dev, "Enabling PCI device has failed: 0x%04X",
err);
return -EACCES;
}
pci_set_master(pdev);
/* set up resources */
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
res[0].start = pdev->resource[0].start;
res[0].end = pdev->resource[0].end;
res[0].name = PCI_DRIVER_NAME;
res[0].flags = IORESOURCE_MEM;
res[1].start = pdev->irq;
res[1].name = PCI_DRIVER_NAME;
res[1].flags = IORESOURCE_IRQ;
dev_info(&pdev->dev, "EMAC physical base addr = 0x%p\n",
(void *)(uintptr_t)pci_resource_start(pdev, 0));
/* set up macb platform data */
memset(&plat_data, 0, sizeof(plat_data));
/* initialize clocks */
plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
GEM_PCLK_RATE);
if (IS_ERR(plat_data.pclk)) {
err = PTR_ERR(plat_data.pclk);
goto err_pclk_register;
}
plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
GEM_HCLK_RATE);
if (IS_ERR(plat_data.hclk)) {
err = PTR_ERR(plat_data.hclk);
goto err_hclk_register;
}
/* set up platform device info */
memset(&plat_info, 0, sizeof(plat_info));
plat_info.parent = &pdev->dev;
plat_info.fwnode = pdev->dev.fwnode;
plat_info.name = PLAT_DRIVER_NAME;
plat_info.id = pdev->devfn;
plat_info.res = res;
plat_info.num_res = ARRAY_SIZE(res);
plat_info.data = &plat_data;
plat_info.size_data = sizeof(plat_data);
plat_info.dma_mask = DMA_BIT_MASK(32);
/* register platform device */
plat_dev = platform_device_register_full(&plat_info);
if (IS_ERR(plat_dev)) {
err = PTR_ERR(plat_dev);
goto err_plat_dev_register;
}
pci_set_drvdata(pdev, plat_dev);
return 0;
err_plat_dev_register:
clk_unregister(plat_data.hclk);
err_hclk_register:
clk_unregister(plat_data.pclk);
err_pclk_register:
pci_disable_device(pdev);
return err;
}
static void macb_remove(struct pci_dev *pdev)
{
struct platform_device *plat_dev = pci_get_drvdata(pdev);
struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
platform_device_unregister(plat_dev);
pci_disable_device(pdev);
clk_unregister(plat_data->pclk);
clk_unregister(plat_data->hclk);
}
static struct pci_device_id dev_id_table[] = {
{ PCI_DEVICE(CDNS_VENDOR_ID, CDNS_DEVICE_ID), },
{ 0, }
};
static struct pci_driver macb_pci_driver = {
.name = PCI_DRIVER_NAME,
.id_table = dev_id_table,
.probe = macb_probe,
.remove = macb_remove,
};
module_pci_driver(macb_pci_driver);
MODULE_DEVICE_TABLE(pci, dev_id_table);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cadence NIC PCI wrapper");

View File

@ -568,28 +568,33 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct adapter *adapter = dev->ml_priv;
struct port_info *p = &adapter->port[dev->if_port];
u32 supported, advertising;
cmd->supported = p->link_config.supported;
cmd->advertising = p->link_config.advertising;
supported = p->link_config.supported;
advertising = p->link_config.advertising;
if (netif_carrier_ok(dev)) {
ethtool_cmd_speed_set(cmd, p->link_config.speed);
cmd->duplex = p->link_config.duplex;
cmd->base.speed = p->link_config.speed;
cmd->base.duplex = p->link_config.duplex;
} else {
ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
cmd->duplex = DUPLEX_UNKNOWN;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
cmd->phy_address = p->phy->mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
cmd->base.port = (supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
cmd->base.phy_address = p->phy->mdio.prtad;
cmd->base.autoneg = p->link_config.autoneg;
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
supported);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
advertising);
return 0;
}
@ -628,36 +633,41 @@ static int speed_duplex_to_caps(int speed, int duplex)
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
ADVERTISED_10000baseT_Full)
static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
struct adapter *adapter = dev->ml_priv;
struct port_info *p = &adapter->port[dev->if_port];
struct link_config *lc = &p->link_config;
u32 advertising;
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
if (!(lc->supported & SUPPORTED_Autoneg))
return -EOPNOTSUPP; /* can't change speed/duplex */
if (cmd->autoneg == AUTONEG_DISABLE) {
u32 speed = ethtool_cmd_speed(cmd);
int cap = speed_duplex_to_caps(speed, cmd->duplex);
if (cmd->base.autoneg == AUTONEG_DISABLE) {
u32 speed = cmd->base.speed;
int cap = speed_duplex_to_caps(speed, cmd->base.duplex);
if (!(lc->supported & cap) || (speed == SPEED_1000))
return -EINVAL;
lc->requested_speed = speed;
lc->requested_duplex = cmd->duplex;
lc->requested_duplex = cmd->base.duplex;
lc->advertising = 0;
} else {
cmd->advertising &= ADVERTISED_MASK;
if (cmd->advertising & (cmd->advertising - 1))
cmd->advertising = lc->supported;
cmd->advertising &= lc->supported;
if (!cmd->advertising)
advertising &= ADVERTISED_MASK;
if (advertising & (advertising - 1))
advertising = lc->supported;
advertising &= lc->supported;
if (!advertising)
return -EINVAL;
lc->requested_speed = SPEED_INVALID;
lc->requested_duplex = DUPLEX_INVALID;
lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
lc->advertising = advertising | ADVERTISED_Autoneg;
}
lc->autoneg = cmd->autoneg;
lc->autoneg = cmd->base.autoneg;
if (netif_running(dev))
t1_link_start(p->phy, p->mac, lc);
return 0;
@ -788,8 +798,6 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
}
static const struct ethtool_ops t1_ethtool_ops = {
.get_settings = get_settings,
.set_settings = set_settings,
.get_drvinfo = get_drvinfo,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
@ -807,6 +815,8 @@ static const struct ethtool_ops t1_ethtool_ops = {
.get_ethtool_stats = get_stats,
.get_regs_len = get_regs_len,
.get_regs = get_regs,
.get_link_ksettings = get_link_ksettings,
.set_link_ksettings = set_link_ksettings,
};
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)

View File

@ -1801,27 +1801,31 @@ static int set_phys_id(struct net_device *dev,
return 0;
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct port_info *p = netdev_priv(dev);
u32 supported;
cmd->supported = p->link_config.supported;
cmd->advertising = p->link_config.advertising;
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
p->link_config.supported);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
p->link_config.advertising);
if (netif_carrier_ok(dev)) {
ethtool_cmd_speed_set(cmd, p->link_config.speed);
cmd->duplex = p->link_config.duplex;
cmd->base.speed = p->link_config.speed;
cmd->base.duplex = p->link_config.duplex;
} else {
ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
cmd->duplex = DUPLEX_UNKNOWN;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
cmd->phy_address = p->phy.mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
ethtool_convert_link_mode_to_legacy_u32(&supported,
cmd->link_modes.supported);
cmd->base.port = (supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
cmd->base.phy_address = p->phy.mdio.prtad;
cmd->base.autoneg = p->link_config.autoneg;
return 0;
}
@ -1860,44 +1864,49 @@ static int speed_duplex_to_caps(int speed, int duplex)
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
ADVERTISED_10000baseT_Full)
static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
struct port_info *p = netdev_priv(dev);
struct link_config *lc = &p->link_config;
u32 advertising;
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
if (!(lc->supported & SUPPORTED_Autoneg)) {
/*
* PHY offers a single speed/duplex. See if that's what's
* being requested.
*/
if (cmd->autoneg == AUTONEG_DISABLE) {
u32 speed = ethtool_cmd_speed(cmd);
int cap = speed_duplex_to_caps(speed, cmd->duplex);
if (cmd->base.autoneg == AUTONEG_DISABLE) {
u32 speed = cmd->base.speed;
int cap = speed_duplex_to_caps(speed, cmd->base.duplex);
if (lc->supported & cap)
return 0;
}
return -EINVAL;
}
if (cmd->autoneg == AUTONEG_DISABLE) {
u32 speed = ethtool_cmd_speed(cmd);
int cap = speed_duplex_to_caps(speed, cmd->duplex);
if (cmd->base.autoneg == AUTONEG_DISABLE) {
u32 speed = cmd->base.speed;
int cap = speed_duplex_to_caps(speed, cmd->base.duplex);
if (!(lc->supported & cap) || (speed == SPEED_1000))
return -EINVAL;
lc->requested_speed = speed;
lc->requested_duplex = cmd->duplex;
lc->requested_duplex = cmd->base.duplex;
lc->advertising = 0;
} else {
cmd->advertising &= ADVERTISED_MASK;
cmd->advertising &= lc->supported;
if (!cmd->advertising)
advertising &= ADVERTISED_MASK;
advertising &= lc->supported;
if (!advertising)
return -EINVAL;
lc->requested_speed = SPEED_INVALID;
lc->requested_duplex = DUPLEX_INVALID;
lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
lc->advertising = advertising | ADVERTISED_Autoneg;
}
lc->autoneg = cmd->autoneg;
lc->autoneg = cmd->base.autoneg;
if (netif_running(dev))
t3_link_start(&p->phy, &p->mac, lc);
return 0;
@ -2097,8 +2106,6 @@ static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
}
static const struct ethtool_ops cxgb_ethtool_ops = {
.get_settings = get_settings,
.set_settings = set_settings,
.get_drvinfo = get_drvinfo,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
@ -2120,6 +2127,8 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.get_regs_len = get_regs_len,
.get_regs = get_regs,
.get_wol = get_wol,
.get_link_ksettings = get_link_ksettings,
.set_link_ksettings = set_link_ksettings,
};
static int in_range(int val, int lo, int hi)

View File

@ -715,16 +715,18 @@ static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
}
static int ep93xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int ep93xx_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct ep93xx_priv *ep = netdev_priv(dev);
return mii_ethtool_gset(&ep->mii, cmd);
return mii_ethtool_get_link_ksettings(&ep->mii, cmd);
}
static int ep93xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int ep93xx_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
struct ep93xx_priv *ep = netdev_priv(dev);
return mii_ethtool_sset(&ep->mii, cmd);
return mii_ethtool_set_link_ksettings(&ep->mii, cmd);
}
static int ep93xx_nway_reset(struct net_device *dev)
@ -741,10 +743,10 @@ static u32 ep93xx_get_link(struct net_device *dev)
static const struct ethtool_ops ep93xx_ethtool_ops = {
.get_drvinfo = ep93xx_get_drvinfo,
.get_settings = ep93xx_get_settings,
.set_settings = ep93xx_set_settings,
.nway_reset = ep93xx_nway_reset,
.get_link = ep93xx_get_link,
.get_link_ksettings = ep93xx_get_link_ksettings,
.set_link_ksettings = ep93xx_set_link_ksettings,
};
static const struct net_device_ops ep93xx_netdev_ops = {

View File

@ -570,19 +570,21 @@ static void dm9000_set_msglevel(struct net_device *dev, u32 value)
dm->msg_enable = value;
}
static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int dm9000_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct board_info *dm = to_dm9000_board(dev);
mii_ethtool_gset(&dm->mii, cmd);
mii_ethtool_get_link_ksettings(&dm->mii, cmd);
return 0;
}
static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int dm9000_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
struct board_info *dm = to_dm9000_board(dev);
return mii_ethtool_sset(&dm->mii, cmd);
return mii_ethtool_set_link_ksettings(&dm->mii, cmd);
}
static int dm9000_nway_reset(struct net_device *dev)
@ -741,8 +743,6 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
static const struct ethtool_ops dm9000_ethtool_ops = {
.get_drvinfo = dm9000_get_drvinfo,
.get_settings = dm9000_get_settings,
.set_settings = dm9000_set_settings,
.get_msglevel = dm9000_get_msglevel,
.set_msglevel = dm9000_set_msglevel,
.nway_reset = dm9000_nway_reset,
@ -752,6 +752,8 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
.get_eeprom_len = dm9000_get_eeprom_len,
.get_eeprom = dm9000_get_eeprom,
.set_eeprom = dm9000_set_eeprom,
.get_link_ksettings = dm9000_get_link_ksettings,
.set_link_ksettings = dm9000_set_link_ksettings,
};
static void dm9000_show_carrier(struct board_info *db,

View File

@ -1,6 +1,6 @@
menuconfig FSL_DPAA_ETH
tristate "DPAA Ethernet"
depends on FSL_SOC && FSL_DPAA && FSL_FMAN
depends on FSL_DPAA && FSL_FMAN
select PHYLIB
select FSL_FMAN_MAC
---help---

View File

@ -733,7 +733,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
/* Enable Congestion State Change Notifications and CS taildrop */
initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
/* Set different thresholds based on the MAC speed.
@ -747,7 +747,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
cs_th = DPAA_CS_THRESHOLD_1G;
qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
initcgr.we_mask |= cpu_to_be16(QM_CGR_WE_CSTD_EN);
initcgr.cgr.cstd_en = QM_CGR_EN;
err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
@ -896,18 +896,18 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
if (dpaa_fq->init) {
memset(&initfq, 0, sizeof(initfq));
initfq.we_mask = QM_INITFQ_WE_FQCTRL;
initfq.we_mask = cpu_to_be16(QM_INITFQ_WE_FQCTRL);
/* Note: we may get to keep an empty FQ in cache */
initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
initfq.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_PREFERINCACHE);
/* Try to reduce the number of portal interrupts for
* Tx Confirmation FQs.
*/
if (dpaa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE);
/* FQ placement */
initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_DESTWQ);
qm_fqd_set_destwq(&initfq.fqd, dpaa_fq->channel, dpaa_fq->wq);
@ -920,8 +920,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
if (dpaa_fq->fq_type == FQ_TYPE_TX ||
dpaa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
dpaa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
initfq.we_mask |= QM_INITFQ_WE_CGID;
initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CGID);
initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_CGE);
initfq.fqd.cgid = (u8)priv->cgr_data.cgr.cgrid;
/* Set a fixed overhead accounting, in an attempt to
* reduce the impact of fixed-size skb shells and the
@ -932,7 +932,7 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
* insufficient value, but even that is better than
* no overhead accounting at all.
*/
initfq.we_mask |= QM_INITFQ_WE_OAC;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_OAC);
qm_fqd_set_oac(&initfq.fqd, QM_OAC_CG);
qm_fqd_set_oal(&initfq.fqd,
min(sizeof(struct sk_buff) +
@ -941,9 +941,9 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
}
if (td_enable) {
initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_TDTHRESH);
qm_fqd_set_taildrop(&initfq.fqd, DPAA_FQ_TD, 1);
initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
initfq.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_TDE);
}
if (dpaa_fq->fq_type == FQ_TYPE_TX) {
@ -951,7 +951,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
if (queue_id >= 0)
confq = priv->conf_fqs[queue_id];
if (confq) {
initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
initfq.we_mask |=
cpu_to_be16(QM_INITFQ_WE_CONTEXTA);
/* ContextA: OVOM=1(use contextA2 bits instead of ICAD)
* A2V=1 (contextA A2 field is valid)
* A0V=1 (contextA A0 field is valid)
@ -959,8 +960,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
* ContextA A2: EBD=1 (deallocate buffers inside FMan)
* ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
*/
initfq.fqd.context_a.hi = 0x1e000000;
initfq.fqd.context_a.lo = 0x80000000;
qm_fqd_context_a_set64(&initfq.fqd,
0x1e00000080000000ULL);
}
}
@ -968,13 +969,13 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
if (priv->use_ingress_cgr &&
(dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
initfq.we_mask |= QM_INITFQ_WE_CGID;
initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CGID);
initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_CGE);
initfq.fqd.cgid = (u8)priv->ingress_cgr.cgrid;
/* Set a fixed overhead accounting, just like for the
* egress CGR.
*/
initfq.we_mask |= QM_INITFQ_WE_OAC;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_OAC);
qm_fqd_set_oac(&initfq.fqd, QM_OAC_CG);
qm_fqd_set_oal(&initfq.fqd,
min(sizeof(struct sk_buff) +
@ -984,9 +985,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable)
/* Initialization common to all ingress queues */
if (dpaa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
initfq.fqd.fq_ctrl |=
QM_FQCTRL_HOLDACTIVE;
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CONTEXTA);
initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE);
initfq.fqd.context_a.stashing.exclusive =
QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
QM_STASHING_EXCL_ANNOTATION;
@ -1350,7 +1350,7 @@ static int dpaa_enable_tx_csum(struct dpaa_priv *priv,
parse_result->l4_off = (u8)skb_transport_offset(skb);
/* Enable L3 (and L4, if TCP or UDP) HW checksum. */
fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
fd->cmd |= cpu_to_be32(FM_FD_CMD_RPD | FM_FD_CMD_DTC);
/* On P1023 and similar platforms fd->cmd interpretation could
* be disabled by setting CONTEXT_A bit ICMD; currently this bit
@ -1732,7 +1732,7 @@ static int skb_to_contig_fd(struct dpaa_priv *priv,
/* Fill in the rest of the FD fields */
qm_fd_set_contig(fd, priv->tx_headroom, skb->len);
fd->cmd |= FM_FD_CMD_FCO;
fd->cmd |= cpu_to_be32(FM_FD_CMD_FCO);
/* Map the entire buffer size that may be seen by FMan, but no more */
addr = dma_map_single(dev, skbh,
@ -1840,7 +1840,7 @@ static int skb_to_sg_fd(struct dpaa_priv *priv,
}
fd->bpid = FSL_DPAA_BPID_INV;
fd->cmd |= FM_FD_CMD_FCO;
fd->cmd |= cpu_to_be32(FM_FD_CMD_FCO);
qm_fd_addr_set64(fd, addr);
return 0;
@ -1867,7 +1867,7 @@ static inline int dpaa_xmit(struct dpaa_priv *priv,
egress_fq = priv->egress_fqs[queue];
if (fd->bpid == FSL_DPAA_BPID_INV)
fd->cmd |= qman_fq_fqid(priv->conf_fqs[queue]);
fd->cmd |= cpu_to_be32(qman_fq_fqid(priv->conf_fqs[queue]));
/* Trace this Tx fd */
trace_dpaa_tx_fd(priv->net_dev, egress_fq, fd);
@ -1960,17 +1960,17 @@ static void dpaa_rx_error(struct net_device *net_dev,
{
if (net_ratelimit())
netif_err(priv, hw, net_dev, "Err FD status = 0x%08x\n",
fd->status & FM_FD_STAT_RX_ERRORS);
be32_to_cpu(fd->status) & FM_FD_STAT_RX_ERRORS);
percpu_priv->stats.rx_errors++;
if (fd->status & FM_FD_ERR_DMA)
if (be32_to_cpu(fd->status) & FM_FD_ERR_DMA)
percpu_priv->rx_errors.dme++;
if (fd->status & FM_FD_ERR_PHYSICAL)
if (be32_to_cpu(fd->status) & FM_FD_ERR_PHYSICAL)
percpu_priv->rx_errors.fpe++;
if (fd->status & FM_FD_ERR_SIZE)
if (be32_to_cpu(fd->status) & FM_FD_ERR_SIZE)
percpu_priv->rx_errors.fse++;
if (fd->status & FM_FD_ERR_PRS_HDR_ERR)
if (be32_to_cpu(fd->status) & FM_FD_ERR_PRS_HDR_ERR)
percpu_priv->rx_errors.phe++;
dpaa_fd_release(net_dev, fd);
@ -1986,7 +1986,7 @@ static void dpaa_tx_error(struct net_device *net_dev,
if (net_ratelimit())
netif_warn(priv, hw, net_dev, "FD status = 0x%08x\n",
fd->status & FM_FD_STAT_TX_ERRORS);
be32_to_cpu(fd->status) & FM_FD_STAT_TX_ERRORS);
percpu_priv->stats.tx_errors++;
@ -2020,10 +2020,11 @@ static void dpaa_tx_conf(struct net_device *net_dev,
{
struct sk_buff *skb;
if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
if (unlikely(be32_to_cpu(fd->status) & FM_FD_STAT_TX_ERRORS)) {
if (net_ratelimit())
netif_warn(priv, hw, net_dev, "FD status = 0x%08x\n",
fd->status & FM_FD_STAT_TX_ERRORS);
be32_to_cpu(fd->status) &
FM_FD_STAT_TX_ERRORS);
percpu_priv->stats.tx_errors++;
}
@ -2100,6 +2101,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
struct sk_buff *skb;
int *count_ptr;
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
net_dev = ((struct dpaa_fq *)fq)->net_dev;
priv = netdev_priv(net_dev);
dpaa_bp = dpaa_bpid2pool(dq->fd.bpid);
@ -2417,12 +2420,12 @@ static int dpaa_ingress_cgr_init(struct dpaa_priv *priv)
}
/* Enable CS TD, but disable Congestion State Change Notifications. */
initcgr.we_mask = QM_CGR_WE_CS_THRES;
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
cs_th = DPAA_INGRESS_CS_THRESHOLD;
qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
initcgr.we_mask |= cpu_to_be16(QM_CGR_WE_CSTD_EN);
initcgr.cgr.cstd_en = QM_CGR_EN;
/* This CGR will be associated with the SWP affined to the current CPU.

View File

@ -828,6 +828,7 @@ static int hip04_mac_probe(struct platform_device *pdev)
priv = netdev_priv(ndev);
priv->ndev = ndev;
platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(d, res);
@ -903,7 +904,6 @@ static int hip04_mac_probe(struct platform_device *pdev)
ndev->priv_flags |= IFF_UNICAST_FLT;
ndev->irq = irq;
netif_napi_add(ndev, &priv->napi, hip04_rx_poll, NAPI_POLL_WEIGHT);
SET_NETDEV_DEV(ndev, &pdev->dev);
hip04_reset_ppe(priv);
if (priv->phy_mode == PHY_INTERFACE_MODE_MII)

View File

@ -805,6 +805,7 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
priv = netdev_priv(ndev);
priv->dev = dev;
@ -882,7 +883,6 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
ndev->netdev_ops = &hisi_femac_netdev_ops;
ndev->ethtool_ops = &hisi_femac_ethtools_ops;
netif_napi_add(ndev, &priv->napi, hisi_femac_poll, FEMAC_POLL_WEIGHT);
SET_NETDEV_DEV(ndev, &pdev->dev);
hisi_femac_port_init(priv);

View File

@ -1181,7 +1181,9 @@ map_failed:
static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
{
struct tcphdr *tcph;
int offset = 0;
int hdr_len;
/* only TCP packets will be aggregated */
if (skb->protocol == htons(ETH_P_IP)) {
@ -1208,14 +1210,20 @@ static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
/* if mss is not set through Large Packet bit/mss in rx buffer,
* expect that the mss will be written to the tcp header checksum.
*/
tcph = (struct tcphdr *)(skb->data + offset);
if (lrg_pkt) {
skb_shinfo(skb)->gso_size = mss;
} else if (offset) {
struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
skb_shinfo(skb)->gso_size = ntohs(tcph->check);
tcph->check = 0;
}
if (skb_shinfo(skb)->gso_size) {
hdr_len = offset + tcph->doff * 4;
skb_shinfo(skb)->gso_segs =
DIV_ROUND_UP(skb->len - hdr_len,
skb_shinfo(skb)->gso_size);
}
}
static int ibmveth_poll(struct napi_struct *napi, int budget)

View File

@ -2713,7 +2713,7 @@ static const struct of_device_id mv643xx_eth_shared_ids[] = {
MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids);
#endif
#if defined(CONFIG_OF) && !defined(CONFIG_MV64X60)
#if defined(CONFIG_OF_IRQ) && !defined(CONFIG_MV64X60)
#define mv643xx_eth_property(_np, _name, _v) \
do { \
u32 tmp; \

View File

@ -2404,7 +2404,7 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
local_port);
return err;
}
err = __mlxsw_sp_port_create(mlxsw_sp, local_port, false,
err = __mlxsw_sp_port_create(mlxsw_sp, local_port, split,
module, width, lane);
if (err)
goto err_port_create;

View File

@ -26,11 +26,11 @@ static inline bool is_bits_set(int value, int mask)
}
static int encx24j600_switch_bank(struct encx24j600_context *ctx,
int bank)
int bank)
{
int ret = 0;
int bank_opcode = BANK_SELECT(bank);
ret = spi_write(ctx->spi, &bank_opcode, 1);
if (ret == 0)
ctx->bank = bank;
@ -39,7 +39,7 @@ static int encx24j600_switch_bank(struct encx24j600_context *ctx,
}
static int encx24j600_cmdn(struct encx24j600_context *ctx, u8 opcode,
const void *buf, size_t len)
const void *buf, size_t len)
{
struct spi_message m;
struct spi_transfer t[2] = { { .tx_buf = &opcode, .len = 1, },
@ -54,12 +54,14 @@ static int encx24j600_cmdn(struct encx24j600_context *ctx, u8 opcode,
static void regmap_lock_mutex(void *context)
{
struct encx24j600_context *ctx = context;
mutex_lock(&ctx->mutex);
}
static void regmap_unlock_mutex(void *context)
{
struct encx24j600_context *ctx = context;
mutex_unlock(&ctx->mutex);
}
@ -128,6 +130,7 @@ static int regmap_encx24j600_sfr_update(struct encx24j600_context *ctx,
if (reg < 0x80) {
int ret = 0;
cmd = banked_code | banked_reg;
if ((banked_reg < 0x16) && (ctx->bank != bank))
ret = encx24j600_switch_bank(ctx, bank);
@ -174,6 +177,7 @@ static int regmap_encx24j600_sfr_write(void *context, u8 reg, u8 *val,
size_t len)
{
struct encx24j600_context *ctx = context;
return regmap_encx24j600_sfr_update(ctx, reg, val, len, WCRU, WCRCODE);
}
@ -228,9 +232,9 @@ int regmap_encx24j600_spi_write(void *context, u8 reg, const u8 *data,
if (reg < 0xc0)
return encx24j600_cmdn(ctx, reg, data, count);
else
/* SPI 1-byte command. Ignore data */
return spi_write(ctx->spi, &reg, 1);
/* SPI 1-byte command. Ignore data */
return spi_write(ctx->spi, &reg, 1);
}
EXPORT_SYMBOL_GPL(regmap_encx24j600_spi_write);
@ -495,6 +499,7 @@ static struct regmap_config phycfg = {
.writeable_reg = encx24j600_phymap_writeable,
.volatile_reg = encx24j600_phymap_volatile,
};
static struct regmap_bus phymap_encx24j600 = {
.reg_write = regmap_encx24j600_phy_reg_write,
.reg_read = regmap_encx24j600_phy_reg_read,

View File

@ -30,7 +30,7 @@
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
static int debug = -1;
module_param(debug, int, 0);
module_param(debug, int, 0000);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
/* SRAM memory layout:
@ -105,6 +105,7 @@ static u16 encx24j600_read_reg(struct encx24j600_priv *priv, u8 reg)
struct net_device *dev = priv->ndev;
unsigned int val = 0;
int ret = regmap_read(priv->ctx.regmap, reg, &val);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d reading reg %02x\n",
__func__, ret, reg);
@ -115,6 +116,7 @@ static void encx24j600_write_reg(struct encx24j600_priv *priv, u8 reg, u16 val)
{
struct net_device *dev = priv->ndev;
int ret = regmap_write(priv->ctx.regmap, reg, val);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d writing reg %02x=%04x\n",
__func__, ret, reg, val);
@ -125,6 +127,7 @@ static void encx24j600_update_reg(struct encx24j600_priv *priv, u8 reg,
{
struct net_device *dev = priv->ndev;
int ret = regmap_update_bits(priv->ctx.regmap, reg, mask, val);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d updating reg %02x=%04x~%04x\n",
__func__, ret, reg, val, mask);
@ -135,6 +138,7 @@ static u16 encx24j600_read_phy(struct encx24j600_priv *priv, u8 reg)
struct net_device *dev = priv->ndev;
unsigned int val = 0;
int ret = regmap_read(priv->ctx.phymap, reg, &val);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d reading %02x\n",
__func__, ret, reg);
@ -145,6 +149,7 @@ static void encx24j600_write_phy(struct encx24j600_priv *priv, u8 reg, u16 val)
{
struct net_device *dev = priv->ndev;
int ret = regmap_write(priv->ctx.phymap, reg, val);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d writing reg %02x=%04x\n",
__func__, ret, reg, val);
@ -164,6 +169,7 @@ static void encx24j600_cmd(struct encx24j600_priv *priv, u8 cmd)
{
struct net_device *dev = priv->ndev;
int ret = regmap_write(priv->ctx.regmap, cmd, 0);
if (unlikely(ret))
netif_err(priv, drv, dev, "%s: error %d with cmd %02x\n",
__func__, ret, cmd);
@ -173,6 +179,7 @@ static int encx24j600_raw_read(struct encx24j600_priv *priv, u8 reg, u8 *data,
size_t count)
{
int ret;
mutex_lock(&priv->ctx.mutex);
ret = regmap_encx24j600_spi_read(&priv->ctx, reg, data, count);
mutex_unlock(&priv->ctx.mutex);
@ -184,6 +191,7 @@ static int encx24j600_raw_write(struct encx24j600_priv *priv, u8 reg,
const u8 *data, size_t count)
{
int ret;
mutex_lock(&priv->ctx.mutex);
ret = regmap_encx24j600_spi_write(&priv->ctx, reg, data, count);
mutex_unlock(&priv->ctx.mutex);
@ -194,6 +202,7 @@ static int encx24j600_raw_write(struct encx24j600_priv *priv, u8 reg,
static void encx24j600_update_phcon1(struct encx24j600_priv *priv)
{
u16 phcon1 = encx24j600_read_phy(priv, PHCON1);
if (priv->autoneg == AUTONEG_ENABLE) {
phcon1 |= ANEN | RENEG;
} else {
@ -328,6 +337,7 @@ static int encx24j600_receive_packet(struct encx24j600_priv *priv,
{
struct net_device *dev = priv->ndev;
struct sk_buff *skb = netdev_alloc_skb(dev, rsv->len + NET_IP_ALIGN);
if (!skb) {
pr_err_ratelimited("RX: OOM: packet dropped\n");
dev->stats.rx_dropped++;
@ -346,7 +356,6 @@ static int encx24j600_receive_packet(struct encx24j600_priv *priv,
/* Maintain stats */
dev->stats.rx_packets++;
dev->stats.rx_bytes += rsv->len;
priv->next_packet = rsv->next_packet;
netif_rx(skb);
@ -383,6 +392,8 @@ static void encx24j600_rx_packets(struct encx24j600_priv *priv, u8 packet_count)
encx24j600_receive_packet(priv, &rsv);
}
priv->next_packet = rsv.next_packet;
newrxtail = priv->next_packet - 2;
if (newrxtail == ENC_RX_BUF_START)
newrxtail = SRAM_SIZE - 2;
@ -827,6 +838,7 @@ static void encx24j600_set_multicast_list(struct net_device *dev)
static void encx24j600_hw_tx(struct encx24j600_priv *priv)
{
struct net_device *dev = priv->ndev;
netif_info(priv, tx_queued, dev, "TX Packet Len:%d\n",
priv->tx_skb->len);
@ -894,7 +906,6 @@ static void encx24j600_tx_timeout(struct net_device *dev)
dev->stats.tx_errors++;
netif_wake_queue(dev);
return;
}
static int encx24j600_get_regs_len(struct net_device *dev)
@ -957,12 +968,14 @@ static int encx24j600_set_settings(struct net_device *dev,
static u32 encx24j600_get_msglevel(struct net_device *dev)
{
struct encx24j600_priv *priv = netdev_priv(dev);
return priv->msg_enable;
}
static void encx24j600_set_msglevel(struct net_device *dev, u32 val)
{
struct encx24j600_priv *priv = netdev_priv(dev);
priv->msg_enable = val;
}

View File

@ -1265,7 +1265,7 @@ static const struct qed_iscsi_ops qed_iscsi_ops_pass = {
.get_stats = &qed_iscsi_stats,
};
const struct qed_iscsi_ops *qed_get_iscsi_ops()
const struct qed_iscsi_ops *qed_get_iscsi_ops(void)
{
return &qed_iscsi_ops_pass;
}

View File

@ -460,6 +460,12 @@ static int emac_clks_phase1_init(struct platform_device *pdev,
{
int ret;
/* On ACPI platforms, clocks are controlled by firmware and/or
* ACPI, not by drivers.
*/
if (has_acpi_companion(&pdev->dev))
return 0;
ret = emac_clks_get(pdev, adpt);
if (ret)
return ret;
@ -485,6 +491,9 @@ static int emac_clks_phase2_init(struct platform_device *pdev,
{
int ret;
if (has_acpi_companion(&pdev->dev))
return 0;
ret = clk_set_rate(adpt->clk[EMAC_CLK_TX], 125000000);
if (ret)
return ret;

View File

@ -472,8 +472,6 @@ static void r6040_down(struct net_device *dev)
iowrite16(adrp[0], ioaddr + MID_0L);
iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H);
phy_stop(dev->phydev);
}
static int r6040_close(struct net_device *dev)
@ -481,12 +479,12 @@ static int r6040_close(struct net_device *dev)
struct r6040_private *lp = netdev_priv(dev);
struct pci_dev *pdev = lp->pdev;
spin_lock_irq(&lp->lock);
phy_stop(dev->phydev);
napi_disable(&lp->napi);
netif_stop_queue(dev);
r6040_down(dev);
free_irq(dev->irq, dev);
spin_lock_irq(&lp->lock);
r6040_down(dev);
/* Free RX buffer */
r6040_free_rxbufs(dev);
@ -496,6 +494,8 @@ static int r6040_close(struct net_device *dev)
spin_unlock_irq(&lp->lock);
free_irq(dev->irq, dev);
/* Free Descriptor memory */
if (lp->rx_ring) {
pci_free_consistent(pdev,

View File

@ -120,44 +120,53 @@ static int efx_ethtool_phys_id(struct net_device *net_dev,
}
/* This must be called with rtnl_lock held. */
static int efx_ethtool_get_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd)
static int
efx_ethtool_get_link_ksettings(struct net_device *net_dev,
struct ethtool_link_ksettings *cmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_link_state *link_state = &efx->link_state;
u32 supported;
mutex_lock(&efx->mac_lock);
efx->phy_op->get_settings(efx, ecmd);
efx->phy_op->get_link_ksettings(efx, cmd);
mutex_unlock(&efx->mac_lock);
/* Both MACs support pause frames (bidirectional and respond-only) */
ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
ethtool_convert_link_mode_to_legacy_u32(&supported,
cmd->link_modes.supported);
supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
supported);
if (LOOPBACK_INTERNAL(efx)) {
ethtool_cmd_speed_set(ecmd, link_state->speed);
ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
cmd->base.speed = link_state->speed;
cmd->base.duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
}
return 0;
}
/* This must be called with rtnl_lock held. */
static int efx_ethtool_set_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd)
static int
efx_ethtool_set_link_ksettings(struct net_device *net_dev,
const struct ethtool_link_ksettings *cmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
int rc;
/* GMAC does not support 1000Mbps HD */
if ((ethtool_cmd_speed(ecmd) == SPEED_1000) &&
(ecmd->duplex != DUPLEX_FULL)) {
if ((cmd->base.speed == SPEED_1000) &&
(cmd->base.duplex != DUPLEX_FULL)) {
netif_dbg(efx, drv, efx->net_dev,
"rejecting unsupported 1000Mbps HD setting\n");
return -EINVAL;
}
mutex_lock(&efx->mac_lock);
rc = efx->phy_op->set_settings(efx, ecmd);
rc = efx->phy_op->set_link_ksettings(efx, cmd);
mutex_unlock(&efx->mac_lock);
return rc;
}
@ -1342,8 +1351,6 @@ static int efx_ethtool_get_module_info(struct net_device *net_dev,
}
const struct ethtool_ops efx_ethtool_ops = {
.get_settings = efx_ethtool_get_settings,
.set_settings = efx_ethtool_set_settings,
.get_drvinfo = efx_ethtool_get_drvinfo,
.get_regs_len = efx_ethtool_get_regs_len,
.get_regs = efx_ethtool_get_regs,
@ -1373,4 +1380,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_ts_info = efx_ethtool_get_ts_info,
.get_module_info = efx_ethtool_get_module_info,
.get_module_eeprom = efx_ethtool_get_module_eeprom,
.get_link_ksettings = efx_ethtool_get_link_ksettings,
.set_link_ksettings = efx_ethtool_set_link_ksettings,
};

View File

@ -503,45 +503,59 @@ static void efx_mcdi_phy_remove(struct efx_nic *efx)
kfree(phy_data);
}
static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
static void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx,
struct ethtool_link_ksettings *cmd)
{
struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
int rc;
u32 supported, advertising, lp_advertising;
ecmd->supported =
mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
ecmd->advertising = efx->link_advertising;
ethtool_cmd_speed_set(ecmd, efx->link_state.speed);
ecmd->duplex = efx->link_state.fd;
ecmd->port = mcdi_to_ethtool_media(phy_cfg->media);
ecmd->phy_address = phy_cfg->port;
ecmd->transceiver = XCVR_INTERNAL;
ecmd->autoneg = !!(efx->link_advertising & ADVERTISED_Autoneg);
ecmd->mdio_support = (efx->mdio.mode_support &
supported = mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
advertising = efx->link_advertising;
cmd->base.speed = efx->link_state.speed;
cmd->base.duplex = efx->link_state.fd;
cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
cmd->base.phy_address = phy_cfg->port;
cmd->base.autoneg = !!(efx->link_advertising & ADVERTISED_Autoneg);
cmd->base.mdio_support = (efx->mdio.mode_support &
(MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
supported);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
advertising);
BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), NULL);
if (rc)
return;
ecmd->lp_advertising =
lp_advertising =
mcdi_to_ethtool_cap(phy_cfg->media,
MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP));
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising,
lp_advertising);
}
static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
static int
efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
const struct ethtool_link_ksettings *cmd)
{
struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
u32 caps;
int rc;
u32 advertising;
if (ecmd->autoneg) {
caps = (ethtool_to_mcdi_cap(ecmd->advertising) |
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
if (cmd->base.autoneg) {
caps = (ethtool_to_mcdi_cap(advertising) |
1 << MC_CMD_PHY_CAP_AN_LBN);
} else if (ecmd->duplex) {
switch (ethtool_cmd_speed(ecmd)) {
} else if (cmd->base.duplex) {
switch (cmd->base.speed) {
case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
@ -550,7 +564,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
default: return -EINVAL;
}
} else {
switch (ethtool_cmd_speed(ecmd)) {
switch (cmd->base.speed) {
case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
@ -563,9 +577,9 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
if (rc)
return rc;
if (ecmd->autoneg) {
if (cmd->base.autoneg) {
efx_link_set_advertising(
efx, ecmd->advertising | ADVERTISED_Autoneg);
efx, advertising | ADVERTISED_Autoneg);
phy_cfg->forced_cap = 0;
} else {
efx_link_set_advertising(efx, 0);
@ -812,8 +826,8 @@ static const struct efx_phy_operations efx_mcdi_phy_ops = {
.poll = efx_mcdi_phy_poll,
.fini = efx_port_dummy_op_void,
.remove = efx_mcdi_phy_remove,
.get_settings = efx_mcdi_phy_get_settings,
.set_settings = efx_mcdi_phy_set_settings,
.get_link_ksettings = efx_mcdi_phy_get_link_ksettings,
.set_link_ksettings = efx_mcdi_phy_set_link_ksettings,
.test_alive = efx_mcdi_phy_test_alive,
.run_tests = efx_mcdi_phy_run_tests,
.test_name = efx_mcdi_phy_test_name,

View File

@ -720,8 +720,8 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left,
* @reconfigure: Reconfigure PHY (e.g. for new link parameters)
* @poll: Update @link_state and report whether it changed.
* Serialised by the mac_lock.
* @get_settings: Get ethtool settings. Serialised by the mac_lock.
* @set_settings: Set ethtool settings. Serialised by the mac_lock.
* @get_link_ksettings: Get ethtool settings. Serialised by the mac_lock.
* @set_link_ksettings: Set ethtool settings. Serialised by the mac_lock.
* @set_npage_adv: Set abilities advertised in (Extended) Next Page
* (only needed where AN bit is set in mmds)
* @test_alive: Test that PHY is 'alive' (online)
@ -736,10 +736,10 @@ struct efx_phy_operations {
void (*remove) (struct efx_nic *efx);
int (*reconfigure) (struct efx_nic *efx);
bool (*poll) (struct efx_nic *efx);
void (*get_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
int (*set_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
void (*get_link_ksettings)(struct efx_nic *efx,
struct ethtool_link_ksettings *cmd);
int (*set_link_ksettings)(struct efx_nic *efx,
const struct ethtool_link_ksettings *cmd);
void (*set_npage_adv) (struct efx_nic *efx, u32);
int (*test_alive) (struct efx_nic *efx);
const char *(*test_name) (struct efx_nic *efx, unsigned int index);

View File

@ -158,9 +158,9 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
if (!pskb_may_pull(skb, hdrlen + sizeof(struct iphdr)))
return false;
iph = (struct iphdr *)(skb->data + hdrlen + sizeof(struct iphdr));
iph = (struct iphdr *)(skb->data + hdrlen);
return iph->saddr != pctx->ms_addr_ip4.s_addr;
return iph->saddr == pctx->ms_addr_ip4.s_addr;
}
/* Check if the inner IP source address in this packet is assigned to any
@ -423,11 +423,11 @@ static inline void gtp1_push_header(struct sk_buff *skb, struct pdp_ctx *pctx)
/* Bits 8 7 6 5 4 3 2 1
* +--+--+--+--+--+--+--+--+
* |version |PT| 1| E| S|PN|
* |version |PT| 0| E| S|PN|
* +--+--+--+--+--+--+--+--+
* 0 0 1 1 1 0 0 0
*/
gtp1->flags = 0x38; /* v1, GTP-non-prime. */
gtp1->flags = 0x30; /* v1, GTP-non-prime. */
gtp1->type = GTP_TPDU;
gtp1->length = htons(payload_len);
gtp1->tid = htonl(pctx->u.v1.o_tei);

View File

@ -517,9 +517,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
mtt = irda_get_mtt(skb);
pr_debug("%s: %ld, mtt=%d\n", __func__, jiffies, mtt);
if (mtt > 1000)
mdelay(mtt / 1000);
else if (mtt)
if (mtt > 1000)
mdelay(mtt / 1000);
else if (mtt)
udelay(mtt);
/* Enable DMA interrupt */

View File

@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/virtio.h>
#include <linux/virtio_net.h>
#include <linux/bpf.h>
#include <linux/scatterlist.h>
#include <linux/if_vlan.h>
#include <linux/slab.h>
@ -81,6 +82,8 @@ struct receive_queue {
struct napi_struct napi;
struct bpf_prog __rcu *xdp_prog;
/* Chain pages by the private ptr. */
struct page *pages;
@ -111,6 +114,9 @@ struct virtnet_info {
/* # of queue pairs currently used by the driver */
u16 curr_queue_pairs;
/* # of XDP queue pairs currently used by the driver */
u16 xdp_queue_pairs;
/* I like... big packets and I cannot lie! */
bool big_packets;
@ -324,6 +330,90 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
return skb;
}
static void virtnet_xdp_xmit(struct virtnet_info *vi,
struct receive_queue *rq,
struct send_queue *sq,
struct xdp_buff *xdp)
{
struct page *page = virt_to_head_page(xdp->data);
struct virtio_net_hdr_mrg_rxbuf *hdr;
unsigned int num_sg, len;
void *xdp_sent;
int err;
/* Free up any pending old buffers before queueing new ones. */
while ((xdp_sent = virtqueue_get_buf(sq->vq, &len)) != NULL) {
struct page *sent_page = virt_to_head_page(xdp_sent);
if (vi->mergeable_rx_bufs)
put_page(sent_page);
else
give_pages(rq, sent_page);
}
/* Zero header and leave csum up to XDP layers */
hdr = xdp->data;
memset(hdr, 0, vi->hdr_len);
num_sg = 1;
sg_init_one(sq->sg, xdp->data, xdp->data_end - xdp->data);
err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
xdp->data, GFP_ATOMIC);
if (unlikely(err)) {
if (vi->mergeable_rx_bufs)
put_page(page);
else
give_pages(rq, page);
return; // On error abort to avoid unnecessary kick
} else if (!vi->mergeable_rx_bufs) {
/* If not mergeable bufs must be big packets so cleanup pages */
give_pages(rq, (struct page *)page->private);
page->private = 0;
}
virtqueue_kick(sq->vq);
}
static u32 do_xdp_prog(struct virtnet_info *vi,
struct receive_queue *rq,
struct bpf_prog *xdp_prog,
struct page *page, int offset, int len)
{
int hdr_padded_len;
struct xdp_buff xdp;
unsigned int qp;
u32 act;
u8 *buf;
buf = page_address(page) + offset;
if (vi->mergeable_rx_bufs)
hdr_padded_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else
hdr_padded_len = sizeof(struct padded_vnet_hdr);
xdp.data = buf + hdr_padded_len;
xdp.data_end = xdp.data + (len - vi->hdr_len);
act = bpf_prog_run_xdp(xdp_prog, &xdp);
switch (act) {
case XDP_PASS:
return XDP_PASS;
case XDP_TX:
qp = vi->curr_queue_pairs -
vi->xdp_queue_pairs +
smp_processor_id();
xdp.data = buf + (vi->mergeable_rx_bufs ? 0 : 4);
virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp);
return XDP_TX;
default:
bpf_warn_invalid_xdp_action(act);
case XDP_ABORTED:
case XDP_DROP:
return XDP_DROP;
}
}
static struct sk_buff *receive_small(struct virtnet_info *vi, void *buf, unsigned int len)
{
struct sk_buff * skb = buf;
@ -340,17 +430,102 @@ static struct sk_buff *receive_big(struct net_device *dev,
void *buf,
unsigned int len)
{
struct bpf_prog *xdp_prog;
struct page *page = buf;
struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
struct sk_buff *skb;
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
if (xdp_prog) {
struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
u32 act;
if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
goto err_xdp;
act = do_xdp_prog(vi, rq, xdp_prog, page, 0, len);
switch (act) {
case XDP_PASS:
break;
case XDP_TX:
rcu_read_unlock();
goto xdp_xmit;
case XDP_DROP:
default:
goto err_xdp;
}
}
rcu_read_unlock();
skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
if (unlikely(!skb))
goto err;
return skb;
err_xdp:
rcu_read_unlock();
err:
dev->stats.rx_dropped++;
give_pages(rq, page);
xdp_xmit:
return NULL;
}
/* The conditions to enable XDP should preclude the underlying device from
* sending packets across multiple buffers (num_buf > 1). However per spec
* it does not appear to be illegal to do so but rather just against convention.
* So in order to avoid making a system unresponsive the packets are pushed
* into a page and the XDP program is run. This will be extremely slow and we
* push a warning to the user to fix this as soon as possible. Fixing this may
* require resolving the underlying hardware to determine why multiple buffers
* are being received or simply loading the XDP program in the ingress stack
* after the skb is built because there is no advantage to running it here
* anymore.
*/
static struct page *xdp_linearize_page(struct receive_queue *rq,
u16 num_buf,
struct page *p,
int offset,
unsigned int *len)
{
struct page *page = alloc_page(GFP_ATOMIC);
unsigned int page_off = 0;
if (!page)
return NULL;
memcpy(page_address(page) + page_off, page_address(p) + offset, *len);
page_off += *len;
while (--num_buf) {
unsigned int buflen;
unsigned long ctx;
void *buf;
int off;
ctx = (unsigned long)virtqueue_get_buf(rq->vq, &buflen);
if (unlikely(!ctx))
goto err_buf;
/* guard against a misconfigured or uncooperative backend that
* is sending packet larger than the MTU.
*/
if ((page_off + buflen) > PAGE_SIZE)
goto err_buf;
buf = mergeable_ctx_to_buf_address(ctx);
p = virt_to_head_page(buf);
off = buf - page_address(p);
memcpy(page_address(page) + page_off,
page_address(p) + off, buflen);
page_off += buflen;
}
*len = page_off;
return page;
err_buf:
__free_pages(page, 0);
return NULL;
}
@ -365,11 +540,67 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers);
struct page *page = virt_to_head_page(buf);
int offset = buf - page_address(page);
unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
struct sk_buff *head_skb, *curr_skb;
struct bpf_prog *xdp_prog;
unsigned int truesize;
struct sk_buff *head_skb = page_to_skb(vi, rq, page, offset, len,
truesize);
struct sk_buff *curr_skb = head_skb;
head_skb = NULL;
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
if (xdp_prog) {
struct page *xdp_page;
u32 act;
/* No known backend devices should send packets with
* more than a single buffer when XDP conditions are
* met. However it is not strictly illegal so the case
* is handled as an exception and a warning is thrown.
*/
if (unlikely(num_buf > 1)) {
bpf_warn_invalid_xdp_buffer();
/* linearize data for XDP */
xdp_page = xdp_linearize_page(rq, num_buf,
page, offset, &len);
if (!xdp_page)
goto err_xdp;
offset = 0;
} else {
xdp_page = page;
}
/* Transient failure which in theory could occur if
* in-flight packets from before XDP was enabled reach
* the receive path after XDP is loaded. In practice I
* was not able to create this condition.
*/
if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
goto err_xdp;
act = do_xdp_prog(vi, rq, xdp_prog, page, offset, len);
switch (act) {
case XDP_PASS:
if (unlikely(xdp_page != page))
__free_pages(xdp_page, 0);
break;
case XDP_TX:
if (unlikely(xdp_page != page))
goto err_xdp;
rcu_read_unlock();
goto xdp_xmit;
case XDP_DROP:
default:
if (unlikely(xdp_page != page))
__free_pages(xdp_page, 0);
goto err_xdp;
}
}
rcu_read_unlock();
truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
head_skb = page_to_skb(vi, rq, page, offset, len, truesize);
curr_skb = head_skb;
if (unlikely(!curr_skb))
goto err_skb;
@ -423,6 +654,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
ewma_pkt_len_add(&rq->mrg_avg_pkt_len, head_skb->len);
return head_skb;
err_xdp:
rcu_read_unlock();
err_skb:
put_page(page);
while (--num_buf) {
@ -439,6 +672,7 @@ err_skb:
err_buf:
dev->stats.rx_dropped++;
dev_kfree_skb(head_skb);
xdp_xmit:
return NULL;
}
@ -1337,6 +1571,13 @@ static int virtnet_set_channels(struct net_device *dev,
if (queue_pairs > vi->max_queue_pairs || queue_pairs == 0)
return -EINVAL;
/* For now we don't support modifying channels while XDP is loaded
* also when XDP is loaded all RX queues have XDP programs so we only
* need to check a single RX queue.
*/
if (vi->rq[0].xdp_prog)
return -EINVAL;
get_online_cpus();
err = virtnet_set_queues(vi, queue_pairs);
if (!err) {
@ -1428,6 +1669,93 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
.set_settings = virtnet_set_settings,
};
static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
{
unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
struct virtnet_info *vi = netdev_priv(dev);
struct bpf_prog *old_prog;
u16 xdp_qp = 0, curr_qp;
int i, err;
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6)) {
netdev_warn(dev, "can't set XDP while host is implementing LRO, disable LRO first\n");
return -EOPNOTSUPP;
}
if (vi->mergeable_rx_bufs && !vi->any_header_sg) {
netdev_warn(dev, "XDP expects header/data in single page, any_header_sg required\n");
return -EINVAL;
}
if (dev->mtu > max_sz) {
netdev_warn(dev, "XDP requires MTU less than %lu\n", max_sz);
return -EINVAL;
}
curr_qp = vi->curr_queue_pairs - vi->xdp_queue_pairs;
if (prog)
xdp_qp = nr_cpu_ids;
/* XDP requires extra queues for XDP_TX */
if (curr_qp + xdp_qp > vi->max_queue_pairs) {
netdev_warn(dev, "request %i queues but max is %i\n",
curr_qp + xdp_qp, vi->max_queue_pairs);
return -ENOMEM;
}
err = virtnet_set_queues(vi, curr_qp + xdp_qp);
if (err) {
dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
return err;
}
if (prog) {
prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
if (IS_ERR(prog)) {
virtnet_set_queues(vi, curr_qp);
return PTR_ERR(prog);
}
}
vi->xdp_queue_pairs = xdp_qp;
netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
for (i = 0; i < vi->max_queue_pairs; i++) {
old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
if (old_prog)
bpf_prog_put(old_prog);
}
return 0;
}
static bool virtnet_xdp_query(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
int i;
for (i = 0; i < vi->max_queue_pairs; i++) {
if (vi->rq[i].xdp_prog)
return true;
}
return false;
}
static int virtnet_xdp(struct net_device *dev, struct netdev_xdp *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return virtnet_xdp_set(dev, xdp->prog);
case XDP_QUERY_PROG:
xdp->prog_attached = virtnet_xdp_query(dev);
return 0;
default:
return -EINVAL;
}
}
static const struct net_device_ops virtnet_netdev = {
.ndo_open = virtnet_open,
.ndo_stop = virtnet_close,
@ -1444,6 +1772,7 @@ static const struct net_device_ops virtnet_netdev = {
#ifdef CONFIG_NET_RX_BUSY_POLL
.ndo_busy_poll = virtnet_busy_poll,
#endif
.ndo_xdp = virtnet_xdp,
};
static void virtnet_config_changed_work(struct work_struct *work)
@ -1505,12 +1834,20 @@ static void virtnet_free_queues(struct virtnet_info *vi)
static void free_receive_bufs(struct virtnet_info *vi)
{
struct bpf_prog *old_prog;
int i;
rtnl_lock();
for (i = 0; i < vi->max_queue_pairs; i++) {
while (vi->rq[i].pages)
__free_pages(get_a_page(&vi->rq[i], GFP_KERNEL), 0);
old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
RCU_INIT_POINTER(vi->rq[i].xdp_prog, NULL);
if (old_prog)
bpf_prog_put(old_prog);
}
rtnl_unlock();
}
static void free_receive_page_frags(struct virtnet_info *vi)
@ -1521,6 +1858,16 @@ static void free_receive_page_frags(struct virtnet_info *vi)
put_page(vi->rq[i].alloc_frag.page);
}
static bool is_xdp_queue(struct virtnet_info *vi, int q)
{
if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs))
return false;
else if (q < vi->curr_queue_pairs)
return true;
else
return false;
}
static void free_unused_bufs(struct virtnet_info *vi)
{
void *buf;
@ -1528,8 +1875,12 @@ static void free_unused_bufs(struct virtnet_info *vi)
for (i = 0; i < vi->max_queue_pairs; i++) {
struct virtqueue *vq = vi->sq[i].vq;
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
dev_kfree_skb(buf);
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
if (!is_xdp_queue(vi, i))
dev_kfree_skb(buf);
else
put_page(virt_to_head_page(buf));
}
}
for (i = 0; i < vi->max_queue_pairs; i++) {
@ -1930,7 +2281,9 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_unregister_netdev;
}
virtnet_set_affinity(vi);
rtnl_lock();
virtnet_set_queues(vi, vi->curr_queue_pairs);
rtnl_unlock();
/* Assume link up if device can't report link status,
otherwise get link status from config. */

View File

@ -366,6 +366,8 @@ static int vrf_finish_output6(struct net *net, struct sock *sk,
struct in6_addr *nexthop;
int ret;
nf_reset(skb);
skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
@ -547,6 +549,8 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
u32 nexthop;
int ret = -EINVAL;
nf_reset(skb);
/* Be paranoid, rather than too clever. */
if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
struct sk_buff *skb2;
@ -849,8 +853,6 @@ static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook,
{
struct net *net = dev_net(dev);
nf_reset(skb);
if (NF_HOOK(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) < 0)
skb = NULL; /* kfree_skb(skb) handled by nf code */

View File

@ -95,62 +95,63 @@ static inline void write_av9110_bit (lmc_softc_t *, int);
static void write_av9110(lmc_softc_t *, u32, u32, u32, u32, u32);
lmc_media_t lmc_ds3_media = {
lmc_ds3_init, /* special media init stuff */
lmc_ds3_default, /* reset to default state */
lmc_ds3_set_status, /* reset status to state provided */
lmc_dummy_set_1, /* set clock source */
lmc_dummy_set2_1, /* set line speed */
lmc_ds3_set_100ft, /* set cable length */
lmc_ds3_set_scram, /* set scrambler */
lmc_ds3_get_link_status, /* get link status */
lmc_dummy_set_1, /* set link status */
lmc_ds3_set_crc_length, /* set CRC length */
lmc_dummy_set_1, /* set T1 or E1 circuit type */
lmc_ds3_watchdog
.init = lmc_ds3_init, /* special media init stuff */
.defaults = lmc_ds3_default, /* reset to default state */
.set_status = lmc_ds3_set_status, /* reset status to state provided */
.set_clock_source = lmc_dummy_set_1, /* set clock source */
.set_speed = lmc_dummy_set2_1, /* set line speed */
.set_cable_length = lmc_ds3_set_100ft, /* set cable length */
.set_scrambler = lmc_ds3_set_scram, /* set scrambler */
.get_link_status = lmc_ds3_get_link_status, /* get link status */
.set_link_status = lmc_dummy_set_1, /* set link status */
.set_crc_length = lmc_ds3_set_crc_length, /* set CRC length */
.set_circuit_type = lmc_dummy_set_1, /* set T1 or E1 circuit type */
.watchdog = lmc_ds3_watchdog
};
lmc_media_t lmc_hssi_media = {
lmc_hssi_init, /* special media init stuff */
lmc_hssi_default, /* reset to default state */
lmc_hssi_set_status, /* reset status to state provided */
lmc_hssi_set_clock, /* set clock source */
lmc_dummy_set2_1, /* set line speed */
lmc_dummy_set_1, /* set cable length */
lmc_dummy_set_1, /* set scrambler */
lmc_hssi_get_link_status, /* get link status */
lmc_hssi_set_link_status, /* set link status */
lmc_hssi_set_crc_length, /* set CRC length */
lmc_dummy_set_1, /* set T1 or E1 circuit type */
lmc_hssi_watchdog
.init = lmc_hssi_init, /* special media init stuff */
.defaults = lmc_hssi_default, /* reset to default state */
.set_status = lmc_hssi_set_status, /* reset status to state provided */
.set_clock_source = lmc_hssi_set_clock, /* set clock source */
.set_speed = lmc_dummy_set2_1, /* set line speed */
.set_cable_length = lmc_dummy_set_1, /* set cable length */
.set_scrambler = lmc_dummy_set_1, /* set scrambler */
.get_link_status = lmc_hssi_get_link_status, /* get link status */
.set_link_status = lmc_hssi_set_link_status, /* set link status */
.set_crc_length = lmc_hssi_set_crc_length, /* set CRC length */
.set_circuit_type = lmc_dummy_set_1, /* set T1 or E1 circuit type */
.watchdog = lmc_hssi_watchdog
};
lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */
lmc_ssi_default, /* reset to default state */
lmc_ssi_set_status, /* reset status to state provided */
lmc_ssi_set_clock, /* set clock source */
lmc_ssi_set_speed, /* set line speed */
lmc_dummy_set_1, /* set cable length */
lmc_dummy_set_1, /* set scrambler */
lmc_ssi_get_link_status, /* get link status */
lmc_ssi_set_link_status, /* set link status */
lmc_ssi_set_crc_length, /* set CRC length */
lmc_dummy_set_1, /* set T1 or E1 circuit type */
lmc_ssi_watchdog
lmc_media_t lmc_ssi_media = {
.init = lmc_ssi_init, /* special media init stuff */
.defaults = lmc_ssi_default, /* reset to default state */
.set_status = lmc_ssi_set_status, /* reset status to state provided */
.set_clock_source = lmc_ssi_set_clock, /* set clock source */
.set_speed = lmc_ssi_set_speed, /* set line speed */
.set_cable_length = lmc_dummy_set_1, /* set cable length */
.set_scrambler = lmc_dummy_set_1, /* set scrambler */
.get_link_status = lmc_ssi_get_link_status, /* get link status */
.set_link_status = lmc_ssi_set_link_status, /* set link status */
.set_crc_length = lmc_ssi_set_crc_length, /* set CRC length */
.set_circuit_type = lmc_dummy_set_1, /* set T1 or E1 circuit type */
.watchdog = lmc_ssi_watchdog
};
lmc_media_t lmc_t1_media = {
lmc_t1_init, /* special media init stuff */
lmc_t1_default, /* reset to default state */
lmc_t1_set_status, /* reset status to state provided */
lmc_t1_set_clock, /* set clock source */
lmc_dummy_set2_1, /* set line speed */
lmc_dummy_set_1, /* set cable length */
lmc_dummy_set_1, /* set scrambler */
lmc_t1_get_link_status, /* get link status */
lmc_dummy_set_1, /* set link status */
lmc_t1_set_crc_length, /* set CRC length */
lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */
lmc_t1_watchdog
.init = lmc_t1_init, /* special media init stuff */
.defaults = lmc_t1_default, /* reset to default state */
.set_status = lmc_t1_set_status, /* reset status to state provided */
.set_clock_source = lmc_t1_set_clock, /* set clock source */
.set_speed = lmc_dummy_set2_1, /* set line speed */
.set_cable_length = lmc_dummy_set_1, /* set cable length */
.set_scrambler = lmc_dummy_set_1, /* set scrambler */
.get_link_status = lmc_t1_get_link_status, /* get link status */
.set_link_status = lmc_dummy_set_1, /* set link status */
.set_crc_length = lmc_t1_set_crc_length, /* set CRC length */
.set_circuit_type = lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */
.watchdog = lmc_t1_watchdog
};
static void

View File

@ -20,7 +20,7 @@ struct cgroup_bpf {
* when this cgroup is accessed.
*/
struct bpf_prog *prog[MAX_BPF_ATTACH_TYPE];
struct bpf_prog *effective[MAX_BPF_ATTACH_TYPE];
struct bpf_prog __rcu *effective[MAX_BPF_ATTACH_TYPE];
};
void cgroup_bpf_put(struct cgroup *cgrp);

View File

@ -216,7 +216,7 @@ u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
void bpf_prog_calc_digest(struct bpf_prog *fp);
int bpf_prog_calc_digest(struct bpf_prog *fp);
const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
@ -238,6 +238,8 @@ struct bpf_prog * __must_check bpf_prog_add(struct bpf_prog *prog, int i);
void bpf_prog_sub(struct bpf_prog *prog, int i);
struct bpf_prog * __must_check bpf_prog_inc(struct bpf_prog *prog);
void bpf_prog_put(struct bpf_prog *prog);
int __bpf_prog_charge(struct user_struct *user, u32 pages);
void __bpf_prog_uncharge(struct user_struct *user, u32 pages);
struct bpf_map *bpf_map_get_with_uref(u32 ufd);
struct bpf_map *__bpf_map_get(struct fd f);
@ -318,6 +320,15 @@ static inline struct bpf_prog * __must_check bpf_prog_inc(struct bpf_prog *prog)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline int __bpf_prog_charge(struct user_struct *user, u32 pages)
{
return 0;
}
static inline void __bpf_prog_uncharge(struct user_struct *user, u32 pages)
{
}
#endif /* CONFIG_BPF_SYSCALL */
/* verifier prototypes for helper functions called from eBPF programs */

View File

@ -57,9 +57,6 @@ struct bpf_prog_aux;
/* BPF program can access up to 512 bytes of stack space. */
#define MAX_BPF_STACK 512
/* Maximum BPF program size in bytes. */
#define MAX_BPF_SIZE (BPF_MAXINSNS * sizeof(struct bpf_insn))
/* Helper macros for filter block array initializers. */
/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
@ -517,6 +514,17 @@ static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,
return BPF_PROG_RUN(prog, xdp);
}
static inline u32 bpf_prog_insn_size(const struct bpf_prog *prog)
{
return prog->len * sizeof(struct bpf_insn);
}
static inline u32 bpf_prog_digest_scratch_size(const struct bpf_prog *prog)
{
return round_up(bpf_prog_insn_size(prog) +
sizeof(__be64) + 1, SHA_MESSAGE_BYTES);
}
static inline unsigned int bpf_prog_size(unsigned int proglen)
{
return max(sizeof(struct bpf_prog),
@ -602,6 +610,7 @@ bool bpf_helper_changes_pkt_data(void *func);
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
const struct bpf_insn *patch, u32 len);
void bpf_warn_invalid_xdp_action(u32 act);
void bpf_warn_invalid_xdp_buffer(void);
#ifdef CONFIG_BPF_JIT
extern int bpf_jit_enable;

View File

@ -32,6 +32,7 @@
#define STORE_QUEUE_MINOR 155 /* unused */
#define I2O_MINOR 166
#define MICROCODE_MINOR 184
#define IRNET_MINOR 187
#define VFIO_MINOR 196
#define TUN_MINOR 200
#define CUSE_MINOR 203

View File

@ -8,6 +8,8 @@
#ifndef __MACB_PDATA_H__
#define __MACB_PDATA_H__
#include <linux/clk.h>
/**
* struct macb_platform_data - platform data for MACB Ethernet
* @phy_mask: phy mask passed when register the MDIO bus
@ -15,12 +17,16 @@
* @phy_irq_pin: PHY IRQ
* @is_rmii: using RMII interface?
* @rev_eth_addr: reverse Ethernet address byte order
* @pclk: platform clock
* @hclk: AHB clock
*/
struct macb_platform_data {
u32 phy_mask;
int phy_irq_pin;
u8 is_rmii;
u8 rev_eth_addr;
struct clk *pclk;
struct clk *hclk;
};
#endif /* __MACB_PDATA_H__ */

View File

@ -22,7 +22,8 @@ struct sock;
struct sockaddr;
int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax);
const struct inet_bind_bucket *tb, bool relax,
bool soreuseport_ok);
struct dst_entry *inet6_csk_route_req(const struct sock *sk, struct flowi6 *fl6,
const struct request_sock *req, u8 proto);

View File

@ -63,7 +63,8 @@ struct inet_connection_sock_af_ops {
#endif
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
int (*bind_conflict)(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax);
const struct inet_bind_bucket *tb,
bool relax, bool soreuseport_ok);
void (*mtu_reduced)(struct sock *sk);
};
@ -261,7 +262,8 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax);
const struct inet_bind_bucket *tb, bool relax,
bool soreuseport_ok);
int inet_csk_get_port(struct sock *sk, unsigned short snum);
struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4,

View File

@ -698,7 +698,8 @@ static inline int nla_len(const struct nlattr *nla)
*/
static inline int nla_ok(const struct nlattr *nla, int remaining)
{
return nla->nla_len >= sizeof(*nla) &&
return remaining >= (int) sizeof(*nla) &&
nla->nla_len >= sizeof(*nla) &&
nla->nla_len <= remaining;
}

View File

@ -1156,7 +1156,8 @@ config CGROUP_PERF
config CGROUP_BPF
bool "Support for eBPF programs attached to cgroups"
depends on BPF_SYSCALL && SOCK_CGROUP_DATA
depends on BPF_SYSCALL
select SOCK_CGROUP_DATA
help
Allow attaching eBPF programs to a cgroup using the bpf(2)
syscall command BPF_PROG_ATTACH.

View File

@ -105,19 +105,29 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO |
gfp_extra_flags;
struct bpf_prog *fp;
u32 pages, delta;
int ret;
BUG_ON(fp_old == NULL);
size = round_up(size, PAGE_SIZE);
if (size <= fp_old->pages * PAGE_SIZE)
pages = size / PAGE_SIZE;
if (pages <= fp_old->pages)
return fp_old;
delta = pages - fp_old->pages;
ret = __bpf_prog_charge(fp_old->aux->user, delta);
if (ret)
return NULL;
fp = __vmalloc(size, gfp_flags, PAGE_KERNEL);
if (fp != NULL) {
if (fp == NULL) {
__bpf_prog_uncharge(fp_old->aux->user, delta);
} else {
kmemcheck_annotate_bitfield(fp, meta);
memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE);
fp->pages = size / PAGE_SIZE;
fp->pages = pages;
fp->aux->prog = fp;
/* We keep fp->aux from fp_old around in the new
@ -136,28 +146,29 @@ void __bpf_prog_free(struct bpf_prog *fp)
vfree(fp);
}
#define SHA_BPF_RAW_SIZE \
round_up(MAX_BPF_SIZE + sizeof(__be64) + 1, SHA_MESSAGE_BYTES)
/* Called under verifier mutex. */
void bpf_prog_calc_digest(struct bpf_prog *fp)
int bpf_prog_calc_digest(struct bpf_prog *fp)
{
const u32 bits_offset = SHA_MESSAGE_BYTES - sizeof(__be64);
static u32 ws[SHA_WORKSPACE_WORDS];
static u8 raw[SHA_BPF_RAW_SIZE];
struct bpf_insn *dst = (void *)raw;
u32 raw_size = bpf_prog_digest_scratch_size(fp);
u32 ws[SHA_WORKSPACE_WORDS];
u32 i, bsize, psize, blocks;
struct bpf_insn *dst;
bool was_ld_map;
u8 *todo = raw;
u8 *raw, *todo;
__be32 *result;
__be64 *bits;
raw = vmalloc(raw_size);
if (!raw)
return -ENOMEM;
sha_init(fp->digest);
memset(ws, 0, sizeof(ws));
/* We need to take out the map fd for the digest calculation
* since they are unstable from user space side.
*/
dst = (void *)raw;
for (i = 0, was_ld_map = false; i < fp->len; i++) {
dst[i] = fp->insnsi[i];
if (!was_ld_map &&
@ -177,12 +188,13 @@ void bpf_prog_calc_digest(struct bpf_prog *fp)
}
}
psize = fp->len * sizeof(struct bpf_insn);
memset(&raw[psize], 0, sizeof(raw) - psize);
psize = bpf_prog_insn_size(fp);
memset(&raw[psize], 0, raw_size - psize);
raw[psize++] = 0x80;
bsize = round_up(psize, SHA_MESSAGE_BYTES);
blocks = bsize / SHA_MESSAGE_BYTES;
todo = raw;
if (bsize - psize >= sizeof(__be64)) {
bits = (__be64 *)(todo + bsize - sizeof(__be64));
} else {
@ -199,6 +211,9 @@ void bpf_prog_calc_digest(struct bpf_prog *fp)
result = (__force __be32 *)fp->digest;
for (i = 0; i < SHA_DIGEST_WORDS; i++)
result[i] = cpu_to_be32(fp->digest[i]);
vfree(raw);
return 0;
}
static bool bpf_is_jmp_and_has_target(const struct bpf_insn *insn)

View File

@ -615,19 +615,39 @@ static void free_used_maps(struct bpf_prog_aux *aux)
kfree(aux->used_maps);
}
int __bpf_prog_charge(struct user_struct *user, u32 pages)
{
unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
unsigned long user_bufs;
if (user) {
user_bufs = atomic_long_add_return(pages, &user->locked_vm);
if (user_bufs > memlock_limit) {
atomic_long_sub(pages, &user->locked_vm);
return -EPERM;
}
}
return 0;
}
void __bpf_prog_uncharge(struct user_struct *user, u32 pages)
{
if (user)
atomic_long_sub(pages, &user->locked_vm);
}
static int bpf_prog_charge_memlock(struct bpf_prog *prog)
{
struct user_struct *user = get_current_user();
unsigned long memlock_limit;
int ret;
memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
atomic_long_add(prog->pages, &user->locked_vm);
if (atomic_long_read(&user->locked_vm) > memlock_limit) {
atomic_long_sub(prog->pages, &user->locked_vm);
ret = __bpf_prog_charge(user, prog->pages);
if (ret) {
free_uid(user);
return -EPERM;
return ret;
}
prog->aux->user = user;
return 0;
}
@ -636,7 +656,7 @@ static void bpf_prog_uncharge_memlock(struct bpf_prog *prog)
{
struct user_struct *user = prog->aux->user;
atomic_long_sub(prog->pages, &user->locked_vm);
__bpf_prog_uncharge(user, prog->pages);
free_uid(user);
}
@ -811,7 +831,7 @@ static int bpf_prog_load(union bpf_attr *attr)
err = -EFAULT;
if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns),
prog->len * sizeof(struct bpf_insn)) != 0)
bpf_prog_insn_size(prog)) != 0)
goto free_prog;
prog->orig_prog = NULL;

View File

@ -462,14 +462,19 @@ static void init_reg_state(struct bpf_reg_state *regs)
regs[BPF_REG_1].type = PTR_TO_CTX;
}
static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
static void __mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
{
BUG_ON(regno >= MAX_BPF_REG);
regs[regno].type = UNKNOWN_VALUE;
regs[regno].id = 0;
regs[regno].imm = 0;
}
static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
{
BUG_ON(regno >= MAX_BPF_REG);
__mark_reg_unknown_value(regs, regno);
}
static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno)
{
regs[regno].min_value = BPF_REGISTER_MIN_RANGE;
@ -1970,8 +1975,13 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
if (reg->type == PTR_TO_MAP_VALUE_OR_NULL && reg->id == id) {
reg->type = type;
/* We don't need id from this point onwards anymore, thus we
* should better reset it, so that state pruning has chances
* to take effect.
*/
reg->id = 0;
if (type == UNKNOWN_VALUE)
mark_reg_unknown_value(regs, regno);
__mark_reg_unknown_value(regs, regno);
}
}
@ -1982,16 +1992,16 @@ static void mark_map_regs(struct bpf_verifier_state *state, u32 regno,
enum bpf_reg_type type)
{
struct bpf_reg_state *regs = state->regs;
u32 id = regs[regno].id;
int i;
for (i = 0; i < MAX_BPF_REG; i++)
mark_map_reg(regs, i, regs[regno].id, type);
mark_map_reg(regs, i, id, type);
for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) {
if (state->stack_slot_type[i] != STACK_SPILL)
continue;
mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE,
regs[regno].id, type);
mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE, id, type);
}
}
@ -2926,6 +2936,10 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
int insn_cnt = env->prog->len;
int i, j, err;
err = bpf_prog_calc_digest(env->prog);
if (err)
return err;
for (i = 0; i < insn_cnt; i++, insn++) {
if (BPF_CLASS(insn->code) == BPF_LDX &&
(BPF_MODE(insn->code) != BPF_MEM || insn->imm != 0)) {
@ -3173,8 +3187,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
log_level = 0;
}
bpf_prog_calc_digest(env->prog);
ret = replace_map_fd_with_map_ptr(env);
if (ret < 0)
goto skip_full_check;

View File

@ -111,9 +111,9 @@ static inline void lec_arp_put(struct lec_arp_table *entry)
}
static struct lane2_ops lane2_ops = {
lane2_resolve, /* resolve, spec 3.1.3 */
lane2_associate_req, /* associate_req, spec 3.1.4 */
NULL /* associate indicator, spec 3.1.5 */
.resolve = lane2_resolve, /* spec 3.1.3 */
.associate_req = lane2_associate_req, /* spec 3.1.4 */
.associate_indicator = NULL /* spec 3.1.5 */
};
static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@ -535,33 +535,32 @@ static void eg_destroy_cache(struct mpoa_client *mpc)
static const struct in_cache_ops ingress_ops = {
in_cache_add_entry, /* add_entry */
in_cache_get, /* get */
in_cache_get_with_mask, /* get_with_mask */
in_cache_get_by_vcc, /* get_by_vcc */
in_cache_put, /* put */
in_cache_remove_entry, /* remove_entry */
cache_hit, /* cache_hit */
clear_count_and_expired, /* clear_count */
check_resolving_entries, /* check_resolving */
refresh_entries, /* refresh */
in_destroy_cache /* destroy_cache */
.add_entry = in_cache_add_entry,
.get = in_cache_get,
.get_with_mask = in_cache_get_with_mask,
.get_by_vcc = in_cache_get_by_vcc,
.put = in_cache_put,
.remove_entry = in_cache_remove_entry,
.cache_hit = cache_hit,
.clear_count = clear_count_and_expired,
.check_resolving = check_resolving_entries,
.refresh = refresh_entries,
.destroy_cache = in_destroy_cache
};
static const struct eg_cache_ops egress_ops = {
eg_cache_add_entry, /* add_entry */
eg_cache_get_by_cache_id, /* get_by_cache_id */
eg_cache_get_by_tag, /* get_by_tag */
eg_cache_get_by_vcc, /* get_by_vcc */
eg_cache_get_by_src_ip, /* get_by_src_ip */
eg_cache_put, /* put */
eg_cache_remove_entry, /* remove_entry */
update_eg_cache_entry, /* update */
clear_expired, /* clear_expired */
eg_destroy_cache /* destroy_cache */
.add_entry = eg_cache_add_entry,
.get_by_cache_id = eg_cache_get_by_cache_id,
.get_by_tag = eg_cache_get_by_tag,
.get_by_vcc = eg_cache_get_by_vcc,
.get_by_src_ip = eg_cache_get_by_src_ip,
.put = eg_cache_put,
.remove_entry = eg_cache_remove_entry,
.update = update_eg_cache_entry,
.clear_expired = clear_expired,
.destroy_cache = eg_destroy_cache
};
void atm_mpoa_init_cache(struct mpoa_client *mpc)
{
mpc->in_ops = &ingress_ops;

View File

@ -2972,6 +2972,12 @@ void bpf_warn_invalid_xdp_action(u32 act)
}
EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
void bpf_warn_invalid_xdp_buffer(void)
{
WARN_ONCE(1, "Illegal XDP buffer encountered, expect throughput degradation\n");
}
EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_buffer);
static u32 sk_filter_convert_ctx_access(enum bpf_access_type type, int dst_reg,
int src_reg, int ctx_off,
struct bpf_insn *insn_buf,

View File

@ -201,7 +201,7 @@ static struct dn_dev_sysctl_table {
.extra1 = &min_t3,
.extra2 = &max_t3
},
{0}
{ }
},
};

View File

@ -45,11 +45,12 @@ void inet_get_local_port_range(struct net *net, int *low, int *high)
EXPORT_SYMBOL(inet_get_local_port_range);
int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax)
const struct inet_bind_bucket *tb, bool relax,
bool reuseport_ok)
{
struct sock *sk2;
int reuse = sk->sk_reuse;
int reuseport = sk->sk_reuseport;
bool reuse = sk->sk_reuse;
bool reuseport = !!sk->sk_reuseport && reuseport_ok;
kuid_t uid = sock_i_uid((struct sock *)sk);
/*
@ -105,6 +106,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
struct inet_bind_bucket *tb;
kuid_t uid = sock_i_uid(sk);
u32 remaining, offset;
bool reuseport_ok = !!snum;
if (port) {
have_port:
@ -165,7 +167,8 @@ other_parity_scan:
smallest_size = tb->num_owners;
smallest_port = port;
}
if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb, false))
if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb, false,
reuseport_ok))
goto tb_found;
goto next_port;
}
@ -206,13 +209,14 @@ tb_found:
sk->sk_reuseport && uid_eq(tb->fastuid, uid))) &&
smallest_size == -1)
goto success;
if (inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb, true)) {
if (inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb, true,
reuseport_ok)) {
if ((reuse ||
(tb->fastreuseport > 0 &&
sk->sk_reuseport &&
!rcu_access_pointer(sk->sk_reuseport_cb) &&
uid_eq(tb->fastuid, uid))) &&
smallest_size != -1 && --attempts >= 0) {
!snum && smallest_size != -1 && --attempts >= 0) {
spin_unlock_bh(&head->lock);
goto again;
}

View File

@ -29,11 +29,12 @@
#include <net/sock_reuseport.h>
int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb, bool relax)
const struct inet_bind_bucket *tb, bool relax,
bool reuseport_ok)
{
const struct sock *sk2;
int reuse = sk->sk_reuse;
int reuseport = sk->sk_reuseport;
bool reuse = !!sk->sk_reuse;
bool reuseport = !!sk->sk_reuseport && reuseport_ok;
kuid_t uid = sock_i_uid((struct sock *)sk);
/* We must walk the whole port owner list in this case. -DaveM */

View File

@ -2174,6 +2174,8 @@ static int ip6_route_del(struct fib6_config *cfg)
continue;
if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
continue;
if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol)
continue;
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);

View File

@ -245,7 +245,6 @@
#include <linux/tty.h>
#include <linux/proc_fs.h>
#include <linux/netdevice.h>
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <linux/capability.h>
#include <linux/ctype.h> /* isspace() */

View File

@ -15,13 +15,10 @@
/***************************** INCLUDES *****************************/
#include "irnet.h" /* Module global include */
#include <linux/miscdevice.h>
/************************ CONSTANTS & MACROS ************************/
/* /dev/irnet file constants */
#define IRNET_MAJOR 10 /* Misc range */
#define IRNET_MINOR 187 /* Official allocation */
/* IrNET control channel stuff */
#define IRNET_MAX_COMMAND 256 /* Max length of a command line */
@ -111,9 +108,9 @@ static const struct file_operations irnet_device_fops =
/* Structure so that the misc major (drivers/char/misc.c) take care of us... */
static struct miscdevice irnet_misc_device =
{
IRNET_MINOR,
"irnet",
&irnet_device_fops
.minor = IRNET_MINOR,
.name = "irnet",
.fops = &irnet_device_fops
};
#endif /* IRNET_PPP_H */

View File

@ -23,7 +23,6 @@
*
********************************************************************/
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/module.h>

View File

@ -265,7 +265,8 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
if (uni) {
rcu_assign_pointer(sdata->default_unicast_key, key);
ieee80211_check_fast_xmit_iface(sdata);
drv_set_default_unicast_key(sdata->local, sdata, idx);
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
drv_set_default_unicast_key(sdata->local, sdata, idx);
}
if (multi)

View File

@ -2472,7 +2472,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (!ifmsh->mshcfg.dot11MeshForwarding)
goto out;
fwd_skb = skb_copy(skb, GFP_ATOMIC);
fwd_skb = skb_copy_expand(skb, local->tx_headroom, 0, GFP_ATOMIC);
if (!fwd_skb) {
net_info_ratelimited("%s: failed to clone mesh frame\n",
sdata->name);

View File

@ -1972,6 +1972,7 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
u16 brate;
unsigned int shift;
rinfo->flags = 0;
sband = local->hw.wiphy->bands[(rate >> 4) & 0xf];
brate = sband->bitrates[rate & 0xf].bitrate;
if (rinfo->bw == RATE_INFO_BW_5)
@ -1987,14 +1988,15 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
static void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
{
u16 rate = ACCESS_ONCE(sta_get_last_rx_stats(sta)->last_rate);
if (rate == STA_STATS_RATE_INVALID)
rinfo->flags = 0;
else
sta_stats_decode_rate(sta->local, rate, rinfo);
return -EINVAL;
sta_stats_decode_rate(sta->local, rate, rinfo);
return 0;
}
static void sta_set_tidstats(struct sta_info *sta,
@ -2199,8 +2201,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
}
if (!(sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))) {
sta_set_rate_info_rx(sta, &sinfo->rxrate);
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
if (sta_set_rate_info_rx(sta, &sinfo->rxrate) == 0)
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
}
sinfo->filled |= BIT(NL80211_STA_INFO_TID_STATS);

View File

@ -252,7 +252,7 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
offload.cookie = (unsigned long)f;
offload.dissector = dissector;
offload.mask = mask;
offload.key = &f->key;
offload.key = &f->mkey;
offload.exts = &f->exts;
tc->type = TC_SETUP_CLSFLOWER;
@ -509,6 +509,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
mask->control.addr_type = ~0;
fl_set_key_val(tb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
&mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
sizeof(key->ipv4.src));
@ -517,6 +518,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
sizeof(key->ipv4.dst));
} else if (tb[TCA_FLOWER_KEY_IPV6_SRC] || tb[TCA_FLOWER_KEY_IPV6_DST]) {
key->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
mask->control.addr_type = ~0;
fl_set_key_val(tb, &key->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC,
&mask->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC_MASK,
sizeof(key->ipv6.src));
@ -571,6 +573,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
if (tb[TCA_FLOWER_KEY_ENC_IPV4_SRC] ||
tb[TCA_FLOWER_KEY_ENC_IPV4_DST]) {
key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
mask->enc_control.addr_type = ~0;
fl_set_key_val(tb, &key->enc_ipv4.src,
TCA_FLOWER_KEY_ENC_IPV4_SRC,
&mask->enc_ipv4.src,
@ -586,6 +589,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
if (tb[TCA_FLOWER_KEY_ENC_IPV6_SRC] ||
tb[TCA_FLOWER_KEY_ENC_IPV6_DST]) {
key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
mask->enc_control.addr_type = ~0;
fl_set_key_val(tb, &key->enc_ipv6.src,
TCA_FLOWER_KEY_ENC_IPV6_SRC,
&mask->enc_ipv6.src,

View File

@ -331,7 +331,9 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
* on this endpoint.
*/
if (!ep->base.bind_addr.port)
goto out;
return NULL;
rcu_read_lock();
t = sctp_epaddr_lookup_transport(ep, paddr);
if (!t)
goto out;
@ -339,6 +341,7 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
*transport = t;
asoc = t->asoc;
out:
rcu_read_unlock();
return asoc;
}

View File

@ -4472,18 +4472,17 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
const union sctp_addr *paddr, void *p)
{
struct sctp_transport *transport;
int err = -ENOENT;
int err;
rcu_read_lock();
transport = sctp_addrs_lookup_transport(net, laddr, paddr);
if (!transport)
goto out;
rcu_read_unlock();
if (!transport)
return -ENOENT;
err = cb(transport, p);
sctp_transport_put(transport);
out:
return err;
}
EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);

View File

@ -662,19 +662,19 @@ static void vmci_transport_notify_pkt_process_negotiate(struct sock *sk)
/* Socket control packet based operations. */
const struct vmci_transport_notify_ops vmci_transport_notify_pkt_ops = {
vmci_transport_notify_pkt_socket_init,
vmci_transport_notify_pkt_socket_destruct,
vmci_transport_notify_pkt_poll_in,
vmci_transport_notify_pkt_poll_out,
vmci_transport_notify_pkt_handle_pkt,
vmci_transport_notify_pkt_recv_init,
vmci_transport_notify_pkt_recv_pre_block,
vmci_transport_notify_pkt_recv_pre_dequeue,
vmci_transport_notify_pkt_recv_post_dequeue,
vmci_transport_notify_pkt_send_init,
vmci_transport_notify_pkt_send_pre_block,
vmci_transport_notify_pkt_send_pre_enqueue,
vmci_transport_notify_pkt_send_post_enqueue,
vmci_transport_notify_pkt_process_request,
vmci_transport_notify_pkt_process_negotiate,
.socket_init = vmci_transport_notify_pkt_socket_init,
.socket_destruct = vmci_transport_notify_pkt_socket_destruct,
.poll_in = vmci_transport_notify_pkt_poll_in,
.poll_out = vmci_transport_notify_pkt_poll_out,
.handle_notify_pkt = vmci_transport_notify_pkt_handle_pkt,
.recv_init = vmci_transport_notify_pkt_recv_init,
.recv_pre_block = vmci_transport_notify_pkt_recv_pre_block,
.recv_pre_dequeue = vmci_transport_notify_pkt_recv_pre_dequeue,
.recv_post_dequeue = vmci_transport_notify_pkt_recv_post_dequeue,
.send_init = vmci_transport_notify_pkt_send_init,
.send_pre_block = vmci_transport_notify_pkt_send_pre_block,
.send_pre_enqueue = vmci_transport_notify_pkt_send_pre_enqueue,
.send_post_enqueue = vmci_transport_notify_pkt_send_post_enqueue,
.process_request = vmci_transport_notify_pkt_process_request,
.process_negotiate = vmci_transport_notify_pkt_process_negotiate,
};

View File

@ -420,19 +420,19 @@ vmci_transport_notify_pkt_send_pre_enqueue(
/* Socket always on control packet based operations. */
const struct vmci_transport_notify_ops vmci_transport_notify_pkt_q_state_ops = {
vmci_transport_notify_pkt_socket_init,
vmci_transport_notify_pkt_socket_destruct,
vmci_transport_notify_pkt_poll_in,
vmci_transport_notify_pkt_poll_out,
vmci_transport_notify_pkt_handle_pkt,
vmci_transport_notify_pkt_recv_init,
vmci_transport_notify_pkt_recv_pre_block,
vmci_transport_notify_pkt_recv_pre_dequeue,
vmci_transport_notify_pkt_recv_post_dequeue,
vmci_transport_notify_pkt_send_init,
vmci_transport_notify_pkt_send_pre_block,
vmci_transport_notify_pkt_send_pre_enqueue,
vmci_transport_notify_pkt_send_post_enqueue,
vmci_transport_notify_pkt_process_request,
vmci_transport_notify_pkt_process_negotiate,
.socket_init = vmci_transport_notify_pkt_socket_init,
.socket_destruct = vmci_transport_notify_pkt_socket_destruct,
.poll_in = vmci_transport_notify_pkt_poll_in,
.poll_out = vmci_transport_notify_pkt_poll_out,
.handle_notify_pkt = vmci_transport_notify_pkt_handle_pkt,
.recv_init = vmci_transport_notify_pkt_recv_init,
.recv_pre_block = vmci_transport_notify_pkt_recv_pre_block,
.recv_pre_dequeue = vmci_transport_notify_pkt_recv_pre_dequeue,
.recv_post_dequeue = vmci_transport_notify_pkt_recv_post_dequeue,
.send_init = vmci_transport_notify_pkt_send_init,
.send_pre_block = vmci_transport_notify_pkt_send_pre_block,
.send_pre_enqueue = vmci_transport_notify_pkt_send_pre_enqueue,
.send_post_enqueue = vmci_transport_notify_pkt_send_post_enqueue,
.process_request = vmci_transport_notify_pkt_process_request,
.process_negotiate = vmci_transport_notify_pkt_process_negotiate,
};

View File

@ -70,7 +70,7 @@ static struct ctl_table x25_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
{ 0, },
{ },
};
void __init x25_register_sysctl(void)

View File

@ -1059,7 +1059,7 @@ static struct bpf_test tests[] = {
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
.errstr_unpriv = "unknown func 6",
.errstr_unpriv = "unknown func bpf_trace_printk#6",
.result_unpriv = REJECT,
.result = ACCEPT,
},
@ -2660,6 +2660,34 @@ static struct bpf_test tests[] = {
.result = ACCEPT,
.prog_type = BPF_PROG_TYPE_SCHED_CLS
},
{
"multiple registers share map_lookup_elem bad reg type",
.insns = {
BPF_MOV64_IMM(BPF_REG_1, 10),
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
BPF_LD_MAP_FD(BPF_REG_1, 0),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
BPF_FUNC_map_lookup_elem),
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
BPF_MOV64_IMM(BPF_REG_1, 1),
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
BPF_MOV64_IMM(BPF_REG_1, 2),
BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1),
BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 0),
BPF_MOV64_IMM(BPF_REG_1, 3),
BPF_EXIT_INSN(),
},
.fixup_map1 = { 4 },
.result = REJECT,
.errstr = "R3 invalid mem access 'inv'",
.prog_type = BPF_PROG_TYPE_SCHED_CLS
},
{
"invalid map access from else condition",
.insns = {