mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
Including fixes from Bluetooth and WiFi. Notably this includes the fix
for the iwlwifi issue you reported.
Current release - regressions:
- core: avoid prefetching NULL pointers
- wifi:
- iwlwifi: implement settime64 as stub for MVM/MLD PTP
- mac80211: fix list iteration in ieee80211_add_virtual_monitor()
- handshake: fix null-ptr-deref in handshake_complete()
- eth: mana: fix use-after-free in reset service rescan path
Previous releases - regressions:
- openvswitch: avoid needlessly taking the RTNL on vport destroy
- dsa: properly keep track of conduit reference
- ipv4:
- fix reference count leak when using error routes with nexthop objects
- fib: restore ECMP balance from loopback
- mptcp: ensure context reset on disconnect()
- bluetooth: fix potential UaF in btusb
- nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write
- eth: gve: defer interrupt enabling until NAPI registration
- eth: i40e: fix scheduling in set_rx_mode
- eth: macb: relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()
- eth: rtl8150: fix memory leak on usb_submit_urb() failure
- wifi: 8192cu: fix tid out of range in rtl92cu_tx_fill_desc()
Previous releases - always broken:
- ip6_gre: make ip6gre_header() robust
- ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT
- af_unix: don't post cmsg for SO_INQ unless explicitly asked for
- phy: mediatek: fix nvmem cell reference leak in mt798x_phy_calibration
- wifi: mac80211: discard beacon frames to non-broadcast address
- eth: iavf: fix off-by-one issues in iavf_config_rss_reg()
- eth: stmmac: fix the crash issue for zero copy XDP_TX action
- eth: team: fix check for port enabled in team_queue_override_port_prio_changed()
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-----BEGIN PGP SIGNATURE-----
iQJGBAABCgAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmlT43wSHHBhYmVuaUBy
ZWRoYXQuY29tAAoJECkkeY3MjxOkHhMP/jF3B8c3djMgpYpEwPRgqJlzdpBGQvcO
UsN/8fYI/XowIcU6T/yC/KM5cABCWyfnj6yZe743wPrlj8DnWK7+Fezrfwx7l8e0
0LH9kVwOIaQXg/QthtXaDHNB/9OanDtgcpitI209gENRjF81bYWCehImil6jbVnn
DUnVmfZIQ6k3dFsAPC4W7uJdA2FORtQzEZ1dZ13Ivx9jmbazK81ptUbIMAAnyfIZ
rUhv+UqaDIlflYwuay58ZPdu8no4nQlJMPiPybXiizfTVStEne9SQKOacP8j7XL0
GSjEyDO8lJXCPVSVnGEyybBH50M0myGUSH73+56o2QRRLtrHLDfieOL/N8AarNDh
7U2g9pq0+IFPuJsm9SFR14dIpUAvpKohc57ZvsmworC8NuENzl6H3b6/U4n/1oNE
JCbcitl91GkyF0Bvyac5a9wfk8SsYEJEGLPrtNX8UwH0UJh8spkfoQq5oHkC3juQ
77n//eOFSz8oPDlV7ayNv+W3CEzOW09mSYFu8bdjBKC5HeyBJsm3HnJdaAhSqNEH
6duRvcMlUJQ0JPILJoS1Zoy166uIu8hs2mZtygcAzyacia8yckL+Oq2UCYMi2oKP
psOIzfd6G/+f203w37jdSY0OVlQSHvmCFSeaY6FHs2LEApDrNWK1cMLYO+lMU8EE
q0j2SmDNMHhM
=P1hX
-----END PGP SIGNATURE-----
Merge tag 'net-6.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Including fixes from Bluetooth and WiFi. Notably this includes the fix
for the iwlwifi issue you reported.
Current release - regressions:
- core: avoid prefetching NULL pointers
- wifi:
- iwlwifi: implement settime64 as stub for MVM/MLD PTP
- mac80211: fix list iteration in ieee80211_add_virtual_monitor()
- handshake: fix null-ptr-deref in handshake_complete()
- eth: mana: fix use-after-free in reset service rescan path
Previous releases - regressions:
- openvswitch: avoid needlessly taking the RTNL on vport destroy
- dsa: properly keep track of conduit reference
- ipv4:
- fix error route reference count leak with nexthop objects
- fib: restore ECMP balance from loopback
- mptcp: ensure context reset on disconnect()
- bluetooth: fix potential UaF in btusb
- nfc: fix deadlock between nfc_unregister_device and
rfkill_fop_write
- eth:
- gve: defer interrupt enabling until NAPI registration
- i40e: fix scheduling in set_rx_mode
- macb: relocate mog_init_rings() callback from macb_mac_link_up()
to macb_open()
- rtl8150: fix memory leak on usb_submit_urb() failure
- wifi: 8192cu: fix tid out of range in rtl92cu_tx_fill_desc()
Previous releases - always broken:
- ip6_gre: make ip6gre_header() robust
- ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT
- af_unix: don't post cmsg for SO_INQ unless explicitly asked for
- phy: mediatek: fix nvmem cell reference leak in
mt798x_phy_calibration
- wifi: mac80211: discard beacon frames to non-broadcast address
- eth:
- iavf: fix off-by-one issues in iavf_config_rss_reg()
- stmmac: fix the crash issue for zero copy XDP_TX action
- team: fix check for port enabled when priority changes"
* tag 'net-6.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (64 commits)
ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT
net: rose: fix invalid array index in rose_kill_by_device()
net: enetc: do not print error log if addr is 0
net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()
selftests: fib_test: Add test case for ipv4 multi nexthops
net: fib: restore ECMP balance from loopback
selftests: fib_nexthops: Add test cases for error routes deletion
ipv4: Fix reference count leak when using error routes with nexthop objects
net: usb: sr9700: fix incorrect command used to write single register
ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr()
usbnet: avoid a possible crash in dql_completed()
gve: defer interrupt enabling until NAPI registration
net: stmmac: fix the crash issue for zero copy XDP_TX action
octeontx2-pf: fix "UBSAN: shift-out-of-bounds error"
af_unix: don't post cmsg for SO_INQ unless explicitly asked for
net: mana: Fix use-after-free in reset service rescan path
net: avoid prefetching NULL pointers
net: bridge: Describe @tunnel_hash member in net_bridge_vlan_group struct
net: nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write
net: usb: asix: validate PHY address before use
...
This commit is contained in:
commit
dbf8fe85a1
@ -4052,7 +4052,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -4075,8 +4075,10 @@ static int btusb_probe(struct usb_interface *intf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
|
if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
|
||||||
|
kfree(data);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
if (id->driver_info & BTUSB_AMP) {
|
if (id->driver_info & BTUSB_AMP) {
|
||||||
data->cmdreq_type = USB_TYPE_CLASS | 0x01;
|
data->cmdreq_type = USB_TYPE_CLASS | 0x01;
|
||||||
@ -4131,8 +4133,10 @@ static int btusb_probe(struct usb_interface *intf,
|
|||||||
data->recv_acl = hci_recv_frame;
|
data->recv_acl = hci_recv_frame;
|
||||||
|
|
||||||
hdev = hci_alloc_dev_priv(priv_size);
|
hdev = hci_alloc_dev_priv(priv_size);
|
||||||
if (!hdev)
|
if (!hdev) {
|
||||||
|
kfree(data);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
hdev->bus = HCI_USB;
|
hdev->bus = HCI_USB;
|
||||||
hci_set_drvdata(hdev, data);
|
hci_set_drvdata(hdev, data);
|
||||||
@ -4406,6 +4410,7 @@ out_free_dev:
|
|||||||
if (data->reset_gpio)
|
if (data->reset_gpio)
|
||||||
gpiod_put(data->reset_gpio);
|
gpiod_put(data->reset_gpio);
|
||||||
hci_free_dev(hdev);
|
hci_free_dev(hdev);
|
||||||
|
kfree(data);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4454,6 +4459,7 @@ static void btusb_disconnect(struct usb_interface *intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hci_free_dev(hdev);
|
hci_free_dev(hdev);
|
||||||
|
kfree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|||||||
@ -2169,6 +2169,9 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
|
|||||||
if (!ent->is_valid)
|
if (!ent->is_valid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (is_multicast_ether_addr(ent->mac))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (port != ent->port)
|
if (port != ent->port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@ -2924,19 +2924,26 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
|||||||
port->id = id;
|
port->id = id;
|
||||||
eth->ports[p] = port;
|
eth->ports[p] = port;
|
||||||
|
|
||||||
err = airoha_metadata_dst_alloc(port);
|
return airoha_metadata_dst_alloc(port);
|
||||||
if (err)
|
}
|
||||||
return err;
|
|
||||||
|
|
||||||
err = register_netdev(dev);
|
static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
||||||
if (err)
|
{
|
||||||
goto free_metadata_dst;
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||||
|
struct airoha_gdm_port *port = eth->ports[i];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!port)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
err = register_netdev(port->dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_metadata_dst:
|
|
||||||
airoha_metadata_dst_free(port);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int airoha_probe(struct platform_device *pdev)
|
static int airoha_probe(struct platform_device *pdev)
|
||||||
@ -3027,6 +3034,10 @@ static int airoha_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = airoha_register_gdm_devices(eth);
|
||||||
|
if (err)
|
||||||
|
goto error_napi_stop;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_napi_stop:
|
error_napi_stop:
|
||||||
@ -3040,10 +3051,12 @@ error_hw_cleanup:
|
|||||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||||
struct airoha_gdm_port *port = eth->ports[i];
|
struct airoha_gdm_port *port = eth->ports[i];
|
||||||
|
|
||||||
if (port && port->dev->reg_state == NETREG_REGISTERED) {
|
if (!port)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (port->dev->reg_state == NETREG_REGISTERED)
|
||||||
unregister_netdev(port->dev);
|
unregister_netdev(port->dev);
|
||||||
airoha_metadata_dst_free(port);
|
airoha_metadata_dst_free(port);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free_netdev(eth->napi_dev);
|
free_netdev(eth->napi_dev);
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|||||||
@ -1928,6 +1928,7 @@ static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata,
|
|||||||
{
|
{
|
||||||
if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
|
if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
|
||||||
pdata->rx_adapt_retries = 0;
|
pdata->rx_adapt_retries = 0;
|
||||||
|
pdata->mode_set = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1974,6 +1975,7 @@ static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata)
|
|||||||
*/
|
*/
|
||||||
netif_dbg(pdata, link, pdata->netdev, "Block_lock done");
|
netif_dbg(pdata, link, pdata->netdev, "Block_lock done");
|
||||||
pdata->rx_adapt_done = true;
|
pdata->rx_adapt_done = true;
|
||||||
|
pdata->rx_adapt_retries = 0;
|
||||||
pdata->mode_set = false;
|
pdata->mode_set = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -255,14 +255,14 @@ config BNXT_HWMON
|
|||||||
devices, via the hwmon sysfs interface.
|
devices, via the hwmon sysfs interface.
|
||||||
|
|
||||||
config BNGE
|
config BNGE
|
||||||
tristate "Broadcom Ethernet device support"
|
tristate "Broadcom ThorUltra Ethernet device support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
select NET_DEVLINK
|
select NET_DEVLINK
|
||||||
select PAGE_POOL
|
select PAGE_POOL
|
||||||
help
|
help
|
||||||
This driver supports Broadcom 50/100/200/400/800 gigabit Ethernet cards.
|
This driver supports Broadcom ThorUltra 50/100/200/400/800 gigabit
|
||||||
The module will be called bng_en. To compile this driver as a module,
|
Ethernet cards. The module will be called bng_en. To compile this
|
||||||
choose M here.
|
driver as a module, choose M here.
|
||||||
|
|
||||||
config BCMASP
|
config BCMASP
|
||||||
tristate "Broadcom ASP 2.0 Ethernet support"
|
tristate "Broadcom ASP 2.0 Ethernet support"
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#define _BNGE_H_
|
#define _BNGE_H_
|
||||||
|
|
||||||
#define DRV_NAME "bng_en"
|
#define DRV_NAME "bng_en"
|
||||||
#define DRV_SUMMARY "Broadcom 800G Ethernet Linux Driver"
|
#define DRV_SUMMARY "Broadcom ThorUltra NIC Ethernet Driver"
|
||||||
|
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/bnxt/hsi.h>
|
#include <linux/bnxt/hsi.h>
|
||||||
|
|||||||
@ -19,7 +19,7 @@ char bnge_driver_name[] = DRV_NAME;
|
|||||||
static const struct {
|
static const struct {
|
||||||
char *name;
|
char *name;
|
||||||
} board_info[] = {
|
} board_info[] = {
|
||||||
[BCM57708] = { "Broadcom BCM57708 50Gb/100Gb/200Gb/400Gb/800Gb Ethernet" },
|
[BCM57708] = { "Broadcom BCM57708 ThorUltra 50Gb/100Gb/200Gb/400Gb/800Gb Ethernet" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pci_device_id bnge_pci_tbl[] = {
|
static const struct pci_device_id bnge_pci_tbl[] = {
|
||||||
|
|||||||
@ -708,7 +708,6 @@ static void macb_mac_link_up(struct phylink_config *config,
|
|||||||
/* Initialize rings & buffers as clearing MACB_BIT(TE) in link down
|
/* Initialize rings & buffers as clearing MACB_BIT(TE) in link down
|
||||||
* cleared the pipeline and control registers.
|
* cleared the pipeline and control registers.
|
||||||
*/
|
*/
|
||||||
bp->macbgem_ops.mog_init_rings(bp);
|
|
||||||
macb_init_buffers(bp);
|
macb_init_buffers(bp);
|
||||||
|
|
||||||
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
|
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
|
||||||
@ -2954,6 +2953,8 @@ static int macb_open(struct net_device *dev)
|
|||||||
goto pm_exit;
|
goto pm_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bp->macbgem_ops.mog_init_rings(bp);
|
||||||
|
|
||||||
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
|
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
|
||||||
napi_enable(&queue->napi_rx);
|
napi_enable(&queue->napi_rx);
|
||||||
napi_enable(&queue->napi_tx);
|
napi_enable(&queue->napi_tx);
|
||||||
|
|||||||
@ -577,11 +577,17 @@ static int imx94_enetc_mdio_phyaddr_config(struct netc_blk_ctrl *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
addr = netc_get_phy_addr(np);
|
addr = netc_get_phy_addr(np);
|
||||||
if (addr <= 0) {
|
if (addr < 0) {
|
||||||
dev_err(dev, "Failed to get PHY address\n");
|
dev_err(dev, "Failed to get PHY address\n");
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The default value of LaBCR[MDIO_PHYAD_PRTAD] is 0,
|
||||||
|
* so no need to set the register.
|
||||||
|
*/
|
||||||
|
if (!addr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (phy_mask & BIT(addr)) {
|
if (phy_mask & BIT(addr)) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"Find same PHY address in EMDIO and ENETC node\n");
|
"Find same PHY address in EMDIO and ENETC node\n");
|
||||||
|
|||||||
@ -558,7 +558,7 @@ static int gve_alloc_notify_blocks(struct gve_priv *priv)
|
|||||||
block->priv = priv;
|
block->priv = priv;
|
||||||
err = request_irq(priv->msix_vectors[msix_idx].vector,
|
err = request_irq(priv->msix_vectors[msix_idx].vector,
|
||||||
gve_is_gqi(priv) ? gve_intr : gve_intr_dqo,
|
gve_is_gqi(priv) ? gve_intr : gve_intr_dqo,
|
||||||
0, block->name, block);
|
IRQF_NO_AUTOEN, block->name, block);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&priv->pdev->dev,
|
dev_err(&priv->pdev->dev,
|
||||||
"Failed to receive msix vector %d\n", i);
|
"Failed to receive msix vector %d\n", i);
|
||||||
|
|||||||
@ -112,11 +112,13 @@ void gve_add_napi(struct gve_priv *priv, int ntfy_idx,
|
|||||||
|
|
||||||
netif_napi_add_locked(priv->dev, &block->napi, gve_poll);
|
netif_napi_add_locked(priv->dev, &block->napi, gve_poll);
|
||||||
netif_napi_set_irq_locked(&block->napi, block->irq);
|
netif_napi_set_irq_locked(&block->napi, block->irq);
|
||||||
|
enable_irq(block->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gve_remove_napi(struct gve_priv *priv, int ntfy_idx)
|
void gve_remove_napi(struct gve_priv *priv, int ntfy_idx)
|
||||||
{
|
{
|
||||||
struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
|
struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
|
||||||
|
|
||||||
|
disable_irq(block->irq);
|
||||||
netif_napi_del_locked(&block->napi);
|
netif_napi_del_locked(&block->napi);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4094,7 +4094,15 @@ static bool e1000_tbi_should_accept(struct e1000_adapter *adapter,
|
|||||||
u32 length, const u8 *data)
|
u32 length, const u8 *data)
|
||||||
{
|
{
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
u8 last_byte = *(data + length - 1);
|
u8 last_byte;
|
||||||
|
|
||||||
|
/* Guard against OOB on data[length - 1] */
|
||||||
|
if (unlikely(!length))
|
||||||
|
return false;
|
||||||
|
/* Upper bound: length must not exceed rx_buffer_len */
|
||||||
|
if (unlikely(length > adapter->rx_buffer_len))
|
||||||
|
return false;
|
||||||
|
last_byte = *(data + length - 1);
|
||||||
|
|
||||||
if (TBI_ACCEPT(hw, status, errors, length, last_byte)) {
|
if (TBI_ACCEPT(hw, status, errors, length, last_byte)) {
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
|
|||||||
@ -1422,4 +1422,15 @@ static inline struct i40e_veb *i40e_pf_get_main_veb(struct i40e_pf *pf)
|
|||||||
return (pf->lan_veb != I40E_NO_VEB) ? pf->veb[pf->lan_veb] : NULL;
|
return (pf->lan_veb != I40E_NO_VEB) ? pf->veb[pf->lan_veb] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 i40e_get_max_num_descriptors(const struct i40e_pf *pf)
|
||||||
|
{
|
||||||
|
const struct i40e_hw *hw = &pf->hw;
|
||||||
|
|
||||||
|
switch (hw->mac.type) {
|
||||||
|
case I40E_MAC_XL710:
|
||||||
|
return I40E_MAX_NUM_DESCRIPTORS_XL710;
|
||||||
|
default:
|
||||||
|
return I40E_MAX_NUM_DESCRIPTORS;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* _I40E_H_ */
|
#endif /* _I40E_H_ */
|
||||||
|
|||||||
@ -2013,18 +2013,6 @@ static void i40e_get_drvinfo(struct net_device *netdev,
|
|||||||
drvinfo->n_priv_flags += I40E_GL_PRIV_FLAGS_STR_LEN;
|
drvinfo->n_priv_flags += I40E_GL_PRIV_FLAGS_STR_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 i40e_get_max_num_descriptors(struct i40e_pf *pf)
|
|
||||||
{
|
|
||||||
struct i40e_hw *hw = &pf->hw;
|
|
||||||
|
|
||||||
switch (hw->mac.type) {
|
|
||||||
case I40E_MAC_XL710:
|
|
||||||
return I40E_MAX_NUM_DESCRIPTORS_XL710;
|
|
||||||
default:
|
|
||||||
return I40E_MAX_NUM_DESCRIPTORS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void i40e_get_ringparam(struct net_device *netdev,
|
static void i40e_get_ringparam(struct net_device *netdev,
|
||||||
struct ethtool_ringparam *ring,
|
struct ethtool_ringparam *ring,
|
||||||
struct kernel_ethtool_ringparam *kernel_ring,
|
struct kernel_ethtool_ringparam *kernel_ring,
|
||||||
|
|||||||
@ -2234,6 +2234,7 @@ static void i40e_set_rx_mode(struct net_device *netdev)
|
|||||||
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
|
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
|
||||||
set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state);
|
set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state);
|
||||||
}
|
}
|
||||||
|
i40e_service_event_schedule(vsi->back);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -656,7 +656,7 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id,
|
|||||||
|
|
||||||
/* ring_len has to be multiple of 8 */
|
/* ring_len has to be multiple of 8 */
|
||||||
if (!IS_ALIGNED(info->ring_len, 8) ||
|
if (!IS_ALIGNED(info->ring_len, 8) ||
|
||||||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
|
info->ring_len > i40e_get_max_num_descriptors(pf)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error_context;
|
goto error_context;
|
||||||
}
|
}
|
||||||
@ -726,7 +726,7 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,
|
|||||||
|
|
||||||
/* ring_len has to be multiple of 32 */
|
/* ring_len has to be multiple of 32 */
|
||||||
if (!IS_ALIGNED(info->ring_len, 32) ||
|
if (!IS_ALIGNED(info->ring_len, 32) ||
|
||||||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
|
info->ring_len > i40e_get_max_num_descriptors(pf)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1726,11 +1726,11 @@ static int iavf_config_rss_reg(struct iavf_adapter *adapter)
|
|||||||
u16 i;
|
u16 i;
|
||||||
|
|
||||||
dw = (u32 *)adapter->rss_key;
|
dw = (u32 *)adapter->rss_key;
|
||||||
for (i = 0; i <= adapter->rss_key_size / 4; i++)
|
for (i = 0; i < adapter->rss_key_size / 4; i++)
|
||||||
wr32(hw, IAVF_VFQF_HKEY(i), dw[i]);
|
wr32(hw, IAVF_VFQF_HKEY(i), dw[i]);
|
||||||
|
|
||||||
dw = (u32 *)adapter->rss_lut;
|
dw = (u32 *)adapter->rss_lut;
|
||||||
for (i = 0; i <= adapter->rss_lut_size / 4; i++)
|
for (i = 0; i < adapter->rss_lut_size / 4; i++)
|
||||||
wr32(hw, IAVF_VFQF_HLUT(i), dw[i]);
|
wr32(hw, IAVF_VFQF_HLUT(i), dw[i]);
|
||||||
|
|
||||||
iavf_flush(hw);
|
iavf_flush(hw);
|
||||||
|
|||||||
@ -1271,7 +1271,7 @@ void idpf_mbx_task(struct work_struct *work)
|
|||||||
idpf_mb_irq_enable(adapter);
|
idpf_mb_irq_enable(adapter);
|
||||||
else
|
else
|
||||||
queue_delayed_work(adapter->mbx_wq, &adapter->mbx_task,
|
queue_delayed_work(adapter->mbx_wq, &adapter->mbx_task,
|
||||||
msecs_to_jiffies(300));
|
usecs_to_jiffies(300));
|
||||||
|
|
||||||
idpf_recv_mb_msg(adapter);
|
idpf_recv_mb_msg(adapter);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1016,6 +1016,9 @@ static int idpf_send_get_lan_memory_regions(struct idpf_adapter *adapter)
|
|||||||
struct idpf_vc_xn_params xn_params = {
|
struct idpf_vc_xn_params xn_params = {
|
||||||
.vc_op = VIRTCHNL2_OP_GET_LAN_MEMORY_REGIONS,
|
.vc_op = VIRTCHNL2_OP_GET_LAN_MEMORY_REGIONS,
|
||||||
.recv_buf.iov_len = IDPF_CTLQ_MAX_BUF_LEN,
|
.recv_buf.iov_len = IDPF_CTLQ_MAX_BUF_LEN,
|
||||||
|
.send_buf.iov_len =
|
||||||
|
sizeof(struct virtchnl2_get_lan_memory_regions) +
|
||||||
|
sizeof(struct virtchnl2_mem_region),
|
||||||
.timeout_ms = IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC,
|
.timeout_ms = IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC,
|
||||||
};
|
};
|
||||||
int num_regions, size;
|
int num_regions, size;
|
||||||
@ -1028,6 +1031,8 @@ static int idpf_send_get_lan_memory_regions(struct idpf_adapter *adapter)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
xn_params.recv_buf.iov_base = rcvd_regions;
|
xn_params.recv_buf.iov_base = rcvd_regions;
|
||||||
|
rcvd_regions->num_memory_regions = cpu_to_le16(1);
|
||||||
|
xn_params.send_buf.iov_base = rcvd_regions;
|
||||||
reply_sz = idpf_vc_xn_exec(adapter, &xn_params);
|
reply_sz = idpf_vc_xn_exec(adapter, &xn_params);
|
||||||
if (reply_sz < 0)
|
if (reply_sz < 0)
|
||||||
return reply_sz;
|
return reply_sz;
|
||||||
|
|||||||
@ -418,6 +418,14 @@ static int otx2_set_ringparam(struct net_device *netdev,
|
|||||||
*/
|
*/
|
||||||
if (rx_count < pfvf->hw.rq_skid)
|
if (rx_count < pfvf->hw.rq_skid)
|
||||||
rx_count = pfvf->hw.rq_skid;
|
rx_count = pfvf->hw.rq_skid;
|
||||||
|
|
||||||
|
if (ring->rx_pending < 16) {
|
||||||
|
netdev_err(netdev,
|
||||||
|
"rx ring size %u invalid, min is 16\n",
|
||||||
|
ring->rx_pending);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
rx_count = Q_COUNT(Q_SIZE(rx_count, 3));
|
rx_count = Q_COUNT(Q_SIZE(rx_count, 3));
|
||||||
|
|
||||||
/* Due pipelining impact minimum 2000 unused SQ CQE's
|
/* Due pipelining impact minimum 2000 unused SQ CQE's
|
||||||
|
|||||||
@ -481,7 +481,7 @@ static void mana_serv_reset(struct pci_dev *pdev)
|
|||||||
/* Perform PCI rescan on device if we failed on HWC */
|
/* Perform PCI rescan on device if we failed on HWC */
|
||||||
dev_err(&pdev->dev, "MANA service: resume failed, rescanning\n");
|
dev_err(&pdev->dev, "MANA service: resume failed, rescanning\n");
|
||||||
mana_serv_rescan(pdev);
|
mana_serv_rescan(pdev);
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
@ -516,15 +516,7 @@ static inline void smc_rcv(struct net_device *dev)
|
|||||||
* any other concurrent access and C would always interrupt B. But life
|
* any other concurrent access and C would always interrupt B. But life
|
||||||
* isn't that easy in a SMP world...
|
* isn't that easy in a SMP world...
|
||||||
*/
|
*/
|
||||||
#define smc_special_trylock(lock, flags) \
|
#define smc_special_trylock(lock, flags) spin_trylock_irqsave(lock, flags)
|
||||||
({ \
|
|
||||||
int __ret; \
|
|
||||||
local_irq_save(flags); \
|
|
||||||
__ret = spin_trylock(lock); \
|
|
||||||
if (!__ret) \
|
|
||||||
local_irq_restore(flags); \
|
|
||||||
__ret; \
|
|
||||||
})
|
|
||||||
#define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags)
|
#define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags)
|
||||||
#define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags)
|
#define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -89,6 +89,7 @@ MODULE_PARM_DESC(phyaddr, "Physical device address");
|
|||||||
#define STMMAC_XDP_CONSUMED BIT(0)
|
#define STMMAC_XDP_CONSUMED BIT(0)
|
||||||
#define STMMAC_XDP_TX BIT(1)
|
#define STMMAC_XDP_TX BIT(1)
|
||||||
#define STMMAC_XDP_REDIRECT BIT(2)
|
#define STMMAC_XDP_REDIRECT BIT(2)
|
||||||
|
#define STMMAC_XSK_CONSUMED BIT(3)
|
||||||
|
|
||||||
static int flow_ctrl = 0xdead;
|
static int flow_ctrl = 0xdead;
|
||||||
module_param(flow_ctrl, int, 0644);
|
module_param(flow_ctrl, int, 0644);
|
||||||
@ -5126,6 +5127,7 @@ static int stmmac_xdp_get_tx_queue(struct stmmac_priv *priv,
|
|||||||
static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
|
static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
|
||||||
struct xdp_buff *xdp)
|
struct xdp_buff *xdp)
|
||||||
{
|
{
|
||||||
|
bool zc = !!(xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL);
|
||||||
struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
|
struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
struct netdev_queue *nq;
|
struct netdev_queue *nq;
|
||||||
@ -5142,9 +5144,18 @@ static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
|
|||||||
/* Avoids TX time-out as we are sharing with slow path */
|
/* Avoids TX time-out as we are sharing with slow path */
|
||||||
txq_trans_cond_update(nq);
|
txq_trans_cond_update(nq);
|
||||||
|
|
||||||
res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, false);
|
/* For zero copy XDP_TX action, dma_map is true */
|
||||||
if (res == STMMAC_XDP_TX)
|
res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, zc);
|
||||||
|
if (res == STMMAC_XDP_TX) {
|
||||||
stmmac_flush_tx_descriptors(priv, queue);
|
stmmac_flush_tx_descriptors(priv, queue);
|
||||||
|
} else if (res == STMMAC_XDP_CONSUMED && zc) {
|
||||||
|
/* xdp has been freed by xdp_convert_buff_to_frame(),
|
||||||
|
* no need to call xsk_buff_free() again, so return
|
||||||
|
* STMMAC_XSK_CONSUMED.
|
||||||
|
*/
|
||||||
|
res = STMMAC_XSK_CONSUMED;
|
||||||
|
xdp_return_frame(xdpf);
|
||||||
|
}
|
||||||
|
|
||||||
__netif_tx_unlock(nq);
|
__netif_tx_unlock(nq);
|
||||||
|
|
||||||
@ -5494,6 +5505,8 @@ read_again:
|
|||||||
break;
|
break;
|
||||||
case STMMAC_XDP_CONSUMED:
|
case STMMAC_XDP_CONSUMED:
|
||||||
xsk_buff_free(buf->xdp);
|
xsk_buff_free(buf->xdp);
|
||||||
|
fallthrough;
|
||||||
|
case STMMAC_XSK_CONSUMED:
|
||||||
rx_dropped++;
|
rx_dropped++;
|
||||||
break;
|
break;
|
||||||
case STMMAC_XDP_TX:
|
case STMMAC_XDP_TX:
|
||||||
|
|||||||
@ -21,6 +21,7 @@ config LIBWX
|
|||||||
depends on PTP_1588_CLOCK_OPTIONAL
|
depends on PTP_1588_CLOCK_OPTIONAL
|
||||||
select PAGE_POOL
|
select PAGE_POOL
|
||||||
select DIMLIB
|
select DIMLIB
|
||||||
|
select PHYLINK
|
||||||
help
|
help
|
||||||
Common library for Wangxun(R) Ethernet drivers.
|
Common library for Wangxun(R) Ethernet drivers.
|
||||||
|
|
||||||
@ -29,7 +30,6 @@ config NGBE
|
|||||||
depends on PCI
|
depends on PCI
|
||||||
depends on PTP_1588_CLOCK_OPTIONAL
|
depends on PTP_1588_CLOCK_OPTIONAL
|
||||||
select LIBWX
|
select LIBWX
|
||||||
select PHYLINK
|
|
||||||
help
|
help
|
||||||
This driver supports Wangxun(R) GbE PCI Express family of
|
This driver supports Wangxun(R) GbE PCI Express family of
|
||||||
adapters.
|
adapters.
|
||||||
@ -48,7 +48,6 @@ config TXGBE
|
|||||||
depends on PTP_1588_CLOCK_OPTIONAL
|
depends on PTP_1588_CLOCK_OPTIONAL
|
||||||
select MARVELL_10G_PHY
|
select MARVELL_10G_PHY
|
||||||
select REGMAP
|
select REGMAP
|
||||||
select PHYLINK
|
|
||||||
select HWMON if TXGBE=y
|
select HWMON if TXGBE=y
|
||||||
select SFP
|
select SFP
|
||||||
select GPIOLIB
|
select GPIOLIB
|
||||||
@ -71,7 +70,6 @@ config TXGBEVF
|
|||||||
depends on PCI_MSI
|
depends on PCI_MSI
|
||||||
depends on PTP_1588_CLOCK_OPTIONAL
|
depends on PTP_1588_CLOCK_OPTIONAL
|
||||||
select LIBWX
|
select LIBWX
|
||||||
select PHYLINK
|
|
||||||
help
|
help
|
||||||
This driver supports virtual functions for SP1000A, WX1820AL,
|
This driver supports virtual functions for SP1000A, WX1820AL,
|
||||||
WX5XXX, WX5XXXAL.
|
WX5XXX, WX5XXXAL.
|
||||||
|
|||||||
@ -334,7 +334,7 @@ int fjes_hw_init(struct fjes_hw *hw)
|
|||||||
|
|
||||||
ret = fjes_hw_reset(hw);
|
ret = fjes_hw_reset(hw);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_iounmap;
|
||||||
|
|
||||||
fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
|
fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
|
||||||
|
|
||||||
@ -347,8 +347,10 @@ int fjes_hw_init(struct fjes_hw *hw)
|
|||||||
hw->max_epid = fjes_hw_get_max_epid(hw);
|
hw->max_epid = fjes_hw_get_max_epid(hw);
|
||||||
hw->my_epid = fjes_hw_get_my_epid(hw);
|
hw->my_epid = fjes_hw_get_my_epid(hw);
|
||||||
|
|
||||||
if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
|
if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid)) {
|
||||||
return -ENXIO;
|
ret = -ENXIO;
|
||||||
|
goto err_iounmap;
|
||||||
|
}
|
||||||
|
|
||||||
ret = fjes_hw_setup(hw);
|
ret = fjes_hw_setup(hw);
|
||||||
|
|
||||||
@ -356,6 +358,10 @@ int fjes_hw_init(struct fjes_hw *hw)
|
|||||||
hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;
|
hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
err_iounmap:
|
||||||
|
fjes_hw_iounmap(hw);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fjes_hw_exit(struct fjes_hw *hw)
|
void fjes_hw_exit(struct fjes_hw *hw)
|
||||||
|
|||||||
@ -63,6 +63,13 @@ static int aspeed_mdio_op(struct mii_bus *bus, u8 st, u8 op, u8 phyad, u8 regad,
|
|||||||
|
|
||||||
iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
|
iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
|
||||||
|
|
||||||
|
/* Workaround for read-after-write issue.
|
||||||
|
* The controller may return stale data if a read follows immediately
|
||||||
|
* after a write. A dummy read forces the hardware to update its
|
||||||
|
* internal state, ensuring that the next real read returns correct data.
|
||||||
|
*/
|
||||||
|
ioread32(ctx->base + ASPEED_MDIO_CTRL);
|
||||||
|
|
||||||
return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl,
|
return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl,
|
||||||
!(ctrl & ASPEED_MDIO_CTRL_FIRE),
|
!(ctrl & ASPEED_MDIO_CTRL_FIRE),
|
||||||
ASPEED_MDIO_INTERVAL_US,
|
ASPEED_MDIO_INTERVAL_US,
|
||||||
|
|||||||
@ -354,7 +354,6 @@ static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_pri
|
|||||||
struct fwnode_handle *node)
|
struct fwnode_handle *node)
|
||||||
{
|
{
|
||||||
struct rtl9300_mdio_chan *chan;
|
struct rtl9300_mdio_chan *chan;
|
||||||
struct fwnode_handle *child;
|
|
||||||
struct mii_bus *bus;
|
struct mii_bus *bus;
|
||||||
u32 mdio_bus;
|
u32 mdio_bus;
|
||||||
int err;
|
int err;
|
||||||
@ -371,7 +370,7 @@ static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_pri
|
|||||||
* compatible = "ethernet-phy-ieee802.3-c45". This does mean we can't
|
* compatible = "ethernet-phy-ieee802.3-c45". This does mean we can't
|
||||||
* support both c45 and c22 on the same MDIO bus.
|
* support both c45 and c22 on the same MDIO bus.
|
||||||
*/
|
*/
|
||||||
fwnode_for_each_child_node(node, child)
|
fwnode_for_each_child_node_scoped(node, child)
|
||||||
if (fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
|
if (fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
|
||||||
priv->smi_bus_is_c45[mdio_bus] = true;
|
priv->smi_bus_is_c45[mdio_bus] = true;
|
||||||
|
|
||||||
@ -409,7 +408,6 @@ static int rtl9300_mdiobus_map_ports(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct rtl9300_mdio_priv *priv = dev_get_drvdata(dev);
|
struct rtl9300_mdio_priv *priv = dev_get_drvdata(dev);
|
||||||
struct device *parent = dev->parent;
|
struct device *parent = dev->parent;
|
||||||
struct fwnode_handle *port;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
struct fwnode_handle *ports __free(fwnode_handle) =
|
struct fwnode_handle *ports __free(fwnode_handle) =
|
||||||
@ -418,7 +416,7 @@ static int rtl9300_mdiobus_map_ports(struct device *dev)
|
|||||||
return dev_err_probe(dev, -EINVAL, "%pfwP missing ethernet-ports\n",
|
return dev_err_probe(dev, -EINVAL, "%pfwP missing ethernet-ports\n",
|
||||||
dev_fwnode(parent));
|
dev_fwnode(parent));
|
||||||
|
|
||||||
fwnode_for_each_child_node(ports, port) {
|
fwnode_for_each_child_node_scoped(ports, port) {
|
||||||
struct device_node *mdio_dn;
|
struct device_node *mdio_dn;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u32 bus;
|
u32 bus;
|
||||||
|
|||||||
@ -1167,9 +1167,9 @@ static int mt798x_phy_calibration(struct phy_device *phydev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf = (u32 *)nvmem_cell_read(cell, &len);
|
buf = (u32 *)nvmem_cell_read(cell, &len);
|
||||||
|
nvmem_cell_put(cell);
|
||||||
if (IS_ERR(buf))
|
if (IS_ERR(buf))
|
||||||
return PTR_ERR(buf);
|
return PTR_ERR(buf);
|
||||||
nvmem_cell_put(cell);
|
|
||||||
|
|
||||||
if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
|
if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
|
||||||
phydev_err(phydev, "invalid efuse data\n");
|
phydev_err(phydev, "invalid efuse data\n");
|
||||||
|
|||||||
@ -878,7 +878,7 @@ static void __team_queue_override_enabled_check(struct team *team)
|
|||||||
static void team_queue_override_port_prio_changed(struct team *team,
|
static void team_queue_override_port_prio_changed(struct team *team,
|
||||||
struct team_port *port)
|
struct team_port *port)
|
||||||
{
|
{
|
||||||
if (!port->queue_id || team_port_enabled(port))
|
if (!port->queue_id || !team_port_enabled(port))
|
||||||
return;
|
return;
|
||||||
__team_queue_override_port_del(team, port);
|
__team_queue_override_port_del(team, port);
|
||||||
__team_queue_override_port_add(team, port);
|
__team_queue_override_port_add(team, port);
|
||||||
|
|||||||
@ -335,6 +335,11 @@ int asix_read_phy_addr(struct usbnet *dev, bool internal)
|
|||||||
offset = (internal ? 1 : 0);
|
offset = (internal ? 1 : 0);
|
||||||
ret = buf[offset];
|
ret = buf[offset];
|
||||||
|
|
||||||
|
if (ret >= PHY_MAX_ADDR) {
|
||||||
|
netdev_err(dev->net, "invalid PHY address: %d\n", ret);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
netdev_dbg(dev->net, "%s PHY address 0x%x\n",
|
netdev_dbg(dev->net, "%s PHY address 0x%x\n",
|
||||||
internal ? "internal" : "external", ret);
|
internal ? "internal" : "external", ret);
|
||||||
|
|
||||||
|
|||||||
@ -210,11 +210,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||||||
ret = asix_read_phy_addr(dev, priv->use_embdphy);
|
ret = asix_read_phy_addr(dev, priv->use_embdphy);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto free;
|
goto free;
|
||||||
if (ret >= PHY_MAX_ADDR) {
|
|
||||||
netdev_err(dev->net, "Invalid PHY address %#x\n", ret);
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto free;
|
|
||||||
}
|
|
||||||
priv->phy_addr = ret;
|
priv->phy_addr = ret;
|
||||||
|
|
||||||
ax88172a_reset_phy(dev, priv->use_embdphy);
|
ax88172a_reset_phy(dev, priv->use_embdphy);
|
||||||
|
|||||||
@ -211,6 +211,8 @@ static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg)
|
|||||||
if (res == -ENODEV)
|
if (res == -ENODEV)
|
||||||
netif_device_detach(dev->netdev);
|
netif_device_detach(dev->netdev);
|
||||||
dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res);
|
dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res);
|
||||||
|
kfree(req);
|
||||||
|
usb_free_urb(async_urb);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
|
|||||||
|
|
||||||
static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
|
static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
|
||||||
{
|
{
|
||||||
return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
|
return usbnet_write_cmd(dev, SR_WR_REG, SR_REQ_WR_REG,
|
||||||
value, reg, NULL, 0);
|
value, reg, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ static void sr_write_async(struct usbnet *dev, u8 reg, u16 length,
|
|||||||
|
|
||||||
static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
|
static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
|
||||||
{
|
{
|
||||||
usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
|
usbnet_write_cmd_async(dev, SR_WR_REG, SR_REQ_WR_REG,
|
||||||
value, reg, NULL, 0);
|
value, reg, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,6 +539,11 @@ static const struct usb_device_id products[] = {
|
|||||||
USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
|
USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
|
||||||
.driver_info = (unsigned long)&sr9700_driver_info,
|
.driver_info = (unsigned long)&sr9700_driver_info,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/* SR9700 with virtual driver CD-ROM - interface 0 is the CD-ROM device */
|
||||||
|
USB_DEVICE_INTERFACE_NUMBER(0x0fe6, 0x9702, 1),
|
||||||
|
.driver_info = (unsigned long)&sr9700_driver_info,
|
||||||
|
},
|
||||||
{}, /* END */
|
{}, /* END */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -831,7 +831,6 @@ int usbnet_stop(struct net_device *net)
|
|||||||
|
|
||||||
clear_bit(EVENT_DEV_OPEN, &dev->flags);
|
clear_bit(EVENT_DEV_OPEN, &dev->flags);
|
||||||
netif_stop_queue(net);
|
netif_stop_queue(net);
|
||||||
netdev_reset_queue(net);
|
|
||||||
|
|
||||||
netif_info(dev, ifdown, dev->net,
|
netif_info(dev, ifdown, dev->net,
|
||||||
"stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
|
"stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
|
||||||
@ -875,6 +874,8 @@ int usbnet_stop(struct net_device *net)
|
|||||||
timer_delete_sync(&dev->delay);
|
timer_delete_sync(&dev->delay);
|
||||||
cancel_work_sync(&dev->kevent);
|
cancel_work_sync(&dev->kevent);
|
||||||
|
|
||||||
|
netdev_reset_queue(net);
|
||||||
|
|
||||||
if (!pm)
|
if (!pm)
|
||||||
usb_autopm_put_interface(dev->intf);
|
usb_autopm_put_interface(dev->intf);
|
||||||
|
|
||||||
|
|||||||
@ -1597,7 +1597,7 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv)
|
|||||||
*/
|
*/
|
||||||
static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||||
{
|
{
|
||||||
unsigned int min_core, max_core, loaded_core;
|
int min_core, max_core, loaded_core;
|
||||||
struct iwl_drv *drv = context;
|
struct iwl_drv *drv = context;
|
||||||
struct iwl_fw *fw = &drv->fw;
|
struct iwl_fw *fw = &drv->fw;
|
||||||
const struct iwl_ucode_header *ucode;
|
const struct iwl_ucode_header *ucode;
|
||||||
@ -1676,7 +1676,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||||||
if (loaded_core < min_core || loaded_core > max_core) {
|
if (loaded_core < min_core || loaded_core > max_core) {
|
||||||
IWL_ERR(drv,
|
IWL_ERR(drv,
|
||||||
"Driver unable to support your firmware API. "
|
"Driver unable to support your firmware API. "
|
||||||
"Driver supports FW core %u..%u, firmware is %u.\n",
|
"Driver supports FW core %d..%d, firmware is %d.\n",
|
||||||
min_core, max_core, loaded_core);
|
min_core, max_core, loaded_core);
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,6 +121,12 @@ static int iwl_mld_ptp_gettime(struct ptp_clock_info *ptp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iwl_mld_ptp_settime(struct ptp_clock_info *ptp,
|
||||||
|
const struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static int iwl_mld_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
static int iwl_mld_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
||||||
{
|
{
|
||||||
struct iwl_mld *mld = container_of(ptp, struct iwl_mld,
|
struct iwl_mld *mld = container_of(ptp, struct iwl_mld,
|
||||||
@ -279,6 +285,7 @@ void iwl_mld_ptp_init(struct iwl_mld *mld)
|
|||||||
|
|
||||||
mld->ptp_data.ptp_clock_info.owner = THIS_MODULE;
|
mld->ptp_data.ptp_clock_info.owner = THIS_MODULE;
|
||||||
mld->ptp_data.ptp_clock_info.gettime64 = iwl_mld_ptp_gettime;
|
mld->ptp_data.ptp_clock_info.gettime64 = iwl_mld_ptp_gettime;
|
||||||
|
mld->ptp_data.ptp_clock_info.settime64 = iwl_mld_ptp_settime;
|
||||||
mld->ptp_data.ptp_clock_info.max_adj = 0x7fffffff;
|
mld->ptp_data.ptp_clock_info.max_adj = 0x7fffffff;
|
||||||
mld->ptp_data.ptp_clock_info.adjtime = iwl_mld_ptp_adjtime;
|
mld->ptp_data.ptp_clock_info.adjtime = iwl_mld_ptp_adjtime;
|
||||||
mld->ptp_data.ptp_clock_info.adjfine = iwl_mld_ptp_adjfine;
|
mld->ptp_data.ptp_clock_info.adjfine = iwl_mld_ptp_adjfine;
|
||||||
|
|||||||
@ -220,6 +220,12 @@ static int iwl_mvm_ptp_gettime(struct ptp_clock_info *ptp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iwl_mvm_ptp_settime(struct ptp_clock_info *ptp,
|
||||||
|
const struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static int iwl_mvm_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
static int iwl_mvm_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
||||||
{
|
{
|
||||||
struct iwl_mvm *mvm = container_of(ptp, struct iwl_mvm,
|
struct iwl_mvm *mvm = container_of(ptp, struct iwl_mvm,
|
||||||
@ -281,6 +287,7 @@ void iwl_mvm_ptp_init(struct iwl_mvm *mvm)
|
|||||||
mvm->ptp_data.ptp_clock_info.adjfine = iwl_mvm_ptp_adjfine;
|
mvm->ptp_data.ptp_clock_info.adjfine = iwl_mvm_ptp_adjfine;
|
||||||
mvm->ptp_data.ptp_clock_info.adjtime = iwl_mvm_ptp_adjtime;
|
mvm->ptp_data.ptp_clock_info.adjtime = iwl_mvm_ptp_adjtime;
|
||||||
mvm->ptp_data.ptp_clock_info.gettime64 = iwl_mvm_ptp_gettime;
|
mvm->ptp_data.ptp_clock_info.gettime64 = iwl_mvm_ptp_gettime;
|
||||||
|
mvm->ptp_data.ptp_clock_info.settime64 = iwl_mvm_ptp_settime;
|
||||||
mvm->ptp_data.scaled_freq = SCALE_FACTOR;
|
mvm->ptp_data.scaled_freq = SCALE_FACTOR;
|
||||||
|
|
||||||
/* Give a short 'friendly name' to identify the PHC clock */
|
/* Give a short 'friendly name' to identify the PHC clock */
|
||||||
|
|||||||
@ -511,7 +511,8 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
|
|||||||
if (sta) {
|
if (sta) {
|
||||||
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
|
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
|
||||||
tid = ieee80211_get_tid(hdr);
|
tid = ieee80211_get_tid(hdr);
|
||||||
agg_state = sta_entry->tids[tid].agg.agg_state;
|
if (tid < MAX_TID_COUNT)
|
||||||
|
agg_state = sta_entry->tids[tid].agg.agg_state;
|
||||||
ampdu_density = sta->deflink.ht_cap.ampdu_density;
|
ampdu_density = sta->deflink.ht_cap.ampdu_density;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -144,8 +144,10 @@ static u32 rtw_sdio_to_io_address(struct rtw_dev *rtwdev, u32 addr,
|
|||||||
|
|
||||||
static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr)
|
static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr)
|
||||||
{
|
{
|
||||||
|
bool might_indirect_under_power_off = rtwdev->chip->id == RTW_CHIP_TYPE_8822C;
|
||||||
|
|
||||||
if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags) &&
|
if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags) &&
|
||||||
!rtw_sdio_is_bus_addr(addr))
|
!rtw_sdio_is_bus_addr(addr) && might_indirect_under_power_off)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !rtw_sdio_is_sdio30_supported(rtwdev) ||
|
return !rtw_sdio_is_sdio30_supported(rtwdev) ||
|
||||||
|
|||||||
@ -965,8 +965,7 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
|
|||||||
struct sk_buff *rx_skb;
|
struct sk_buff *rx_skb;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_UNBOUND,
|
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0);
|
||||||
0);
|
|
||||||
if (!rtwusb->rxwq) {
|
if (!rtwusb->rxwq) {
|
||||||
rtw_err(rtwdev, "failed to create RX work queue\n");
|
rtw_err(rtwdev, "failed to create RX work queue\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
@ -207,6 +207,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
|
total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
|
||||||
|
|
||||||
if (total_blocks <= wl->tx_blocks_available) {
|
if (total_blocks <= wl->tx_blocks_available) {
|
||||||
|
if (skb_headroom(skb) < (total_len - skb->len) &&
|
||||||
|
pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) {
|
||||||
|
wl1271_free_tx_id(wl, id);
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
desc = skb_push(skb, total_len - skb->len);
|
desc = skb_push(skb, total_len - skb->len);
|
||||||
|
|
||||||
wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
|
wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
|
||||||
|
|||||||
@ -302,6 +302,7 @@ struct dsa_port {
|
|||||||
struct devlink_port devlink_port;
|
struct devlink_port devlink_port;
|
||||||
struct phylink *pl;
|
struct phylink *pl;
|
||||||
struct phylink_config pl_config;
|
struct phylink_config pl_config;
|
||||||
|
netdevice_tracker conduit_tracker;
|
||||||
struct dsa_lag *lag;
|
struct dsa_lag *lag;
|
||||||
struct net_device *hsr_dev;
|
struct net_device *hsr_dev;
|
||||||
|
|
||||||
|
|||||||
@ -849,6 +849,12 @@ static u32 get_supported_settings(struct hci_dev *hdev)
|
|||||||
if (cis_peripheral_capable(hdev))
|
if (cis_peripheral_capable(hdev))
|
||||||
settings |= MGMT_SETTING_CIS_PERIPHERAL;
|
settings |= MGMT_SETTING_CIS_PERIPHERAL;
|
||||||
|
|
||||||
|
if (bis_capable(hdev))
|
||||||
|
settings |= MGMT_SETTING_ISO_BROADCASTER;
|
||||||
|
|
||||||
|
if (sync_recv_capable(hdev))
|
||||||
|
settings |= MGMT_SETTING_ISO_SYNC_RECEIVER;
|
||||||
|
|
||||||
if (ll_privacy_capable(hdev))
|
if (ll_privacy_capable(hdev))
|
||||||
settings |= MGMT_SETTING_LL_PRIVACY;
|
settings |= MGMT_SETTING_LL_PRIVACY;
|
||||||
|
|
||||||
|
|||||||
@ -247,6 +247,7 @@ struct net_bridge_vlan {
|
|||||||
* struct net_bridge_vlan_group
|
* struct net_bridge_vlan_group
|
||||||
*
|
*
|
||||||
* @vlan_hash: VLAN entry rhashtable
|
* @vlan_hash: VLAN entry rhashtable
|
||||||
|
* @tunnel_hash: Hash table to map from tunnel key ID (e.g. VXLAN VNI) to VLAN
|
||||||
* @vlan_list: sorted VLAN entry list
|
* @vlan_list: sorted VLAN entry list
|
||||||
* @num_vlans: number of total VLAN entries
|
* @num_vlans: number of total VLAN entries
|
||||||
* @pvid: PVID VLAN id
|
* @pvid: PVID VLAN id
|
||||||
|
|||||||
@ -4241,9 +4241,11 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
llist_for_each_entry_safe(skb, next, ll_list, ll_node) {
|
llist_for_each_entry_safe(skb, next, ll_list, ll_node) {
|
||||||
prefetch(next);
|
if (next) {
|
||||||
prefetch(&next->priority);
|
prefetch(next);
|
||||||
skb_mark_not_on_list(skb);
|
prefetch(&next->priority);
|
||||||
|
skb_mark_not_on_list(skb);
|
||||||
|
}
|
||||||
rc = dev_qdisc_enqueue(skb, q, &to_free, txq);
|
rc = dev_qdisc_enqueue(skb, q, &to_free, txq);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -367,16 +367,10 @@ static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
|
|||||||
|
|
||||||
struct net_device *dsa_tree_find_first_conduit(struct dsa_switch_tree *dst)
|
struct net_device *dsa_tree_find_first_conduit(struct dsa_switch_tree *dst)
|
||||||
{
|
{
|
||||||
struct device_node *ethernet;
|
|
||||||
struct net_device *conduit;
|
|
||||||
struct dsa_port *cpu_dp;
|
struct dsa_port *cpu_dp;
|
||||||
|
|
||||||
cpu_dp = dsa_tree_find_first_cpu(dst);
|
cpu_dp = dsa_tree_find_first_cpu(dst);
|
||||||
ethernet = of_parse_phandle(cpu_dp->dn, "ethernet", 0);
|
return cpu_dp->conduit;
|
||||||
conduit = of_find_net_device_by_node(ethernet);
|
|
||||||
of_node_put(ethernet);
|
|
||||||
|
|
||||||
return conduit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign the default CPU port (the first one in the tree) to all ports of the
|
/* Assign the default CPU port (the first one in the tree) to all ports of the
|
||||||
@ -1253,14 +1247,25 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
|
|||||||
if (ethernet) {
|
if (ethernet) {
|
||||||
struct net_device *conduit;
|
struct net_device *conduit;
|
||||||
const char *user_protocol;
|
const char *user_protocol;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
conduit = of_find_net_device_by_node(ethernet);
|
conduit = of_find_net_device_by_node(ethernet);
|
||||||
of_node_put(ethernet);
|
of_node_put(ethernet);
|
||||||
if (!conduit)
|
if (!conduit) {
|
||||||
|
rtnl_unlock();
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_hold(conduit, &dp->conduit_tracker, GFP_KERNEL);
|
||||||
|
put_device(&conduit->dev);
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
user_protocol = of_get_property(dn, "dsa-tag-protocol", NULL);
|
user_protocol = of_get_property(dn, "dsa-tag-protocol", NULL);
|
||||||
return dsa_port_parse_cpu(dp, conduit, user_protocol);
|
err = dsa_port_parse_cpu(dp, conduit, user_protocol);
|
||||||
|
if (err)
|
||||||
|
netdev_put(conduit, &dp->conduit_tracker);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link)
|
if (link)
|
||||||
@ -1393,37 +1398,30 @@ static struct device *dev_find_class(struct device *parent, char *class)
|
|||||||
return device_find_child(parent, class, dev_is_class);
|
return device_find_child(parent, class, dev_is_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_device *dsa_dev_to_net_device(struct device *dev)
|
|
||||||
{
|
|
||||||
struct device *d;
|
|
||||||
|
|
||||||
d = dev_find_class(dev, "net");
|
|
||||||
if (d != NULL) {
|
|
||||||
struct net_device *nd;
|
|
||||||
|
|
||||||
nd = to_net_dev(d);
|
|
||||||
dev_hold(nd);
|
|
||||||
put_device(d);
|
|
||||||
|
|
||||||
return nd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsa_port_parse(struct dsa_port *dp, const char *name,
|
static int dsa_port_parse(struct dsa_port *dp, const char *name,
|
||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
if (!strcmp(name, "cpu")) {
|
if (!strcmp(name, "cpu")) {
|
||||||
struct net_device *conduit;
|
struct net_device *conduit;
|
||||||
|
struct device *d;
|
||||||
|
int err;
|
||||||
|
|
||||||
conduit = dsa_dev_to_net_device(dev);
|
rtnl_lock();
|
||||||
if (!conduit)
|
d = dev_find_class(dev, "net");
|
||||||
|
if (!d) {
|
||||||
|
rtnl_unlock();
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
dev_put(conduit);
|
conduit = to_net_dev(d);
|
||||||
|
netdev_hold(conduit, &dp->conduit_tracker, GFP_KERNEL);
|
||||||
|
put_device(d);
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
return dsa_port_parse_cpu(dp, conduit, NULL);
|
err = dsa_port_parse_cpu(dp, conduit, NULL);
|
||||||
|
if (err)
|
||||||
|
netdev_put(conduit, &dp->conduit_tracker);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(name, "dsa"))
|
if (!strcmp(name, "dsa"))
|
||||||
@ -1491,6 +1489,9 @@ static void dsa_switch_release_ports(struct dsa_switch *ds)
|
|||||||
struct dsa_vlan *v, *n;
|
struct dsa_vlan *v, *n;
|
||||||
|
|
||||||
dsa_switch_for_each_port_safe(dp, next, ds) {
|
dsa_switch_for_each_port_safe(dp, next, ds) {
|
||||||
|
if (dsa_port_is_cpu(dp) && dp->conduit)
|
||||||
|
netdev_put(dp->conduit, &dp->conduit_tracker);
|
||||||
|
|
||||||
/* These are either entries that upper layers lost track of
|
/* These are either entries that upper layers lost track of
|
||||||
* (probably due to bugs), or installed through interfaces
|
* (probably due to bugs), or installed through interfaces
|
||||||
* where one does not necessarily have to remove them, like
|
* where one does not necessarily have to remove them, like
|
||||||
@ -1635,8 +1636,10 @@ void dsa_switch_shutdown(struct dsa_switch *ds)
|
|||||||
/* Disconnect from further netdevice notifiers on the conduit,
|
/* Disconnect from further netdevice notifiers on the conduit,
|
||||||
* since netdev_uses_dsa() will now return false.
|
* since netdev_uses_dsa() will now return false.
|
||||||
*/
|
*/
|
||||||
dsa_switch_for_each_cpu_port(dp, ds)
|
dsa_switch_for_each_cpu_port(dp, ds) {
|
||||||
dp->conduit->dsa_ptr = NULL;
|
dp->conduit->dsa_ptr = NULL;
|
||||||
|
netdev_put(dp->conduit, &dp->conduit_tracker);
|
||||||
|
}
|
||||||
|
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
out:
|
out:
|
||||||
|
|||||||
@ -126,7 +126,8 @@ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_complete:
|
out_complete:
|
||||||
handshake_complete(req, -EIO, NULL);
|
if (req)
|
||||||
|
handshake_complete(req, -EIO, NULL);
|
||||||
out_status:
|
out_status:
|
||||||
trace_handshake_cmd_accept_err(net, req, NULL, err);
|
trace_handshake_cmd_accept_err(net, req, NULL, err);
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@ -2167,8 +2167,8 @@ void fib_select_multipath(struct fib_result *res, int hash,
|
|||||||
{
|
{
|
||||||
struct fib_info *fi = res->fi;
|
struct fib_info *fi = res->fi;
|
||||||
struct net *net = fi->fib_net;
|
struct net *net = fi->fib_net;
|
||||||
bool found = false;
|
|
||||||
bool use_neigh;
|
bool use_neigh;
|
||||||
|
int score = -1;
|
||||||
__be32 saddr;
|
__be32 saddr;
|
||||||
|
|
||||||
if (unlikely(res->fi->nh)) {
|
if (unlikely(res->fi->nh)) {
|
||||||
@ -2180,7 +2180,7 @@ void fib_select_multipath(struct fib_result *res, int hash,
|
|||||||
saddr = fl4 ? fl4->saddr : 0;
|
saddr = fl4 ? fl4->saddr : 0;
|
||||||
|
|
||||||
change_nexthops(fi) {
|
change_nexthops(fi) {
|
||||||
int nh_upper_bound;
|
int nh_upper_bound, nh_score = 0;
|
||||||
|
|
||||||
/* Nexthops without a carrier are assigned an upper bound of
|
/* Nexthops without a carrier are assigned an upper bound of
|
||||||
* minus one when "ignore_routes_with_linkdown" is set.
|
* minus one when "ignore_routes_with_linkdown" is set.
|
||||||
@ -2190,24 +2190,18 @@ void fib_select_multipath(struct fib_result *res, int hash,
|
|||||||
(use_neigh && !fib_good_nh(nexthop_nh)))
|
(use_neigh && !fib_good_nh(nexthop_nh)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!found) {
|
if (saddr && nexthop_nh->nh_saddr == saddr)
|
||||||
|
nh_score += 2;
|
||||||
|
if (hash <= nh_upper_bound)
|
||||||
|
nh_score++;
|
||||||
|
if (score < nh_score) {
|
||||||
res->nh_sel = nhsel;
|
res->nh_sel = nhsel;
|
||||||
res->nhc = &nexthop_nh->nh_common;
|
res->nhc = &nexthop_nh->nh_common;
|
||||||
found = !saddr || nexthop_nh->nh_saddr == saddr;
|
if (nh_score == 3 || (!saddr && nh_score == 1))
|
||||||
|
return;
|
||||||
|
score = nh_score;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash > nh_upper_bound)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!saddr || nexthop_nh->nh_saddr == saddr) {
|
|
||||||
res->nh_sel = nhsel;
|
|
||||||
res->nhc = &nexthop_nh->nh_common;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
return;
|
|
||||||
|
|
||||||
} endfor_nexthops(fi);
|
} endfor_nexthops(fi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2053,10 +2053,11 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not flush error routes if network namespace is
|
/* When not flushing the entire table, skip error
|
||||||
* not being dismantled
|
* routes that are not marked for deletion.
|
||||||
*/
|
*/
|
||||||
if (!flush_all && fib_props[fa->fa_type].error) {
|
if (!flush_all && fib_props[fa->fa_type].error &&
|
||||||
|
!(fi->fib_flags & RTNH_F_DEAD)) {
|
||||||
slen = fa->fa_slen;
|
slen = fa->fa_slen;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -330,6 +330,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
|||||||
if (!tun_dst)
|
if (!tun_dst)
|
||||||
return PACKET_REJECT;
|
return PACKET_REJECT;
|
||||||
|
|
||||||
|
/* MUST set options_len before referencing options */
|
||||||
|
info = &tun_dst->u.tun_info;
|
||||||
|
info->options_len = sizeof(*md);
|
||||||
|
|
||||||
/* skb can be uncloned in __iptunnel_pull_header, so
|
/* skb can be uncloned in __iptunnel_pull_header, so
|
||||||
* old pkt_md is no longer valid and we need to reset
|
* old pkt_md is no longer valid and we need to reset
|
||||||
* it
|
* it
|
||||||
@ -344,10 +348,8 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
|||||||
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
|
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
|
||||||
ERSPAN_V2_MDSIZE);
|
ERSPAN_V2_MDSIZE);
|
||||||
|
|
||||||
info = &tun_dst->u.tun_info;
|
|
||||||
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
|
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
|
||||||
info->key.tun_flags);
|
info->key.tun_flags);
|
||||||
info->options_len = sizeof(*md);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
|
|||||||
@ -1342,7 +1342,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
|
|||||||
/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
|
/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
|
||||||
pad = ((new_end & 4) + (end & 7)) & 7;
|
pad = ((new_end & 4) + (end & 7)) & 7;
|
||||||
len_delta = new_end - (int)end + pad;
|
len_delta = new_end - (int)end + pad;
|
||||||
ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
|
ret_val = skb_cow(skb,
|
||||||
|
skb_headroom(skb) + (len_delta > 0 ? len_delta : 0));
|
||||||
if (ret_val < 0)
|
if (ret_val < 0)
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
|
||||||
|
|||||||
@ -535,6 +535,10 @@ static int ip6erspan_rcv(struct sk_buff *skb,
|
|||||||
if (!tun_dst)
|
if (!tun_dst)
|
||||||
return PACKET_REJECT;
|
return PACKET_REJECT;
|
||||||
|
|
||||||
|
/* MUST set options_len before referencing options */
|
||||||
|
info = &tun_dst->u.tun_info;
|
||||||
|
info->options_len = sizeof(*md);
|
||||||
|
|
||||||
/* skb can be uncloned in __iptunnel_pull_header, so
|
/* skb can be uncloned in __iptunnel_pull_header, so
|
||||||
* old pkt_md is no longer valid and we need to reset
|
* old pkt_md is no longer valid and we need to reset
|
||||||
* it
|
* it
|
||||||
@ -543,7 +547,6 @@ static int ip6erspan_rcv(struct sk_buff *skb,
|
|||||||
skb_network_header_len(skb);
|
skb_network_header_len(skb);
|
||||||
pkt_md = (struct erspan_metadata *)(gh + gre_hdr_len +
|
pkt_md = (struct erspan_metadata *)(gh + gre_hdr_len +
|
||||||
sizeof(*ershdr));
|
sizeof(*ershdr));
|
||||||
info = &tun_dst->u.tun_info;
|
|
||||||
md = ip_tunnel_info_opts(info);
|
md = ip_tunnel_info_opts(info);
|
||||||
md->version = ver;
|
md->version = ver;
|
||||||
md2 = &md->u.md2;
|
md2 = &md->u.md2;
|
||||||
@ -551,7 +554,6 @@ static int ip6erspan_rcv(struct sk_buff *skb,
|
|||||||
ERSPAN_V2_MDSIZE);
|
ERSPAN_V2_MDSIZE);
|
||||||
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
|
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
|
||||||
info->key.tun_flags);
|
info->key.tun_flags);
|
||||||
info->options_len = sizeof(*md);
|
|
||||||
|
|
||||||
ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
|
ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
|
||||||
|
|
||||||
@ -1366,9 +1368,16 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
|
|||||||
{
|
{
|
||||||
struct ip6_tnl *t = netdev_priv(dev);
|
struct ip6_tnl *t = netdev_priv(dev);
|
||||||
struct ipv6hdr *ipv6h;
|
struct ipv6hdr *ipv6h;
|
||||||
|
int needed;
|
||||||
__be16 *p;
|
__be16 *p;
|
||||||
|
|
||||||
ipv6h = skb_push(skb, t->hlen + sizeof(*ipv6h));
|
needed = t->hlen + sizeof(*ipv6h);
|
||||||
|
if (skb_headroom(skb) < needed &&
|
||||||
|
pskb_expand_head(skb, HH_DATA_ALIGN(needed - skb_headroom(skb)),
|
||||||
|
0, GFP_ATOMIC))
|
||||||
|
return -needed;
|
||||||
|
|
||||||
|
ipv6h = skb_push(skb, needed);
|
||||||
ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb,
|
ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb,
|
||||||
t->fl.u.ip6.flowlabel,
|
t->fl.u.ip6.flowlabel,
|
||||||
true, &t->fl.u.ip6));
|
true, &t->fl.u.ip6));
|
||||||
|
|||||||
@ -1470,7 +1470,18 @@ static struct rt6_info *rt6_make_pcpu_route(struct net *net,
|
|||||||
|
|
||||||
p = this_cpu_ptr(res->nh->rt6i_pcpu);
|
p = this_cpu_ptr(res->nh->rt6i_pcpu);
|
||||||
prev = cmpxchg(p, NULL, pcpu_rt);
|
prev = cmpxchg(p, NULL, pcpu_rt);
|
||||||
BUG_ON(prev);
|
if (unlikely(prev)) {
|
||||||
|
/*
|
||||||
|
* Another task on this CPU already installed a pcpu_rt.
|
||||||
|
* This can happen on PREEMPT_RT where preemption is possible.
|
||||||
|
* Free our allocation and return the existing one.
|
||||||
|
*/
|
||||||
|
WARN_ON_ONCE(!IS_ENABLED(CONFIG_PREEMPT_RT));
|
||||||
|
|
||||||
|
dst_dev_put(&pcpu_rt->dst);
|
||||||
|
dst_release(&pcpu_rt->dst);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
if (res->f6i->fib6_destroying) {
|
if (res->f6i->fib6_destroying) {
|
||||||
struct fib6_info *from;
|
struct fib6_info *from;
|
||||||
|
|||||||
@ -1345,7 +1345,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
size = sizeof(*new) + new_head_len + new_tail_len;
|
size = sizeof(*new) + new_head_len + new_tail_len;
|
||||||
|
|
||||||
/* new or old multiple BSSID elements? */
|
|
||||||
if (params->mbssid_ies) {
|
if (params->mbssid_ies) {
|
||||||
mbssid = params->mbssid_ies;
|
mbssid = params->mbssid_ies;
|
||||||
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
|
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
|
||||||
@ -1355,15 +1354,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
|
|||||||
}
|
}
|
||||||
size += ieee80211_get_mbssid_beacon_len(mbssid, rnr,
|
size += ieee80211_get_mbssid_beacon_len(mbssid, rnr,
|
||||||
mbssid->cnt);
|
mbssid->cnt);
|
||||||
} else if (old && old->mbssid_ies) {
|
|
||||||
mbssid = old->mbssid_ies;
|
|
||||||
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
|
|
||||||
if (old && old->rnr_ies) {
|
|
||||||
rnr = old->rnr_ies;
|
|
||||||
size += struct_size(new->rnr_ies, elem, rnr->cnt);
|
|
||||||
}
|
|
||||||
size += ieee80211_get_mbssid_beacon_len(mbssid, rnr,
|
|
||||||
mbssid->cnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new = kzalloc(size, GFP_KERNEL);
|
new = kzalloc(size, GFP_KERNEL);
|
||||||
|
|||||||
@ -1251,7 +1251,7 @@ configure_monitor:
|
|||||||
if (!creator_sdata) {
|
if (!creator_sdata) {
|
||||||
struct ieee80211_sub_if_data *other;
|
struct ieee80211_sub_if_data *other;
|
||||||
|
|
||||||
list_for_each_entry(other, &local->mon_list, list) {
|
list_for_each_entry_rcu(other, &local->mon_list, u.mntr.list) {
|
||||||
if (!other->vif.bss_conf.mu_mimo_owner)
|
if (!other->vif.bss_conf.mu_mimo_owner)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@ -1126,7 +1126,10 @@ again:
|
|||||||
|
|
||||||
while (!ieee80211_chandef_usable(sdata, &chanreq->oper,
|
while (!ieee80211_chandef_usable(sdata, &chanreq->oper,
|
||||||
IEEE80211_CHAN_DISABLED)) {
|
IEEE80211_CHAN_DISABLED)) {
|
||||||
if (WARN_ON(chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT)) {
|
if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT) {
|
||||||
|
link_id_info(sdata, link_id,
|
||||||
|
"unusable channel (%d MHz) for connection\n",
|
||||||
|
chanreq->oper.chan->center_freq);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto free;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,9 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
int band;
|
int band;
|
||||||
|
|
||||||
|
if (!ifocb->joined)
|
||||||
|
return;
|
||||||
|
|
||||||
/* XXX: Consider removing the least recently used entry and
|
/* XXX: Consider removing the least recently used entry and
|
||||||
* allow new one to be added.
|
* allow new one to be added.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -3511,6 +3511,11 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
|
|||||||
rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
|
rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
|
||||||
return RX_DROP_U_RUNT_ACTION;
|
return RX_DROP_U_RUNT_ACTION;
|
||||||
|
|
||||||
|
/* Drop non-broadcast Beacon frames */
|
||||||
|
if (ieee80211_is_beacon(mgmt->frame_control) &&
|
||||||
|
!is_broadcast_ether_addr(mgmt->da))
|
||||||
|
return RX_DROP;
|
||||||
|
|
||||||
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
|
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
|
||||||
ieee80211_is_beacon(mgmt->frame_control) &&
|
ieee80211_is_beacon(mgmt->frame_control) &&
|
||||||
!(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
|
!(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
|
||||||
|
|||||||
@ -408,6 +408,16 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
|
|||||||
*/
|
*/
|
||||||
subflow->snd_isn = TCP_SKB_CB(skb)->end_seq;
|
subflow->snd_isn = TCP_SKB_CB(skb)->end_seq;
|
||||||
if (subflow->request_mptcp) {
|
if (subflow->request_mptcp) {
|
||||||
|
if (unlikely(subflow_simultaneous_connect(sk))) {
|
||||||
|
WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK));
|
||||||
|
|
||||||
|
/* Ensure mptcp_finish_connect() will not process the
|
||||||
|
* MPC handshake.
|
||||||
|
*/
|
||||||
|
subflow->request_mptcp = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
opts->suboptions = OPTION_MPTCP_MPC_SYN;
|
opts->suboptions = OPTION_MPTCP_MPC_SYN;
|
||||||
opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
|
opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
|
||||||
opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));
|
opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));
|
||||||
|
|||||||
@ -2467,10 +2467,10 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
|
|||||||
*/
|
*/
|
||||||
static void __mptcp_subflow_disconnect(struct sock *ssk,
|
static void __mptcp_subflow_disconnect(struct sock *ssk,
|
||||||
struct mptcp_subflow_context *subflow,
|
struct mptcp_subflow_context *subflow,
|
||||||
unsigned int flags)
|
bool fastclosing)
|
||||||
{
|
{
|
||||||
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
|
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
|
||||||
subflow->send_fastclose) {
|
fastclosing) {
|
||||||
/* The MPTCP code never wait on the subflow sockets, TCP-level
|
/* The MPTCP code never wait on the subflow sockets, TCP-level
|
||||||
* disconnect should never fail
|
* disconnect should never fail
|
||||||
*/
|
*/
|
||||||
@ -2538,7 +2538,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
|||||||
|
|
||||||
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
|
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
|
||||||
if (!dispose_it) {
|
if (!dispose_it) {
|
||||||
__mptcp_subflow_disconnect(ssk, subflow, flags);
|
__mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing);
|
||||||
release_sock(ssk);
|
release_sock(ssk);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
@ -2884,6 +2884,7 @@ static void mptcp_do_fastclose(struct sock *sk)
|
|||||||
|
|
||||||
mptcp_set_state(sk, TCP_CLOSE);
|
mptcp_set_state(sk, TCP_CLOSE);
|
||||||
mptcp_backlog_purge(sk);
|
mptcp_backlog_purge(sk);
|
||||||
|
msk->fastclosing = 1;
|
||||||
|
|
||||||
/* Explicitly send the fastclose reset as need */
|
/* Explicitly send the fastclose reset as need */
|
||||||
if (__mptcp_check_fallback(msk))
|
if (__mptcp_check_fallback(msk))
|
||||||
@ -3418,6 +3419,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
|
|||||||
msk->bytes_sent = 0;
|
msk->bytes_sent = 0;
|
||||||
msk->bytes_retrans = 0;
|
msk->bytes_retrans = 0;
|
||||||
msk->rcvspace_init = 0;
|
msk->rcvspace_init = 0;
|
||||||
|
msk->fastclosing = 0;
|
||||||
|
|
||||||
/* for fallback's sake */
|
/* for fallback's sake */
|
||||||
WRITE_ONCE(msk->ack_seq, 0);
|
WRITE_ONCE(msk->ack_seq, 0);
|
||||||
|
|||||||
@ -320,7 +320,8 @@ struct mptcp_sock {
|
|||||||
fastopening:1,
|
fastopening:1,
|
||||||
in_accept_queue:1,
|
in_accept_queue:1,
|
||||||
free_first:1,
|
free_first:1,
|
||||||
rcvspace_init:1;
|
rcvspace_init:1,
|
||||||
|
fastclosing:1;
|
||||||
u32 notsent_lowat;
|
u32 notsent_lowat;
|
||||||
int keepalive_cnt;
|
int keepalive_cnt;
|
||||||
int keepalive_idle;
|
int keepalive_idle;
|
||||||
@ -1337,10 +1338,8 @@ static inline bool subflow_simultaneous_connect(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
||||||
|
|
||||||
return (1 << sk->sk_state) &
|
/* Note that the sk state implies !subflow->conn_finished. */
|
||||||
(TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING) &&
|
return sk->sk_state == TCP_SYN_RECV && is_active_ssk(subflow);
|
||||||
is_active_ssk(subflow) &&
|
|
||||||
!subflow->conn_finished;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SYN_COOKIES
|
#ifdef CONFIG_SYN_COOKIES
|
||||||
|
|||||||
@ -1878,12 +1878,6 @@ static void subflow_state_change(struct sock *sk)
|
|||||||
|
|
||||||
__subflow_state_change(sk);
|
__subflow_state_change(sk);
|
||||||
|
|
||||||
if (subflow_simultaneous_connect(sk)) {
|
|
||||||
WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK));
|
|
||||||
subflow->conn_finished = 1;
|
|
||||||
mptcp_propagate_state(parent, sk, subflow, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* as recvmsg() does not acquire the subflow socket for ssk selection
|
/* as recvmsg() does not acquire the subflow socket for ssk selection
|
||||||
* a fin packet carrying a DSS can be unnoticed if we don't trigger
|
* a fin packet carrying a DSS can be unnoticed if we don't trigger
|
||||||
* the data available machinery here.
|
* the data available machinery here.
|
||||||
|
|||||||
@ -1154,6 +1154,7 @@ EXPORT_SYMBOL(nfc_register_device);
|
|||||||
void nfc_unregister_device(struct nfc_dev *dev)
|
void nfc_unregister_device(struct nfc_dev *dev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
struct rfkill *rfk = NULL;
|
||||||
|
|
||||||
pr_debug("dev_name=%s\n", dev_name(&dev->dev));
|
pr_debug("dev_name=%s\n", dev_name(&dev->dev));
|
||||||
|
|
||||||
@ -1164,13 +1165,17 @@ void nfc_unregister_device(struct nfc_dev *dev)
|
|||||||
|
|
||||||
device_lock(&dev->dev);
|
device_lock(&dev->dev);
|
||||||
if (dev->rfkill) {
|
if (dev->rfkill) {
|
||||||
rfkill_unregister(dev->rfkill);
|
rfk = dev->rfkill;
|
||||||
rfkill_destroy(dev->rfkill);
|
|
||||||
dev->rfkill = NULL;
|
dev->rfkill = NULL;
|
||||||
}
|
}
|
||||||
dev->shutting_down = true;
|
dev->shutting_down = true;
|
||||||
device_unlock(&dev->dev);
|
device_unlock(&dev->dev);
|
||||||
|
|
||||||
|
if (rfk) {
|
||||||
|
rfkill_unregister(rfk);
|
||||||
|
rfkill_destroy(rfk);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->ops->check_presence) {
|
if (dev->ops->check_presence) {
|
||||||
timer_delete_sync(&dev->check_pres_timer);
|
timer_delete_sync(&dev->check_pres_timer);
|
||||||
cancel_work_sync(&dev->check_pres_work);
|
cancel_work_sync(&dev->check_pres_work);
|
||||||
|
|||||||
@ -160,10 +160,19 @@ void ovs_netdev_detach_dev(struct vport *vport)
|
|||||||
|
|
||||||
static void netdev_destroy(struct vport *vport)
|
static void netdev_destroy(struct vport *vport)
|
||||||
{
|
{
|
||||||
rtnl_lock();
|
/* When called from ovs_db_notify_wq() after a dp_device_event(), the
|
||||||
if (netif_is_ovs_port(vport->dev))
|
* port has already been detached, so we can avoid taking the RTNL by
|
||||||
ovs_netdev_detach_dev(vport);
|
* checking this first.
|
||||||
rtnl_unlock();
|
*/
|
||||||
|
if (netif_is_ovs_port(vport->dev)) {
|
||||||
|
rtnl_lock();
|
||||||
|
/* Check again while holding the lock to ensure we don't race
|
||||||
|
* with the netdev notifier and detach twice.
|
||||||
|
*/
|
||||||
|
if (netif_is_ovs_port(vport->dev))
|
||||||
|
ovs_netdev_detach_dev(vport);
|
||||||
|
rtnl_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
call_rcu(&vport->rcu, vport_netdev_free);
|
call_rcu(&vport->rcu, vport_netdev_free);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,7 +205,7 @@ start:
|
|||||||
spin_unlock_bh(&rose_list_lock);
|
spin_unlock_bh(&rose_list_lock);
|
||||||
|
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
sk = array[cnt];
|
sk = array[i];
|
||||||
rose = rose_sk(sk);
|
rose = rose_sk(sk);
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
spin_lock_bh(&rose_list_lock);
|
spin_lock_bh(&rose_list_lock);
|
||||||
|
|||||||
@ -2904,6 +2904,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
|||||||
unsigned int last_len;
|
unsigned int last_len;
|
||||||
struct unix_sock *u;
|
struct unix_sock *u;
|
||||||
int copied = 0;
|
int copied = 0;
|
||||||
|
bool do_cmsg;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
long timeo;
|
long timeo;
|
||||||
int target;
|
int target;
|
||||||
@ -2929,6 +2930,9 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
|||||||
|
|
||||||
u = unix_sk(sk);
|
u = unix_sk(sk);
|
||||||
|
|
||||||
|
do_cmsg = READ_ONCE(u->recvmsg_inq);
|
||||||
|
if (do_cmsg)
|
||||||
|
msg->msg_get_inq = 1;
|
||||||
redo:
|
redo:
|
||||||
/* Lock the socket to prevent queue disordering
|
/* Lock the socket to prevent queue disordering
|
||||||
* while sleeps in memcpy_tomsg
|
* while sleeps in memcpy_tomsg
|
||||||
@ -3088,10 +3092,11 @@ unlock:
|
|||||||
if (msg) {
|
if (msg) {
|
||||||
scm_recv_unix(sock, msg, &scm, flags);
|
scm_recv_unix(sock, msg, &scm, flags);
|
||||||
|
|
||||||
if (READ_ONCE(u->recvmsg_inq) || msg->msg_get_inq) {
|
if (msg->msg_get_inq && (copied ?: err) >= 0) {
|
||||||
msg->msg_inq = READ_ONCE(u->inq_len);
|
msg->msg_inq = READ_ONCE(u->inq_len);
|
||||||
put_cmsg(msg, SOL_SOCKET, SCM_INQ,
|
if (do_cmsg)
|
||||||
sizeof(msg->msg_inq), &msg->msg_inq);
|
put_cmsg(msg, SOL_SOCKET, SCM_INQ,
|
||||||
|
sizeof(msg->msg_inq), &msg->msg_inq);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scm_destroy(&scm);
|
scm_destroy(&scm);
|
||||||
|
|||||||
@ -910,7 +910,7 @@ void __cfg80211_connect_result(struct net_device *dev,
|
|||||||
|
|
||||||
ssid_len = min(ssid->datalen, IEEE80211_MAX_SSID_LEN);
|
ssid_len = min(ssid->datalen, IEEE80211_MAX_SSID_LEN);
|
||||||
memcpy(wdev->u.client.ssid, ssid->data, ssid_len);
|
memcpy(wdev->u.client.ssid, ssid->data, ssid_len);
|
||||||
wdev->u.client.ssid_len = ssid->datalen;
|
wdev->u.client.ssid_len = ssid_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|||||||
@ -573,8 +573,9 @@ def psp_ip_ver_test_builder(name, test_func, psp_ver, ipver):
|
|||||||
"""Build test cases for each combo of PSP version and IP version"""
|
"""Build test cases for each combo of PSP version and IP version"""
|
||||||
def test_case(cfg):
|
def test_case(cfg):
|
||||||
cfg.require_ipver(ipver)
|
cfg.require_ipver(ipver)
|
||||||
test_case.__name__ = f"{name}_v{psp_ver}_ip{ipver}"
|
|
||||||
test_func(cfg, psp_ver, ipver)
|
test_func(cfg, psp_ver, ipver)
|
||||||
|
|
||||||
|
test_case.__name__ = f"{name}_v{psp_ver}_ip{ipver}"
|
||||||
return test_case
|
return test_case
|
||||||
|
|
||||||
|
|
||||||
@ -582,8 +583,9 @@ def ipver_test_builder(name, test_func, ipver):
|
|||||||
"""Build test cases for each IP version"""
|
"""Build test cases for each IP version"""
|
||||||
def test_case(cfg):
|
def test_case(cfg):
|
||||||
cfg.require_ipver(ipver)
|
cfg.require_ipver(ipver)
|
||||||
test_case.__name__ = f"{name}_ip{ipver}"
|
|
||||||
test_func(cfg, ipver)
|
test_func(cfg, ipver)
|
||||||
|
|
||||||
|
test_case.__name__ = f"{name}_ip{ipver}"
|
||||||
return test_case
|
return test_case
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -800,6 +800,14 @@ ipv6_fcnal()
|
|||||||
set +e
|
set +e
|
||||||
check_nexthop "dev veth1" ""
|
check_nexthop "dev veth1" ""
|
||||||
log_test $? 0 "Nexthops removed on admin down"
|
log_test $? 0 "Nexthops removed on admin down"
|
||||||
|
|
||||||
|
# error routes should be deleted when their nexthop is deleted
|
||||||
|
run_cmd "$IP li set dev veth1 up"
|
||||||
|
run_cmd "$IP -6 nexthop add id 58 dev veth1"
|
||||||
|
run_cmd "$IP ro add blackhole 2001:db8:101::1/128 nhid 58"
|
||||||
|
run_cmd "$IP nexthop del id 58"
|
||||||
|
check_route6 "2001:db8:101::1" ""
|
||||||
|
log_test $? 0 "Error route removed on nexthop deletion"
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6_grp_refs()
|
ipv6_grp_refs()
|
||||||
@ -1459,6 +1467,13 @@ ipv4_fcnal()
|
|||||||
|
|
||||||
run_cmd "$IP ro del 172.16.102.0/24"
|
run_cmd "$IP ro del 172.16.102.0/24"
|
||||||
log_test $? 0 "Delete route when not specifying nexthop attributes"
|
log_test $? 0 "Delete route when not specifying nexthop attributes"
|
||||||
|
|
||||||
|
# error routes should be deleted when their nexthop is deleted
|
||||||
|
run_cmd "$IP nexthop add id 23 dev veth1"
|
||||||
|
run_cmd "$IP ro add blackhole 172.16.102.100/32 nhid 23"
|
||||||
|
run_cmd "$IP nexthop del id 23"
|
||||||
|
check_route "172.16.102.100" ""
|
||||||
|
log_test $? 0 "Error route removed on nexthop deletion"
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv4_grp_fcnal()
|
ipv4_grp_fcnal()
|
||||||
|
|||||||
@ -12,7 +12,7 @@ TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
|
|||||||
ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
|
ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
|
||||||
ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
|
ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
|
||||||
ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
|
ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
|
||||||
fib6_ra_to_static"
|
ipv4_mpath_balance_preferred fib6_ra_to_static"
|
||||||
|
|
||||||
VERBOSE=0
|
VERBOSE=0
|
||||||
PAUSE_ON_FAIL=no
|
PAUSE_ON_FAIL=no
|
||||||
@ -2751,6 +2751,73 @@ ipv4_mpath_balance_test()
|
|||||||
forwarding_cleanup
|
forwarding_cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_route_dev_src()
|
||||||
|
{
|
||||||
|
local pfx="$1"
|
||||||
|
local src="$2"
|
||||||
|
local out
|
||||||
|
|
||||||
|
if out=$($IP -j route get "$pfx" from "$src" | jq -re ".[0].dev"); then
|
||||||
|
echo "$out"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4_mpath_preferred()
|
||||||
|
{
|
||||||
|
local src_ip=$1
|
||||||
|
local pref_dev=$2
|
||||||
|
local dev routes
|
||||||
|
local route0=0
|
||||||
|
local route1=0
|
||||||
|
local pref_route=0
|
||||||
|
num_routes=254
|
||||||
|
|
||||||
|
for i in $(seq 1 $num_routes) ; do
|
||||||
|
dev=$(get_route_dev_src 172.16.105.$i $src_ip)
|
||||||
|
if [ "$dev" = "$pref_dev" ]; then
|
||||||
|
pref_route=$((pref_route+1))
|
||||||
|
elif [ "$dev" = "veth1" ]; then
|
||||||
|
route0=$((route0+1))
|
||||||
|
elif [ "$dev" = "veth3" ]; then
|
||||||
|
route1=$((route1+1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
routes=$((route0+route1))
|
||||||
|
|
||||||
|
[ "$VERBOSE" = "1" ] && echo "multipath: routes seen: ($route0,$route1,$pref_route)"
|
||||||
|
|
||||||
|
if [ x"$pref_dev" = x"" ]; then
|
||||||
|
[[ $routes -ge $num_routes ]] && [[ $route0 -gt 0 ]] && [[ $route1 -gt 0 ]]
|
||||||
|
else
|
||||||
|
[[ $pref_route -ge $num_routes ]]
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4_mpath_balance_preferred_test()
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
echo "IPv4 multipath load balance preferred route"
|
||||||
|
|
||||||
|
forwarding_setup
|
||||||
|
|
||||||
|
$IP route add 172.16.105.0/24 \
|
||||||
|
nexthop via 172.16.101.2 \
|
||||||
|
nexthop via 172.16.103.2
|
||||||
|
|
||||||
|
ipv4_mpath_preferred 172.16.101.1 veth1
|
||||||
|
log_test $? 0 "IPv4 multipath loadbalance from veth1"
|
||||||
|
|
||||||
|
ipv4_mpath_preferred 172.16.103.1 veth3
|
||||||
|
log_test $? 0 "IPv4 multipath loadbalance from veth3"
|
||||||
|
|
||||||
|
ipv4_mpath_preferred 198.51.100.1
|
||||||
|
log_test $? 0 "IPv4 multipath loadbalance from dummy"
|
||||||
|
|
||||||
|
forwarding_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
ipv6_mpath_balance_test()
|
ipv6_mpath_balance_test()
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
@ -2861,6 +2928,7 @@ do
|
|||||||
ipv6_mpath_list) ipv6_mpath_list_test;;
|
ipv6_mpath_list) ipv6_mpath_list_test;;
|
||||||
ipv4_mpath_balance) ipv4_mpath_balance_test;;
|
ipv4_mpath_balance) ipv4_mpath_balance_test;;
|
||||||
ipv6_mpath_balance) ipv6_mpath_balance_test;;
|
ipv6_mpath_balance) ipv6_mpath_balance_test;;
|
||||||
|
ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
|
||||||
fib6_ra_to_static) fib6_ra_to_static;;
|
fib6_ra_to_static) fib6_ra_to_static;;
|
||||||
|
|
||||||
help) echo "Test names: $TESTS"; exit 0;;
|
help) echo "Test names: $TESTS"; exit 0;;
|
||||||
|
|||||||
@ -56,18 +56,12 @@ static void rtattr_end(struct nlmsghdr *nh, struct rtattr *attr)
|
|||||||
static struct rtattr *rtattr_add_str(struct nlmsghdr *nh, unsigned short type,
|
static struct rtattr *rtattr_add_str(struct nlmsghdr *nh, unsigned short type,
|
||||||
const char *s)
|
const char *s)
|
||||||
{
|
{
|
||||||
struct rtattr *rta = rtattr_add(nh, type, strlen(s));
|
unsigned int strsz = strlen(s) + 1;
|
||||||
|
struct rtattr *rta;
|
||||||
|
|
||||||
memcpy(RTA_DATA(rta), s, strlen(s));
|
rta = rtattr_add(nh, type, strsz);
|
||||||
return rta;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rtattr *rtattr_add_strsz(struct nlmsghdr *nh, unsigned short type,
|
memcpy(RTA_DATA(rta), s, strsz);
|
||||||
const char *s)
|
|
||||||
{
|
|
||||||
struct rtattr *rta = rtattr_add(nh, type, strlen(s) + 1);
|
|
||||||
|
|
||||||
strcpy(RTA_DATA(rta), s);
|
|
||||||
return rta;
|
return rta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +113,7 @@ static int dev_create(const char *dev, const char *link_type,
|
|||||||
|
|
||||||
link_info = rtattr_begin(&req.nh, IFLA_LINKINFO);
|
link_info = rtattr_begin(&req.nh, IFLA_LINKINFO);
|
||||||
|
|
||||||
rtattr_add_strsz(&req.nh, IFLA_INFO_KIND, link_type);
|
rtattr_add_str(&req.nh, IFLA_INFO_KIND, link_type);
|
||||||
|
|
||||||
if (fill_info_data) {
|
if (fill_info_data) {
|
||||||
info_data = rtattr_begin(&req.nh, IFLA_INFO_DATA);
|
info_data = rtattr_begin(&req.nh, IFLA_INFO_DATA);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user