mirror of https://gitee.com/openkylin/linux.git
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking update from David Miller: 1) Fix dump iterator in nfnl_acct_dump() and ctnl_timeout_dump() to dump all objects properly, from Pablo Neira Ayuso. 2) xt_TCPMSS must use the default MSS of 536 when no MSS TCP option is present. Fix from Phil Oester. 3) qdisc_get_rtab() looks for an existing matching rate table and uses that instead of creating a new one. However, it's key matching is incomplete, it fails to check to make sure the ->data[] array is identical too. Fix from Eric Dumazet. 4) ip_vs_dest_entry isn't fully initialized before copying back to userspace, fix from Dan Carpenter. 5) Fix ubuf reference counting regression in vhost_net, from Jason Wang. 6) When sock_diag dumps a socket filter back to userspace, we have to translate it out of the kernel's internal representation first. From Nicolas Dichtel. 7) davinci_mdio holds a spinlock while calling pm_runtime, which sleeps. Fix from Sebastian Siewior. 8) Timeout check in sh_eth_check_reset is off by one, from Sergei Shtylyov. 9) If sctp socket init fails, we can NULL deref during cleanup. Fix from Daniel Borkmann. 10) netlink_mmap() does not propagate errors properly, from Patrick McHardy. 11) Disable powersave and use minstrel by default in ath9k. From Sujith Manoharan. 12) Fix a regression in that SOCK_ZEROCOPY is not set on tuntap sockets which prevents vhost from being able to use zerocopy. From Jason Wang. 13) Fix race between port lookup and TX path in team driver, from Jiri Pirko. 14) Missing length checks in bluetooth L2CAP packet parsing, from Johan Hedberg. 15) rtlwifi fails to connect to networking using any encryption method other than WPA2. Fix from Larry Finger. 16) Fix iwlegacy build due to incorrect CONFIG_* ifdeffing for power management stuff. From Yijing Wang. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (35 commits) b43: stop format string leaking into error msgs ath9k: Use minstrel rate control by default Revert "ath9k_hw: Update rx gain initval to improve rx sensitivity" ath9k: Disable PowerSave by default net: wireless: iwlegacy: fix build error for il_pm_ops rtlwifi: Fix a false leak indication for PCI devices wl12xx/wl18xx: scan all 5ghz channels wl12xx: increase minimum singlerole firmware version required wl12xx: fix minimum required firmware version for wl127x multirole rtlwifi: rtl8192cu: Fix problem in connecting to WEP or WPA(1) networks mwifiex: debugfs: Fix out of bounds array access Bluetooth: Fix mgmt handling of power on failures Bluetooth: Fix missing length checks for L2CAP signalling PDUs Bluetooth: btmrvl: support Marvell Bluetooth device SD8897 Bluetooth: Fix checks for LE support on LE-only controllers team: fix checks in team_get_first_port_txable_rcu() team: move add to port list before port enablement team: check return value of team_get_port_by_index_rcu() for NULL tuntap: set SOCK_ZEROCOPY flag during open netlink: fix error propagation in netlink_mmap() ...
This commit is contained in:
commit
26e04462c8
|
@ -201,7 +201,7 @@ config BT_MRVL
|
|||
The core driver to support Marvell Bluetooth devices.
|
||||
|
||||
This driver is required if you want to support
|
||||
Marvell Bluetooth devices, such as 8688/8787/8797.
|
||||
Marvell Bluetooth devices, such as 8688/8787/8797/8897.
|
||||
|
||||
Say Y here to compile Marvell Bluetooth driver
|
||||
into the kernel or say M to compile it as module.
|
||||
|
@ -214,7 +214,7 @@ config BT_MRVL_SDIO
|
|||
The driver for Marvell Bluetooth chipsets with SDIO interface.
|
||||
|
||||
This driver is required if you want to use Marvell Bluetooth
|
||||
devices with SDIO interface. Currently SD8688/SD8787/SD8797
|
||||
devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897
|
||||
chipsets are supported.
|
||||
|
||||
Say Y here to compile support for Marvell BT-over-SDIO driver
|
||||
|
|
|
@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
|
|||
.io_port_2 = 0x7a,
|
||||
};
|
||||
|
||||
static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
|
||||
.cfg = 0x00,
|
||||
.host_int_mask = 0x02,
|
||||
.host_intstatus = 0x03,
|
||||
.card_status = 0x50,
|
||||
.sq_read_base_addr_a0 = 0x60,
|
||||
.sq_read_base_addr_a1 = 0x61,
|
||||
.card_revision = 0xbc,
|
||||
.card_fw_status0 = 0xc0,
|
||||
.card_fw_status1 = 0xc1,
|
||||
.card_rx_len = 0xc2,
|
||||
.card_rx_unit = 0xc3,
|
||||
.io_port_0 = 0xd8,
|
||||
.io_port_1 = 0xd9,
|
||||
.io_port_2 = 0xda,
|
||||
};
|
||||
|
||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
||||
.helper = "mrvl/sd8688_helper.bin",
|
||||
.firmware = "mrvl/sd8688.bin",
|
||||
|
@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
|||
.sd_blksz_fw_dl = 256,
|
||||
};
|
||||
|
||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
||||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8897_uapsta.bin",
|
||||
.reg = &btmrvl_reg_88xx,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
};
|
||||
|
||||
static const struct sdio_device_id btmrvl_sdio_ids[] = {
|
||||
/* Marvell SD8688 Bluetooth device */
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
|
||||
|
@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
|
|||
/* Marvell SD8797 Bluetooth device */
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
|
||||
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
|
||||
/* Marvell SD8897 Bluetooth device */
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
|
||||
.driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
|
|||
MODULE_FIRMWARE("mrvl/sd8688.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
|
||||
|
|
|
@ -897,8 +897,8 @@ static int sh_eth_check_reset(struct net_device *ndev)
|
|||
mdelay(1);
|
||||
cnt--;
|
||||
}
|
||||
if (cnt < 0) {
|
||||
pr_err("Device reset fail\n");
|
||||
if (cnt <= 0) {
|
||||
pr_err("Device reset failed\n");
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -449,10 +449,9 @@ static int davinci_mdio_suspend(struct device *dev)
|
|||
__raw_writel(ctrl, &data->regs->control);
|
||||
wait_for_idle(data);
|
||||
|
||||
pm_runtime_put_sync(data->dev);
|
||||
|
||||
data->suspended = true;
|
||||
spin_unlock(&data->lock);
|
||||
pm_runtime_put_sync(data->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -462,9 +461,9 @@ static int davinci_mdio_resume(struct device *dev)
|
|||
struct davinci_mdio_data *data = dev_get_drvdata(dev);
|
||||
u32 ctrl;
|
||||
|
||||
spin_lock(&data->lock);
|
||||
pm_runtime_get_sync(data->dev);
|
||||
|
||||
spin_lock(&data->lock);
|
||||
/* restart the scan state machine */
|
||||
ctrl = __raw_readl(&data->regs->control);
|
||||
ctrl |= CONTROL_ENABLE;
|
||||
|
|
|
@ -1092,8 +1092,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
|
|||
}
|
||||
|
||||
port->index = -1;
|
||||
team_port_enable(team, port);
|
||||
list_add_tail_rcu(&port->list, &team->port_list);
|
||||
team_port_enable(team, port);
|
||||
__team_compute_features(team);
|
||||
__team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
|
||||
__team_options_change_check(team);
|
||||
|
|
|
@ -28,6 +28,8 @@ static bool rnd_transmit(struct team *team, struct sk_buff *skb)
|
|||
|
||||
port_index = random_N(team->en_port_count);
|
||||
port = team_get_port_by_index_rcu(team, port_index);
|
||||
if (unlikely(!port))
|
||||
goto drop;
|
||||
port = team_get_first_port_txable_rcu(team, port);
|
||||
if (unlikely(!port))
|
||||
goto drop;
|
||||
|
|
|
@ -32,6 +32,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
|
|||
|
||||
port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
|
||||
port = team_get_port_by_index_rcu(team, port_index);
|
||||
if (unlikely(!port))
|
||||
goto drop;
|
||||
port = team_get_first_port_txable_rcu(team, port);
|
||||
if (unlikely(!port))
|
||||
goto drop;
|
||||
|
|
|
@ -352,7 +352,7 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb)
|
|||
u32 numqueues = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
numqueues = tun->numqueues;
|
||||
numqueues = ACCESS_ONCE(tun->numqueues);
|
||||
|
||||
txq = skb_get_rxhash(skb);
|
||||
if (txq) {
|
||||
|
@ -2159,6 +2159,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)
|
|||
set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
|
||||
INIT_LIST_HEAD(&tfile->next);
|
||||
|
||||
sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -627,6 +627,12 @@ static const struct usb_device_id products [] = {
|
|||
.driver_info = 0,
|
||||
},
|
||||
|
||||
/* Huawei E1820 - handled by qmi_wwan */
|
||||
{
|
||||
USB_DEVICE_INTERFACE_NUMBER(HUAWEI_VENDOR_ID, 0x14ac, 1),
|
||||
.driver_info = 0,
|
||||
},
|
||||
|
||||
/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
|
||||
#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE)
|
||||
{
|
||||
|
|
|
@ -519,6 +519,7 @@ static const struct usb_device_id products[] = {
|
|||
/* 3. Combined interface devices matching on interface number */
|
||||
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
|
||||
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
|
||||
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
|
||||
|
|
|
@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG
|
|||
This option enables collection of statistics for Rx/Tx status
|
||||
data and some other MAC related statistics
|
||||
|
||||
config ATH9K_RATE_CONTROL
|
||||
config ATH9K_LEGACY_RATE_CONTROL
|
||||
bool "Atheros ath9k rate control"
|
||||
depends on ATH9K
|
||||
default y
|
||||
default n
|
||||
---help---
|
||||
Say Y, if you want to use the ath9k specific rate control
|
||||
module instead of minstrel_ht.
|
||||
module instead of minstrel_ht. Be warned that there are various
|
||||
issues with the ath9k RC and minstrel is a more robust algorithm.
|
||||
Note that even if this option is selected, "ath9k_rate_control"
|
||||
has to be passed to mac80211 using the module parameter,
|
||||
ieee80211_default_rc_algo.
|
||||
|
||||
config ATH9K_HTC
|
||||
tristate "Atheros HTC based wireless cards support"
|
||||
|
|
|
@ -8,7 +8,7 @@ ath9k-y += beacon.o \
|
|||
antenna.o
|
||||
|
||||
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
|
||||
ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
|
||||
ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
|
||||
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
|
||||
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
|
||||
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||
|
|
|
@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
|
|||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x1a1a1a1a},
|
||||
{0x0000a084, 0x1a1a1a1a},
|
||||
{0x0000a088, 0x1a1a1a1a},
|
||||
{0x0000a08c, 0x1a1a1a1a},
|
||||
{0x0000a090, 0x171a1a1a},
|
||||
{0x0000a080, 0x22222229},
|
||||
{0x0000a084, 0x1d1d1d1d},
|
||||
{0x0000a088, 0x1d1d1d1d},
|
||||
{0x0000a08c, 0x1d1d1d1d},
|
||||
{0x0000a090, 0x171d1d1d},
|
||||
{0x0000a094, 0x11111717},
|
||||
{0x0000a098, 0x00030311},
|
||||
{0x0000a09c, 0x00000000},
|
||||
|
|
|
@ -787,8 +787,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
hw->wiphy->iface_combinations = if_comb;
|
||||
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
||||
|
||||
if (AR_SREV_5416(sc->sc_ah))
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
|
||||
|
@ -830,10 +829,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
sc->ant_rx = hw->wiphy->available_antennas_rx;
|
||||
sc->ant_tx = hw->wiphy->available_antennas_tx;
|
||||
|
||||
#ifdef CONFIG_ATH9K_RATE_CONTROL
|
||||
hw->rate_control_algorithm = "ath9k_rate_control";
|
||||
#endif
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
||||
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
|
||||
&sc->sbands[IEEE80211_BAND_2GHZ];
|
||||
|
|
|
@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ATH9K_RATE_CONTROL
|
||||
#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
|
||||
int ath_rate_control_register(void);
|
||||
void ath_rate_control_unregister(void);
|
||||
#else
|
||||
|
|
|
@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work)
|
|||
for (i = 0; i < B43_NR_FWTYPES; i++) {
|
||||
errmsg = ctx->errors[i];
|
||||
if (strlen(errmsg))
|
||||
b43err(dev->wl, errmsg);
|
||||
b43err(dev->wl, "%s", errmsg);
|
||||
}
|
||||
b43_print_fw_helptext(dev->wl, 1);
|
||||
goto out;
|
||||
|
|
|
@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
|
|||
__le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
|
||||
u32 beacon_interval);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
extern const struct dev_pm_ops il_pm_ops;
|
||||
|
||||
#define IL_LEGACY_PM_OPS (&il_pm_ops)
|
||||
|
||||
#else /* !CONFIG_PM */
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
|
||||
#define IL_LEGACY_PM_OPS NULL
|
||||
|
||||
#endif /* !CONFIG_PM */
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
|
||||
/*****************************************************
|
||||
* Error Handling Debugging
|
||||
|
|
|
@ -26,10 +26,17 @@
|
|||
static struct dentry *mwifiex_dfs_dir;
|
||||
|
||||
static char *bss_modes[] = {
|
||||
"Unknown",
|
||||
"Ad-hoc",
|
||||
"Managed",
|
||||
"Auto"
|
||||
"UNSPECIFIED",
|
||||
"ADHOC",
|
||||
"STATION",
|
||||
"AP",
|
||||
"AP_VLAN",
|
||||
"WDS",
|
||||
"MONITOR",
|
||||
"MESH_POINT",
|
||||
"P2P_CLIENT",
|
||||
"P2P_GO",
|
||||
"P2P_DEVICE",
|
||||
};
|
||||
|
||||
/* size/addr for mwifiex_debug_info */
|
||||
|
@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
|
|||
p += sprintf(p, "driver_version = %s", fmt);
|
||||
p += sprintf(p, "\nverext = %s", priv->version_str);
|
||||
p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
|
||||
p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
|
||||
|
||||
if (info.bss_mode >= ARRAY_SIZE(bss_modes))
|
||||
p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
|
||||
else
|
||||
p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
|
||||
|
||||
p += sprintf(p, "media_state=\"%s\"\n",
|
||||
(!priv->media_connected ? "Disconnected" : "Connected"));
|
||||
p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
|
||||
|
|
|
@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
|||
"can't alloc skb for rx\n");
|
||||
goto done;
|
||||
}
|
||||
kmemleak_not_leak(new_skb);
|
||||
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
*((dma_addr_t *) skb->cb),
|
||||
|
|
|
@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
|||
}
|
||||
}
|
||||
|
||||
void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level)
|
||||
static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u32 ratr_value = (u32) mac->basic_rates;
|
||||
u8 *mcsrate = mac->mcs;
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u32 ratr_value;
|
||||
u8 ratr_index = 0;
|
||||
u8 nmode = mac->ht_enable;
|
||||
u8 mimo_ps = 1;
|
||||
u16 shortgi_rate = 0;
|
||||
u32 tmp_ratr_value = 0;
|
||||
u8 mimo_ps = IEEE80211_SMPS_OFF;
|
||||
u16 shortgi_rate;
|
||||
u32 tmp_ratr_value;
|
||||
u8 curtxbw_40mhz = mac->bw_40;
|
||||
u8 curshortgi_40mhz = mac->sgi_40;
|
||||
u8 curshortgi_20mhz = mac->sgi_20;
|
||||
u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||
1 : 0;
|
||||
u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
|
||||
1 : 0;
|
||||
enum wireless_mode wirelessmode = mac->mode;
|
||||
|
||||
ratr_value |= ((*(u16 *) (mcsrate))) << 12;
|
||||
if (rtlhal->current_bandtype == BAND_ON_5G)
|
||||
ratr_value = sta->supp_rates[1] << 4;
|
||||
else
|
||||
ratr_value = sta->supp_rates[0];
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
ratr_value = 0xfff;
|
||||
|
||||
ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
|
||||
sta->ht_cap.mcs.rx_mask[0] << 12);
|
||||
switch (wirelessmode) {
|
||||
case WIRELESS_MODE_B:
|
||||
if (ratr_value & 0x0000000c)
|
||||
|
@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
|||
case WIRELESS_MODE_N_24G:
|
||||
case WIRELESS_MODE_N_5G:
|
||||
nmode = 1;
|
||||
if (mimo_ps == 0) {
|
||||
if (mimo_ps == IEEE80211_SMPS_STATIC) {
|
||||
ratr_value &= 0x0007F005;
|
||||
} else {
|
||||
u32 ratr_mask;
|
||||
|
@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
|||
ratr_mask = 0x000ff005;
|
||||
else
|
||||
ratr_mask = 0x0f0ff005;
|
||||
if (curtxbw_40mhz)
|
||||
ratr_mask |= 0x00000010;
|
||||
|
||||
ratr_value &= ratr_mask;
|
||||
}
|
||||
break;
|
||||
|
@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
|||
ratr_value &= 0x000ff0ff;
|
||||
else
|
||||
ratr_value &= 0x0f0ff0ff;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ratr_value &= 0x0FFFFFFF;
|
||||
if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
|
||||
(!curtxbw_40mhz && curshortgi_20mhz))) {
|
||||
|
||||
if (nmode && ((curtxbw_40mhz &&
|
||||
curshortgi_40mhz) || (!curtxbw_40mhz &&
|
||||
curshortgi_20mhz))) {
|
||||
|
||||
ratr_value |= 0x10000000;
|
||||
tmp_ratr_value = (ratr_value >> 12);
|
||||
|
||||
for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
|
||||
if ((1 << shortgi_rate) & tmp_ratr_value)
|
||||
break;
|
||||
}
|
||||
|
||||
shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
|
||||
(shortgi_rate << 4) | (shortgi_rate);
|
||||
(shortgi_rate << 4) | (shortgi_rate);
|
||||
}
|
||||
|
||||
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
|
||||
rtl_read_dword(rtlpriv, REG_ARFR0));
|
||||
}
|
||||
|
||||
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||
static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u32 ratr_bitmap = (u32) mac->basic_rates;
|
||||
u8 *p_mcsrate = mac->mcs;
|
||||
u8 ratr_index = 0;
|
||||
u8 curtxbw_40mhz = mac->bw_40;
|
||||
u8 curshortgi_40mhz = mac->sgi_40;
|
||||
u8 curshortgi_20mhz = mac->sgi_20;
|
||||
enum wireless_mode wirelessmode = mac->mode;
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_sta_info *sta_entry = NULL;
|
||||
u32 ratr_bitmap;
|
||||
u8 ratr_index;
|
||||
u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
|
||||
u8 curshortgi_40mhz = curtxbw_40mhz &&
|
||||
(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||
1 : 0;
|
||||
u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
|
||||
1 : 0;
|
||||
enum wireless_mode wirelessmode = 0;
|
||||
bool shortgi = false;
|
||||
u8 rate_mask[5];
|
||||
u8 macid = 0;
|
||||
u8 mimops = 1;
|
||||
u8 mimo_ps = IEEE80211_SMPS_OFF;
|
||||
|
||||
ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
|
||||
sta_entry = (struct rtl_sta_info *) sta->drv_priv;
|
||||
wirelessmode = sta_entry->wireless_mode;
|
||||
if (mac->opmode == NL80211_IFTYPE_STATION ||
|
||||
mac->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||
curtxbw_40mhz = mac->bw_40;
|
||||
else if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||
mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
macid = sta->aid + 1;
|
||||
|
||||
if (rtlhal->current_bandtype == BAND_ON_5G)
|
||||
ratr_bitmap = sta->supp_rates[1] << 4;
|
||||
else
|
||||
ratr_bitmap = sta->supp_rates[0];
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
ratr_bitmap = 0xfff;
|
||||
ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
|
||||
sta->ht_cap.mcs.rx_mask[0] << 12);
|
||||
switch (wirelessmode) {
|
||||
case WIRELESS_MODE_B:
|
||||
ratr_index = RATR_INX_WIRELESS_B;
|
||||
|
@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
|||
break;
|
||||
case WIRELESS_MODE_G:
|
||||
ratr_index = RATR_INX_WIRELESS_GB;
|
||||
|
||||
if (rssi_level == 1)
|
||||
ratr_bitmap &= 0x00000f00;
|
||||
else if (rssi_level == 2)
|
||||
|
@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
|||
case WIRELESS_MODE_N_24G:
|
||||
case WIRELESS_MODE_N_5G:
|
||||
ratr_index = RATR_INX_WIRELESS_NGB;
|
||||
if (mimops == 0) {
|
||||
|
||||
if (mimo_ps == IEEE80211_SMPS_STATIC) {
|
||||
if (rssi_level == 1)
|
||||
ratr_bitmap &= 0x00070000;
|
||||
else if (rssi_level == 2)
|
||||
|
@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((curtxbw_40mhz && curshortgi_40mhz) ||
|
||||
(!curtxbw_40mhz && curshortgi_20mhz)) {
|
||||
|
||||
if (macid == 0)
|
||||
shortgi = true;
|
||||
else if (macid == 1)
|
||||
|
@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
|||
break;
|
||||
default:
|
||||
ratr_index = RATR_INX_WIRELESS_NGB;
|
||||
|
||||
if (rtlphy->rf_type == RF_1T2R)
|
||||
ratr_bitmap &= 0x000ff0ff;
|
||||
else
|
||||
ratr_bitmap &= 0x0f0ff0ff;
|
||||
break;
|
||||
}
|
||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
|
||||
ratr_bitmap);
|
||||
*(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
|
||||
ratr_index << 28);
|
||||
sta_entry->ratr_index = ratr_index;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
|
||||
"ratr_bitmap :%x\n", ratr_bitmap);
|
||||
*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
|
||||
(ratr_index << 28);
|
||||
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
|
||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
|
||||
"Rate_index:%x, ratr_val:%x, %5phC\n",
|
||||
ratr_index, ratr_bitmap, rate_mask);
|
||||
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
|
||||
memcpy(rtlpriv->rate_mask, rate_mask, 5);
|
||||
/* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
|
||||
* "scheduled while atomic" if called directly */
|
||||
schedule_work(&rtlpriv->works.fill_h2c_cmd);
|
||||
|
||||
if (macid != 0)
|
||||
sta_entry->ratr_index = ratr_index;
|
||||
}
|
||||
|
||||
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->dm.useramask)
|
||||
rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
|
||||
else
|
||||
rtl92cu_update_hal_rate_table(hw, sta);
|
||||
}
|
||||
|
||||
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
|
||||
|
|
|
@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
|
|||
u32 add_msr, u32 rm_msr);
|
||||
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level);
|
||||
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
|
||||
|
||||
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
|
||||
|
|
|
@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
|
|||
macaddr = cam_const_broad;
|
||||
entry_id = key_index;
|
||||
} else {
|
||||
if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||
mac->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||
entry_id = rtl_cam_get_free_entry(hw,
|
||||
p_macaddr);
|
||||
if (entry_id >= TOTAL_CAM_ENTRY) {
|
||||
RT_TRACE(rtlpriv, COMP_SEC,
|
||||
DBG_EMERG,
|
||||
"Can not find free hw security cam entry\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
entry_id = CAM_PAIRWISE_KEY_POSITION;
|
||||
}
|
||||
|
||||
key_index = PAIRWISE_KEYIDX;
|
||||
entry_id = CAM_PAIRWISE_KEY_POSITION;
|
||||
is_pairwise = true;
|
||||
}
|
||||
}
|
||||
if (rtlpriv->sec.key_len[key_index] == 0) {
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
"delete one entry\n");
|
||||
if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||
mac->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||
rtl_cam_del_entry(hw, p_macaddr);
|
||||
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
|
||||
} else {
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
|
|
|
@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
|||
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
|
||||
.get_hw_reg = rtl92cu_get_hw_reg,
|
||||
.set_hw_reg = rtl92cu_set_hw_reg,
|
||||
.update_rate_tbl = rtl92cu_update_hal_rate_table,
|
||||
.update_rate_mask = rtl92cu_update_hal_rate_mask,
|
||||
.update_rate_tbl = rtl92cu_update_hal_rate_tbl,
|
||||
.fill_tx_desc = rtl92cu_tx_fill_desc,
|
||||
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
|
||||
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
|
||||
|
@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
|||
.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
|
||||
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
|
||||
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
|
||||
.fill_h2c_cmd = rtl92c_fill_h2c_cmd,
|
||||
};
|
||||
|
||||
static struct rtl_mod_params rtl92cu_mod_params = {
|
||||
|
|
|
@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
|||
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 regaddr, u32 bitmask);
|
||||
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
|
||||
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
|
|||
|
||||
/* should after adapter start and interrupt enable. */
|
||||
set_hal_stop(rtlhal);
|
||||
cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
|
||||
/* Enable software */
|
||||
SET_USB_STOP(rtlusb);
|
||||
rtl_usb_deinit(hw);
|
||||
|
@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work)
|
||||
{
|
||||
struct rtl_works *rtlworks =
|
||||
container_of(work, struct rtl_works, fill_h2c_cmd);
|
||||
struct ieee80211_hw *hw = rtlworks->hw;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask);
|
||||
}
|
||||
|
||||
static struct rtl_intf_ops rtl_usb_ops = {
|
||||
.adapter_start = rtl_usb_start,
|
||||
.adapter_stop = rtl_usb_stop,
|
||||
|
@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf,
|
|||
|
||||
/* this spin lock must be initialized early */
|
||||
spin_lock_init(&rtlpriv->locks.usb_lock);
|
||||
INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
|
||||
rtl_fill_h2c_cmd_work_callback);
|
||||
|
||||
rtlpriv->usb_data_index = 0;
|
||||
init_completion(&rtlpriv->firmware_loading_complete);
|
||||
|
|
|
@ -1736,6 +1736,8 @@ struct rtl_hal_ops {
|
|||
void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
|
||||
bool mstate);
|
||||
void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
|
||||
void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
|
||||
u32 cmd_len, u8 *p_cmdbuffer);
|
||||
};
|
||||
|
||||
struct rtl_intf_ops {
|
||||
|
@ -1869,6 +1871,7 @@ struct rtl_works {
|
|||
struct delayed_work fwevt_wq;
|
||||
|
||||
struct work_struct lps_change_work;
|
||||
struct work_struct fill_h2c_cmd;
|
||||
};
|
||||
|
||||
struct rtl_debug {
|
||||
|
@ -2048,6 +2051,7 @@ struct rtl_priv {
|
|||
};
|
||||
};
|
||||
bool enter_ps; /* true when entering PS */
|
||||
u8 rate_mask[5];
|
||||
|
||||
/*This must be the last item so
|
||||
that it points to the data allocated
|
||||
|
|
|
@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
|
|||
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
||||
sizeof(cmd->channels_2));
|
||||
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
||||
sizeof(cmd->channels_2));
|
||||
sizeof(cmd->channels_5));
|
||||
/* channels_4 are not supported, so no need to copy them */
|
||||
}
|
||||
|
||||
|
|
|
@ -36,12 +36,12 @@
|
|||
#define WL127X_IFTYPE_SR_VER 3
|
||||
#define WL127X_MAJOR_SR_VER 10
|
||||
#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
||||
#define WL127X_MINOR_SR_VER 115
|
||||
#define WL127X_MINOR_SR_VER 133
|
||||
/* minimum multi-role FW version for wl127x */
|
||||
#define WL127X_IFTYPE_MR_VER 5
|
||||
#define WL127X_MAJOR_MR_VER 7
|
||||
#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
|
||||
#define WL127X_MINOR_MR_VER 115
|
||||
#define WL127X_MINOR_MR_VER 42
|
||||
|
||||
/* FW chip version for wl128x */
|
||||
#define WL128X_CHIP_VER 7
|
||||
|
@ -49,7 +49,7 @@
|
|||
#define WL128X_IFTYPE_SR_VER 3
|
||||
#define WL128X_MAJOR_SR_VER 10
|
||||
#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
||||
#define WL128X_MINOR_SR_VER 115
|
||||
#define WL128X_MINOR_SR_VER 133
|
||||
/* minimum multi-role FW version for wl128x */
|
||||
#define WL128X_IFTYPE_MR_VER 5
|
||||
#define WL128X_MAJOR_MR_VER 7
|
||||
|
|
|
@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd,
|
|||
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
||||
sizeof(cmd->channels_2));
|
||||
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
||||
sizeof(cmd->channels_2));
|
||||
sizeof(cmd->channels_5));
|
||||
/* channels_4 are not supported, so no need to copy them */
|
||||
}
|
||||
|
||||
|
|
|
@ -155,14 +155,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
|
|||
|
||||
static void vhost_net_clear_ubuf_info(struct vhost_net *n)
|
||||
{
|
||||
|
||||
bool zcopy;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n->dev.nvqs; ++i) {
|
||||
zcopy = vhost_net_zcopy_mask & (0x1 << i);
|
||||
if (zcopy)
|
||||
kfree(n->vqs[i].ubuf_info);
|
||||
for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
|
||||
kfree(n->vqs[i].ubuf_info);
|
||||
n->vqs[i].ubuf_info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +168,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
|
|||
bool zcopy;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n->dev.nvqs; ++i) {
|
||||
for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
|
||||
zcopy = vhost_net_zcopy_mask & (0x1 << i);
|
||||
if (!zcopy)
|
||||
continue;
|
||||
|
@ -183,12 +180,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
while (i--) {
|
||||
zcopy = vhost_net_zcopy_mask & (0x1 << i);
|
||||
if (!zcopy)
|
||||
continue;
|
||||
kfree(n->vqs[i].ubuf_info);
|
||||
}
|
||||
vhost_net_clear_ubuf_info(n);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -196,12 +188,12 @@ void vhost_net_vq_reset(struct vhost_net *n)
|
|||
{
|
||||
int i;
|
||||
|
||||
vhost_net_clear_ubuf_info(n);
|
||||
|
||||
for (i = 0; i < VHOST_NET_VQ_MAX; i++) {
|
||||
n->vqs[i].done_idx = 0;
|
||||
n->vqs[i].upend_idx = 0;
|
||||
n->vqs[i].ubufs = NULL;
|
||||
kfree(n->vqs[i].ubuf_info);
|
||||
n->vqs[i].ubuf_info = NULL;
|
||||
n->vqs[i].vhost_hlen = 0;
|
||||
n->vqs[i].sock_hlen = 0;
|
||||
}
|
||||
|
@ -436,7 +428,8 @@ static void handle_tx(struct vhost_net *net)
|
|||
kref_get(&ubufs->kref);
|
||||
}
|
||||
nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV;
|
||||
}
|
||||
} else
|
||||
msg.msg_control = NULL;
|
||||
/* TODO: Check specific error and bomb out unless ENOBUFS? */
|
||||
err = sock->ops->sendmsg(NULL, sock, &msg, len);
|
||||
if (unlikely(err < 0)) {
|
||||
|
@ -1053,6 +1046,10 @@ static long vhost_net_set_owner(struct vhost_net *n)
|
|||
int r;
|
||||
|
||||
mutex_lock(&n->dev.mutex);
|
||||
if (vhost_dev_has_owner(&n->dev)) {
|
||||
r = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
r = vhost_net_set_ubuf_info(n);
|
||||
if (r)
|
||||
goto out;
|
||||
|
|
|
@ -343,6 +343,12 @@ static int vhost_attach_cgroups(struct vhost_dev *dev)
|
|||
return attach.ret;
|
||||
}
|
||||
|
||||
/* Caller should have device mutex */
|
||||
bool vhost_dev_has_owner(struct vhost_dev *dev)
|
||||
{
|
||||
return dev->mm;
|
||||
}
|
||||
|
||||
/* Caller should have device mutex */
|
||||
long vhost_dev_set_owner(struct vhost_dev *dev)
|
||||
{
|
||||
|
@ -350,7 +356,7 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
|
|||
int err;
|
||||
|
||||
/* Is there an owner already? */
|
||||
if (dev->mm) {
|
||||
if (vhost_dev_has_owner(dev)) {
|
||||
err = -EBUSY;
|
||||
goto err_mm;
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ struct vhost_dev {
|
|||
|
||||
long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int nvqs);
|
||||
long vhost_dev_set_owner(struct vhost_dev *dev);
|
||||
bool vhost_dev_has_owner(struct vhost_dev *dev);
|
||||
long vhost_dev_check_owner(struct vhost_dev *);
|
||||
struct vhost_memory *vhost_dev_reset_owner_prepare(void);
|
||||
void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_memory *);
|
||||
|
|
|
@ -46,6 +46,7 @@ extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
|
|||
extern int sk_detach_filter(struct sock *sk);
|
||||
extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
|
||||
extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len);
|
||||
extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);
|
||||
|
||||
#ifdef CONFIG_BPF_JIT
|
||||
#include <stdarg.h>
|
||||
|
|
|
@ -249,12 +249,12 @@ team_get_first_port_txable_rcu(struct team *team, struct team_port *port)
|
|||
return port;
|
||||
cur = port;
|
||||
list_for_each_entry_continue_rcu(cur, &team->port_list, list)
|
||||
if (team_port_txable(port))
|
||||
if (team_port_txable(cur))
|
||||
return cur;
|
||||
list_for_each_entry_rcu(cur, &team->port_list, list) {
|
||||
if (cur == port)
|
||||
break;
|
||||
if (team_port_txable(port))
|
||||
if (team_port_txable(cur))
|
||||
return cur;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
|
|||
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
|
||||
int mgmt_index_added(struct hci_dev *hdev);
|
||||
int mgmt_index_removed(struct hci_dev *hdev);
|
||||
int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
|
||||
int mgmt_powered(struct hci_dev *hdev, u8 powered);
|
||||
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
|
||||
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#define MGMT_STATUS_NOT_POWERED 0x0f
|
||||
#define MGMT_STATUS_CANCELLED 0x10
|
||||
#define MGMT_STATUS_INVALID_INDEX 0x11
|
||||
#define MGMT_STATUS_RFKILLED 0x12
|
||||
|
||||
struct mgmt_hdr {
|
||||
__le16 opcode;
|
||||
|
|
|
@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = {
|
|||
static void hci_power_on(struct work_struct *work)
|
||||
{
|
||||
struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
|
||||
int err;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
if (hci_dev_open(hdev->id) < 0)
|
||||
err = hci_dev_open(hdev->id);
|
||||
if (err < 0) {
|
||||
mgmt_set_powered_failed(hdev, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
|
||||
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
|
||||
|
|
|
@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
|
|||
}
|
||||
|
||||
static inline int l2cap_command_rej(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
|
||||
|
||||
if (cmd_len < sizeof(*rej))
|
||||
return -EPROTO;
|
||||
|
||||
if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
|
||||
return 0;
|
||||
|
||||
|
@ -3829,11 +3833,14 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static int l2cap_connect_req(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hcon->hdev;
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
|
||||
if (cmd_len < sizeof(struct l2cap_conn_req))
|
||||
return -EPROTO;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
|
||||
|
@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
|
||||
u16 scid, dcid, result, status;
|
||||
|
@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
|||
u8 req[128];
|
||||
int err;
|
||||
|
||||
if (cmd_len < sizeof(*rsp))
|
||||
return -EPROTO;
|
||||
|
||||
scid = __le16_to_cpu(rsp->scid);
|
||||
dcid = __le16_to_cpu(rsp->dcid);
|
||||
result = __le16_to_cpu(rsp->result);
|
||||
|
@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
|||
struct l2cap_chan *chan;
|
||||
int len, err = 0;
|
||||
|
||||
if (cmd_len < sizeof(*req))
|
||||
return -EPROTO;
|
||||
|
||||
dcid = __le16_to_cpu(req->dcid);
|
||||
flags = __le16_to_cpu(req->flags);
|
||||
|
||||
|
@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
|||
|
||||
/* Reject if config buffer is too small. */
|
||||
len = cmd_len - sizeof(*req);
|
||||
if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
|
||||
if (chan->conf_len + len > sizeof(chan->conf_req)) {
|
||||
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
|
||||
l2cap_build_conf_rsp(chan, rsp,
|
||||
L2CAP_CONF_REJECT, flags), rsp);
|
||||
|
@ -4053,14 +4067,18 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
|
||||
u16 scid, flags, result;
|
||||
struct l2cap_chan *chan;
|
||||
int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
|
||||
int len = cmd_len - sizeof(*rsp);
|
||||
int err = 0;
|
||||
|
||||
if (cmd_len < sizeof(*rsp))
|
||||
return -EPROTO;
|
||||
|
||||
scid = __le16_to_cpu(rsp->scid);
|
||||
flags = __le16_to_cpu(rsp->flags);
|
||||
result = __le16_to_cpu(rsp->result);
|
||||
|
@ -4161,7 +4179,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
|
||||
struct l2cap_disconn_rsp rsp;
|
||||
|
@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
|||
struct l2cap_chan *chan;
|
||||
struct sock *sk;
|
||||
|
||||
if (cmd_len != sizeof(*req))
|
||||
return -EPROTO;
|
||||
|
||||
scid = __le16_to_cpu(req->scid);
|
||||
dcid = __le16_to_cpu(req->dcid);
|
||||
|
||||
|
@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
|
||||
u16 dcid, scid;
|
||||
struct l2cap_chan *chan;
|
||||
|
||||
if (cmd_len != sizeof(*rsp))
|
||||
return -EPROTO;
|
||||
|
||||
scid = __le16_to_cpu(rsp->scid);
|
||||
dcid = __le16_to_cpu(rsp->dcid);
|
||||
|
||||
|
@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static inline int l2cap_information_req(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_info_req *req = (struct l2cap_info_req *) data;
|
||||
u16 type;
|
||||
|
||||
if (cmd_len != sizeof(*req))
|
||||
return -EPROTO;
|
||||
|
||||
type = __le16_to_cpu(req->type);
|
||||
|
||||
BT_DBG("type 0x%4.4x", type);
|
||||
|
@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
|
|||
}
|
||||
|
||||
static inline int l2cap_information_rsp(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
|
||||
u16 type, result;
|
||||
|
||||
if (cmd_len != sizeof(*rsp))
|
||||
return -EPROTO;
|
||||
|
||||
type = __le16_to_cpu(rsp->type);
|
||||
result = __le16_to_cpu(rsp->result);
|
||||
|
||||
|
@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
|||
|
||||
switch (cmd->code) {
|
||||
case L2CAP_COMMAND_REJ:
|
||||
l2cap_command_rej(conn, cmd, data);
|
||||
l2cap_command_rej(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_CONN_REQ:
|
||||
err = l2cap_connect_req(conn, cmd, data);
|
||||
err = l2cap_connect_req(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_CONN_RSP:
|
||||
case L2CAP_CREATE_CHAN_RSP:
|
||||
err = l2cap_connect_create_rsp(conn, cmd, data);
|
||||
err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_CONF_REQ:
|
||||
|
@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
|||
break;
|
||||
|
||||
case L2CAP_CONF_RSP:
|
||||
err = l2cap_config_rsp(conn, cmd, data);
|
||||
err = l2cap_config_rsp(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_DISCONN_REQ:
|
||||
err = l2cap_disconnect_req(conn, cmd, data);
|
||||
err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_DISCONN_RSP:
|
||||
err = l2cap_disconnect_rsp(conn, cmd, data);
|
||||
err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_ECHO_REQ:
|
||||
|
@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
|||
break;
|
||||
|
||||
case L2CAP_INFO_REQ:
|
||||
err = l2cap_information_req(conn, cmd, data);
|
||||
err = l2cap_information_req(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_INFO_RSP:
|
||||
err = l2cap_information_rsp(conn, cmd, data);
|
||||
err = l2cap_information_rsp(conn, cmd, cmd_len, data);
|
||||
break;
|
||||
|
||||
case L2CAP_CREATE_CHAN_REQ:
|
||||
|
|
|
@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
|
|||
break;
|
||||
|
||||
case DISCOV_TYPE_LE:
|
||||
if (!lmp_host_le_capable(hdev)) {
|
||||
if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
|
||||
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
||||
MGMT_STATUS_NOT_SUPPORTED);
|
||||
mgmt_pending_remove(cmd);
|
||||
|
@ -3418,6 +3418,27 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
|
|||
return err;
|
||||
}
|
||||
|
||||
int mgmt_set_powered_failed(struct hci_dev *hdev, int err)
|
||||
{
|
||||
struct pending_cmd *cmd;
|
||||
u8 status;
|
||||
|
||||
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
|
||||
if (!cmd)
|
||||
return -ENOENT;
|
||||
|
||||
if (err == -ERFKILL)
|
||||
status = MGMT_STATUS_RFKILLED;
|
||||
else
|
||||
status = MGMT_STATUS_FAILED;
|
||||
|
||||
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
|
||||
{
|
||||
struct cmd_lookup match = { NULL, hdev };
|
||||
|
|
|
@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
|||
|
||||
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
|
||||
|
||||
if (!lmp_host_le_capable(hcon->hdev))
|
||||
if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
|
||||
return 1;
|
||||
|
||||
if (sec_level == BT_SECURITY_LOW)
|
||||
|
@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
__u8 reason;
|
||||
int err = 0;
|
||||
|
||||
if (!lmp_host_le_capable(conn->hcon->hdev)) {
|
||||
if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) {
|
||||
err = -ENOTSUPP;
|
||||
reason = SMP_PAIRING_NOTSUPP;
|
||||
goto done;
|
||||
|
|
|
@ -778,7 +778,7 @@ int sk_detach_filter(struct sock *sk)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(sk_detach_filter);
|
||||
|
||||
static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
|
||||
void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
|
||||
{
|
||||
static const u16 decodes[] = {
|
||||
[BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K,
|
||||
|
|
|
@ -73,8 +73,13 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (filter)
|
||||
memcpy(nla_data(attr), filter->insns, len);
|
||||
if (filter) {
|
||||
struct sock_filter *fb = (struct sock_filter *)nla_data(attr);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < filter->len; i++, fb++)
|
||||
sk_decode_filter(&filter->insns[i], fb);
|
||||
}
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -2542,6 +2542,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get,
|
|||
struct ip_vs_dest *dest;
|
||||
struct ip_vs_dest_entry entry;
|
||||
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
list_for_each_entry(dest, &svc->destinations, n_list) {
|
||||
if (count >= get->num_dests)
|
||||
break;
|
||||
|
|
|
@ -149,9 +149,12 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(cur, &nfnl_acct_list, head) {
|
||||
if (last && cur != last)
|
||||
continue;
|
||||
if (last) {
|
||||
if (cur != last)
|
||||
continue;
|
||||
|
||||
last = NULL;
|
||||
}
|
||||
if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
|
||||
|
|
|
@ -220,9 +220,12 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(cur, &cttimeout_list, head) {
|
||||
if (last && cur != last)
|
||||
continue;
|
||||
if (last) {
|
||||
if (cur != last)
|
||||
continue;
|
||||
|
||||
last = NULL;
|
||||
}
|
||||
if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
|
||||
|
|
|
@ -637,9 +637,6 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|||
if (queue->copy_mode == NFQNL_COPY_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(entry->skb))
|
||||
return __nfqnl_enqueue_packet(net, queue, entry);
|
||||
|
||||
skb = entry->skb;
|
||||
|
||||
switch (entry->pf) {
|
||||
|
@ -651,6 +648,9 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(skb))
|
||||
return __nfqnl_enqueue_packet(net, queue, entry);
|
||||
|
||||
nf_bridge_adjust_skb_data(skb);
|
||||
segs = skb_gso_segment(skb, 0);
|
||||
/* Does not use PTR_ERR to limit the number of error codes that can be
|
||||
|
|
|
@ -125,6 +125,12 @@ tcpmss_mangle_packet(struct sk_buff *skb,
|
|||
|
||||
skb_put(skb, TCPOLEN_MSS);
|
||||
|
||||
/* RFC 879 states that the default MSS is 536 without specific
|
||||
* knowledge that the destination host is prepared to accept larger.
|
||||
* Since no MSS was provided, we MUST NOT set a value > 536.
|
||||
*/
|
||||
newmss = min(newmss, (u16)536);
|
||||
|
||||
opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
|
||||
memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ static int netlink_mmap(struct file *file, struct socket *sock,
|
|||
err = 0;
|
||||
out:
|
||||
mutex_unlock(&nlk->pg_vec_lock);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr)
|
||||
|
|
|
@ -291,17 +291,18 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta
|
|||
{
|
||||
struct qdisc_rate_table *rtab;
|
||||
|
||||
if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
|
||||
nla_len(tab) != TC_RTAB_SIZE)
|
||||
return NULL;
|
||||
|
||||
for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
|
||||
if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) {
|
||||
if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
|
||||
!memcmp(&rtab->data, nla_data(tab), 1024)) {
|
||||
rtab->refcnt++;
|
||||
return rtab;
|
||||
}
|
||||
}
|
||||
|
||||
if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
|
||||
nla_len(tab) != TC_RTAB_SIZE)
|
||||
return NULL;
|
||||
|
||||
rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
|
||||
if (rtab) {
|
||||
rtab->rate = *r;
|
||||
|
|
|
@ -4003,6 +4003,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
|
|||
|
||||
/* Release our hold on the endpoint. */
|
||||
sp = sctp_sk(sk);
|
||||
/* This could happen during socket init, thus we bail out
|
||||
* early, since the rest of the below is not setup either.
|
||||
*/
|
||||
if (sp->ep == NULL)
|
||||
return;
|
||||
|
||||
if (sp->do_auto_asconf) {
|
||||
sp->do_auto_asconf = 0;
|
||||
list_del(&sp->auto_asconf_list);
|
||||
|
|
Loading…
Reference in New Issue