mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking updates from David Miller: "Much more accumulated than I would have liked due to an unexpected bout with a nasty flu: 1) AH and ESP input don't set ECN field correctly because the transport head of the SKB isn't set correctly, fix from Li RongQing. 2) If netfilter conntrack zones are disabled, we can return an uninitialized variable instead of the proper error code. Fix from Borislav Petkov. 3) Fix double SKB free in ath9k driver beacon handling, from Felix Feitkau. 4) Remove bogus assumption about netns cleanup ordering in nf_conntrack, from Pablo Neira Ayuso. 5) Remove a bogus BUG_ON in the new TCP fastopen code, from Eric Dumazet. It uses spin_is_locked() in it's test and is therefore unsuitable for UP. 6) Fix SELINUX labelling regressions added by the tuntap multiqueue changes, from Paul Moore. 7) Fix CRC errors with jumbo frame receive in tg3 driver, from Nithin Nayak Sujir. 8) CXGB4 driver sets interrupt coalescing parameters only on first queue, rather than all of them. Fix from Thadeu Lima de Souza Cascardo. 9) Fix regression in the dispatch of read/write registers in dm9601 driver, from Tushar Behera. 10) ipv6_append_data miscalculates header length, from Romain KUNTZ. 11) Fix PMTU handling regressions on ipv4 routes, from Steffen Klassert, Timo Teräs, and Julian Anastasov. 12) In 3c574_cs driver, add necessary parenthesis to "x << y & z" expression. From Nickolai Zeldovich. 13) macvlan_get_size() causes underallocation netlink message space, fix from Eric Dumazet. 14) Avoid division by zero in xfrm_replay_advance_bmp(), from Nickolai Zeldovich. Amusingly the zero check was already there, we were just performing it after the modulus :-) 15) Some more splice bug fixes from Eric Dumazet, which fix things mostly eminating from how we now more aggressively use high-order pages in SKBs. 16) Fix size calculation bug when freeing hash tables in the IPSEC xfrm code, from Michal Kubecek. 17) Fix PMTU event propagation into socket cached routes, from Steffen Klassert. 18) Fix off by one in TX buffer release in netxen driver, from Eric Dumazet. 19) Fix rediculous memory allocation requirements introduced by the tuntap multiqueue changes, from Jason Wang. 20) Remove bogus AMD platform workaround in r8169 driver that causes major problems in normal operation, from Timo Teräs. 21) virtio-net set affinity and select queue don't handle discontiguous cpu numbers properly, fix from Wanlong Gao. 22) Fix a route refcounting issue in loopback driver, from Eric Dumazet. There's a similar fix coming that we might add to the macvlan driver as well. 23) Fix SKB leaks in batman-adv's distributed arp table code, from Matthias Schiffer. 24) r8169 driver gives descriptor ownership back the hardware before we're done reading the VLAN tag out of it, fix from Francois Romieu. 25) Checksums not calculated properly in GRE tunnel driver fix from Pravin B Shelar. 26) Fix SCTP memory leak on namespace exit." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (101 commits) dm9601: support dm9620 variant SCTP: Free the per-net sysctl table on net exit. v2 net: phy: icplus: fix broken INTR pin settings net: phy: icplus: Use the RGMII interface mode to configure clock delays IP_GRE: Fix kernel panic in IP_GRE with GRE csum. sctp: set association state to established in dupcook_a handler ip6mr: limit IPv6 MRT_TABLE identifiers r8169: fix vlan tag read ordering. net: cdc_ncm: use IAD provided by the USB core batman-adv: filter ARP packets with invalid MAC addresses in DAT batman-adv: check for more types of invalid IP addresses in DAT batman-adv: fix skb leak in batadv_dat_snoop_incoming_arp_reply() net: loopback: fix a dst refcounting issue virtio-net: reset virtqueue affinity when doing cpu hotplug virtio-net: split out clean affinity function virtio-net: fix the set affinity bug when CPU IDs are not consecutive can: pch_can: fix invalid error codes can: ti_hecc: fix invalid error codes can: c_can: fix invalid error codes r8169: remove the obsolete and incorrect AMD workaround ...
This commit is contained in:
commit
22f8379815
@ -2966,7 +2966,7 @@ S: Maintained
|
||||
F: drivers/net/ethernet/i825xx/eexpress.*
|
||||
|
||||
ETHERNET BRIDGE
|
||||
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||
M: Stephen Hemminger <stephen@networkplumber.org>
|
||||
L: bridge@lists.linux-foundation.org
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.linuxfoundation.org/en/Net:Bridge
|
||||
@ -4905,7 +4905,7 @@ S: Maintained
|
||||
|
||||
MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
|
||||
M: Mirko Lindner <mlindner@marvell.com>
|
||||
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||
M: Stephen Hemminger <stephen@networkplumber.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/marvell/sk*
|
||||
@ -5180,7 +5180,7 @@ S: Supported
|
||||
F: drivers/infiniband/hw/nes/
|
||||
|
||||
NETEM NETWORK EMULATOR
|
||||
M: Stephen Hemminger <shemminger@vyatta.com>
|
||||
M: Stephen Hemminger <stephen@networkplumber.org>
|
||||
L: netem@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
F: net/sched/sch_netem.c
|
||||
|
@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {
|
||||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||
{ USB_DEVICE(0x13d3, 0x3362) },
|
||||
{ USB_DEVICE(0x0CF3, 0xE004) },
|
||||
{ USB_DEVICE(0x0930, 0x0219) },
|
||||
{ USB_DEVICE(0x0489, 0xe057) },
|
||||
{ USB_DEVICE(0x13d3, 0x3393) },
|
||||
{ USB_DEVICE(0x0489, 0xe04e) },
|
||||
{ USB_DEVICE(0x0489, 0xe056) },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE02C) },
|
||||
@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
|
||||
|
@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
|
||||
|
@ -248,6 +248,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
|
||||
CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
|
||||
CAPIMSG_CONTROL(data));
|
||||
l -= 12;
|
||||
if (l <= 0)
|
||||
return;
|
||||
dbgline = kmalloc(3 * l, GFP_ATOMIC);
|
||||
if (!dbgline)
|
||||
return;
|
||||
|
@ -960,7 +960,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
|
||||
break;
|
||||
case LEC_ACK_ERROR:
|
||||
netdev_dbg(dev, "ack error\n");
|
||||
cf->data[2] |= (CAN_ERR_PROT_LOC_ACK |
|
||||
cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
|
||||
CAN_ERR_PROT_LOC_ACK_DEL);
|
||||
break;
|
||||
case LEC_BIT1_ERROR:
|
||||
@ -973,7 +973,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
|
||||
break;
|
||||
case LEC_CRC_ERROR:
|
||||
netdev_dbg(dev, "CRC error\n");
|
||||
cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
CAN_ERR_PROT_LOC_CRC_DEL);
|
||||
break;
|
||||
default:
|
||||
|
@ -560,7 +560,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
|
||||
stats->rx_errors++;
|
||||
break;
|
||||
case PCH_CRC_ERR:
|
||||
cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
CAN_ERR_PROT_LOC_CRC_DEL;
|
||||
priv->can.can_stats.bus_error++;
|
||||
stats->rx_errors++;
|
||||
|
@ -746,12 +746,12 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
|
||||
}
|
||||
if (err_status & HECC_CANES_CRCE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
|
||||
cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
|
||||
CAN_ERR_PROT_LOC_CRC_DEL;
|
||||
}
|
||||
if (err_status & HECC_CANES_ACKE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
|
||||
cf->data[2] |= CAN_ERR_PROT_LOC_ACK |
|
||||
cf->data[3] |= CAN_ERR_PROT_LOC_ACK |
|
||||
CAN_ERR_PROT_LOC_ACK_DEL;
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ static int tc574_config(struct pcmcia_device *link)
|
||||
netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",
|
||||
cardname, dev->base_addr, dev->irq, dev->dev_addr);
|
||||
netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
|
||||
8 << config & Ram_size,
|
||||
8 << (config & Ram_size),
|
||||
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||
config & Autoselect ? "autoselect " : "");
|
||||
|
||||
|
@ -1283,14 +1283,26 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)
|
||||
return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);
|
||||
}
|
||||
|
||||
#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \
|
||||
tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
|
||||
MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \
|
||||
MII_TG3_AUXCTL_ACTL_TX_6DB)
|
||||
static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable)
|
||||
{
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \
|
||||
tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
|
||||
MII_TG3_AUXCTL_ACTL_TX_6DB);
|
||||
err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
if (enable)
|
||||
|
||||
val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
|
||||
else
|
||||
val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
|
||||
|
||||
err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL,
|
||||
val | MII_TG3_AUXCTL_ACTL_TX_6DB);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tg3_bmcr_reset(struct tg3 *tp)
|
||||
{
|
||||
@ -2223,7 +2235,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
|
||||
|
||||
otp = tp->phy_otp;
|
||||
|
||||
if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp))
|
||||
if (tg3_phy_toggle_auxctl_smdsp(tp, true))
|
||||
return;
|
||||
|
||||
phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
|
||||
@ -2248,7 +2260,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
|
||||
((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
|
||||
tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
|
||||
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
|
||||
static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
|
||||
@ -2284,9 +2296,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
|
||||
|
||||
if (!tp->setlpicnt) {
|
||||
if (current_link_up == 1 &&
|
||||
!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
|
||||
!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
|
||||
tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
|
||||
val = tr32(TG3_CPMU_EEE_MODE);
|
||||
@ -2302,11 +2314,11 @@ static void tg3_phy_eee_enable(struct tg3 *tp)
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
|
||||
tg3_flag(tp, 57765_CLASS)) &&
|
||||
!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
|
||||
!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
|
||||
val = MII_TG3_DSP_TAP26_ALNOKO |
|
||||
MII_TG3_DSP_TAP26_RMRXSTO;
|
||||
tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
|
||||
val = tr32(TG3_CPMU_EEE_MODE);
|
||||
@ -2450,7 +2462,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
|
||||
tg3_writephy(tp, MII_CTRL1000,
|
||||
CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
|
||||
|
||||
err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
|
||||
err = tg3_phy_toggle_auxctl_smdsp(tp, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -2471,7 +2483,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
|
||||
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
|
||||
tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
|
||||
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
|
||||
tg3_writephy(tp, MII_CTRL1000, phy9_orig);
|
||||
|
||||
@ -2572,10 +2584,10 @@ static int tg3_phy_reset(struct tg3 *tp)
|
||||
|
||||
out:
|
||||
if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) &&
|
||||
!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
|
||||
!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
|
||||
tg3_phydsp_write(tp, 0x201f, 0x2aaa);
|
||||
tg3_phydsp_write(tp, 0x000a, 0x0323);
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
|
||||
if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
|
||||
@ -2584,14 +2596,14 @@ out:
|
||||
}
|
||||
|
||||
if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
|
||||
if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
|
||||
if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
|
||||
tg3_phydsp_write(tp, 0x000a, 0x310b);
|
||||
tg3_phydsp_write(tp, 0x201f, 0x9506);
|
||||
tg3_phydsp_write(tp, 0x401f, 0x14e2);
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
} else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
|
||||
if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
|
||||
if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
|
||||
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
|
||||
if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
|
||||
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
|
||||
@ -2600,7 +2612,7 @@ out:
|
||||
} else
|
||||
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
|
||||
|
||||
TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4009,7 +4021,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
|
||||
tw32(TG3_CPMU_EEE_MODE,
|
||||
tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
|
||||
|
||||
err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
|
||||
err = tg3_phy_toggle_auxctl_smdsp(tp, true);
|
||||
if (!err) {
|
||||
u32 err2;
|
||||
|
||||
@ -4042,7 +4054,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
|
||||
MII_TG3_DSP_CH34TP2_HIBW01);
|
||||
}
|
||||
|
||||
err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
|
||||
err2 = tg3_phy_toggle_auxctl_smdsp(tp, false);
|
||||
if (!err)
|
||||
err = err2;
|
||||
}
|
||||
@ -6950,6 +6962,9 @@ static void tg3_poll_controller(struct net_device *dev)
|
||||
int i;
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
|
||||
if (tg3_irq_sync(tp))
|
||||
return;
|
||||
|
||||
for (i = 0; i < tp->irq_cnt; i++)
|
||||
tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
|
||||
}
|
||||
@ -16367,6 +16382,7 @@ static int tg3_init_one(struct pci_dev *pdev,
|
||||
tp->pm_cap = pm_cap;
|
||||
tp->rx_mode = TG3_DEF_RX_MODE;
|
||||
tp->tx_mode = TG3_DEF_TX_MODE;
|
||||
tp->irq_sync = 1;
|
||||
|
||||
if (tg3_debug > 0)
|
||||
tp->msg_enable = tg3_debug;
|
||||
|
@ -548,6 +548,10 @@ static int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All frames should fit into a single buffer */
|
||||
if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG))
|
||||
return -1;
|
||||
|
||||
/* Check if packet has checksum already */
|
||||
if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) &&
|
||||
!(ext_status & RXDESC_IP_PAYLOAD_MASK))
|
||||
|
@ -1994,9 +1994,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
|
||||
{
|
||||
const struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adap = pi->adapter;
|
||||
struct sge_rspq *q;
|
||||
int i;
|
||||
int r = 0;
|
||||
|
||||
return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq,
|
||||
c->rx_coalesce_usecs, c->rx_max_coalesced_frames);
|
||||
for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) {
|
||||
q = &adap->sge.ethrxq[i].rspq;
|
||||
r = set_rxq_intr_params(adap, q, c->rx_coalesce_usecs,
|
||||
c->rx_max_coalesced_frames);
|
||||
if (r) {
|
||||
dev_err(&dev->dev, "failed to set coalesce %d\n", r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
obj-$(CONFIG_IXGBE) += ixgbe.o
|
||||
|
||||
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\
|
||||
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
|
||||
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
|
||||
ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o
|
||||
|
||||
@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
|
||||
ixgbe_dcb_82599.o ixgbe_dcb_nl.o
|
||||
|
||||
ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o
|
||||
ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o
|
||||
ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
|
||||
|
@ -24,9 +24,6 @@
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void)
|
||||
{
|
||||
debugfs_remove_recursive(ixgbe_dbg_root);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
@ -660,11 +660,11 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
|
||||
tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG;
|
||||
tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
|
||||
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
|
||||
tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
|
||||
tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||
|
@ -630,10 +630,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
ring->tx_csum++;
|
||||
}
|
||||
|
||||
/* Copy dst mac address to wqe */
|
||||
ethh = (struct ethhdr *)skb->data;
|
||||
tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest);
|
||||
tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2));
|
||||
if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) {
|
||||
/* Copy dst mac address to wqe. This allows loopback in eSwitch,
|
||||
* so that VFs and PF can communicate with each other
|
||||
*/
|
||||
ethh = (struct ethhdr *)skb->data;
|
||||
tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest);
|
||||
tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2));
|
||||
}
|
||||
|
||||
/* Handle LSO (TSO) packets */
|
||||
if (lso_header_size) {
|
||||
/* Mark opcode as LSO */
|
||||
|
@ -1790,15 +1790,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
|
||||
int i;
|
||||
|
||||
if (msi_x) {
|
||||
/* In multifunction mode each function gets 2 msi-X vectors
|
||||
* one for data path completions anf the other for asynch events
|
||||
* or command completions */
|
||||
if (mlx4_is_mfunc(dev)) {
|
||||
nreq = 2;
|
||||
} else {
|
||||
nreq = min_t(int, dev->caps.num_eqs -
|
||||
dev->caps.reserved_eqs, nreq);
|
||||
}
|
||||
nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
|
||||
nreq);
|
||||
|
||||
entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
|
||||
if (!entries)
|
||||
|
@ -144,7 +144,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
|
||||
buffrag->length, PCI_DMA_TODEVICE);
|
||||
buffrag->dma = 0ULL;
|
||||
}
|
||||
for (j = 0; j < cmd_buf->frag_count; j++) {
|
||||
for (j = 1; j < cmd_buf->frag_count; j++) {
|
||||
buffrag++;
|
||||
if (buffrag->dma) {
|
||||
pci_unmap_page(adapter->pdev, buffrag->dma,
|
||||
|
@ -1963,10 +1963,12 @@ unwind:
|
||||
while (--i >= 0) {
|
||||
nf = &pbuf->frag_array[i+1];
|
||||
pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
|
||||
nf->dma = 0ULL;
|
||||
}
|
||||
|
||||
nf = &pbuf->frag_array[0];
|
||||
pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
|
||||
nf->dma = 0ULL;
|
||||
|
||||
out_err:
|
||||
return -ENOMEM;
|
||||
|
@ -1826,8 +1826,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
|
||||
|
||||
if (opts2 & RxVlanTag)
|
||||
__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
|
||||
|
||||
desc->opts2 = 0;
|
||||
}
|
||||
|
||||
static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
@ -6064,8 +6062,6 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget
|
||||
!(status & (RxRWT | RxFOVF)) &&
|
||||
(dev->features & NETIF_F_RXALL))
|
||||
goto process_pkt;
|
||||
|
||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||
} else {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t addr;
|
||||
@ -6086,16 +6082,14 @@ process_pkt:
|
||||
if (unlikely(rtl8169_fragmented_frame(status))) {
|
||||
dev->stats.rx_dropped++;
|
||||
dev->stats.rx_length_errors++;
|
||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||
continue;
|
||||
goto release_descriptor;
|
||||
}
|
||||
|
||||
skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],
|
||||
tp, pkt_size, addr);
|
||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||
if (!skb) {
|
||||
dev->stats.rx_dropped++;
|
||||
continue;
|
||||
goto release_descriptor;
|
||||
}
|
||||
|
||||
rtl8169_rx_csum(skb, status);
|
||||
@ -6111,13 +6105,10 @@ process_pkt:
|
||||
tp->rx_stats.bytes += pkt_size;
|
||||
u64_stats_update_end(&tp->rx_stats.syncp);
|
||||
}
|
||||
|
||||
/* Work around for AMD plateform. */
|
||||
if ((desc->opts2 & cpu_to_le32(0xfffe000)) &&
|
||||
(tp->mac_version == RTL_GIGA_MAC_VER_05)) {
|
||||
desc->opts2 = 0;
|
||||
cur_rx++;
|
||||
}
|
||||
release_descriptor:
|
||||
desc->opts2 = 0;
|
||||
wmb();
|
||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||
}
|
||||
|
||||
count = cur_rx - tp->cur_rx;
|
||||
|
@ -84,7 +84,7 @@ struct hv_netvsc_packet {
|
||||
};
|
||||
|
||||
struct netvsc_device_info {
|
||||
unsigned char mac_adr[6];
|
||||
unsigned char mac_adr[ETH_ALEN];
|
||||
bool link_state; /* 0 - link up, 1 - link down */
|
||||
int ring_size;
|
||||
};
|
||||
|
@ -349,7 +349,7 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
|
||||
struct net_device_context *ndevctx = netdev_priv(ndev);
|
||||
struct hv_device *hdev = ndevctx->device_ctx;
|
||||
struct sockaddr *addr = p;
|
||||
char save_adr[14];
|
||||
char save_adr[ETH_ALEN];
|
||||
unsigned char save_aatype;
|
||||
int err;
|
||||
|
||||
|
@ -77,6 +77,11 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
|
||||
|
||||
skb_orphan(skb);
|
||||
|
||||
/* Before queueing this packet to netif_rx(),
|
||||
* make sure dst is refcounted.
|
||||
*/
|
||||
skb_dst_force(skb);
|
||||
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
/* it's OK to use per_cpu_ptr() because BHs are off */
|
||||
|
@ -822,7 +822,10 @@ static int macvlan_changelink(struct net_device *dev,
|
||||
|
||||
static size_t macvlan_get_size(const struct net_device *dev)
|
||||
{
|
||||
return nla_total_size(4);
|
||||
return (0
|
||||
+ nla_total_size(4) /* IFLA_MACVLAN_MODE */
|
||||
+ nla_total_size(2) /* IFLA_MACVLAN_FLAGS */
|
||||
);
|
||||
}
|
||||
|
||||
static int macvlan_fill_info(struct sk_buff *skb,
|
||||
|
@ -36,8 +36,9 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
/* IP101A/G - IP1001 */
|
||||
#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
|
||||
#define IP1001_RXPHASE_SEL (1<<0) /* Add delay on RX_CLK */
|
||||
#define IP1001_TXPHASE_SEL (1<<1) /* Add delay on TX_CLK */
|
||||
#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
|
||||
#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
|
||||
#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
|
||||
#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */
|
||||
#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */
|
||||
@ -138,19 +139,24 @@ static int ip1001_config_init(struct phy_device *phydev)
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
/* INTR pin used: speed/link/duplex will cause an interrupt */
|
||||
c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
|
||||
if (c < 0)
|
||||
return c;
|
||||
if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
|
||||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
|
||||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
|
||||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
|
||||
/* Additional delay (2ns) used to adjust RX clock phase
|
||||
* at RGMII interface */
|
||||
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
c |= IP1001_PHASE_SEL_MASK;
|
||||
c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
||||
c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
|
||||
else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
||||
c |= IP1001_RXPHASE_SEL;
|
||||
else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
||||
c |= IP1001_TXPHASE_SEL;
|
||||
|
||||
c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
|
||||
if (c < 0)
|
||||
return c;
|
||||
@ -167,6 +173,11 @@ static int ip101a_g_config_init(struct phy_device *phydev)
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
/* INTR pin used: speed/link/duplex will cause an interrupt */
|
||||
c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
/* Enable Auto Power Saving mode */
|
||||
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
|
||||
c |= IP101A_G_APS_ON;
|
||||
|
@ -353,15 +353,6 @@ static int m88e1111_config_init(struct phy_device *phydev)
|
||||
int err;
|
||||
int temp;
|
||||
|
||||
/* Enable Fiber/Copper auto selection */
|
||||
temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
|
||||
temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO;
|
||||
phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
|
||||
|
||||
temp = phy_read(phydev, MII_BMCR);
|
||||
temp |= BMCR_RESET;
|
||||
phy_write(phydev, MII_BMCR, temp);
|
||||
|
||||
if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
|
||||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
|
||||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
|
||||
|
@ -109,11 +109,11 @@ struct tap_filter {
|
||||
unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
|
||||
};
|
||||
|
||||
/* 1024 is probably a high enough limit: modern hypervisors seem to support on
|
||||
* the order of 100-200 CPUs so this leaves us some breathing space if we want
|
||||
* to match a queue per guest CPU.
|
||||
*/
|
||||
#define MAX_TAP_QUEUES 1024
|
||||
/* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for
|
||||
* the netdevice to be fit in one page. So we can make sure the success of
|
||||
* memory allocation. TODO: increase the limit. */
|
||||
#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES
|
||||
#define MAX_TAP_FLOWS 4096
|
||||
|
||||
#define TUN_FLOW_EXPIRE (3 * HZ)
|
||||
|
||||
@ -185,6 +185,8 @@ struct tun_struct {
|
||||
unsigned long ageing_time;
|
||||
unsigned int numdisabled;
|
||||
struct list_head disabled;
|
||||
void *security;
|
||||
u32 flow_count;
|
||||
};
|
||||
|
||||
static inline u32 tun_hashfn(u32 rxhash)
|
||||
@ -218,6 +220,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,
|
||||
e->queue_index = queue_index;
|
||||
e->tun = tun;
|
||||
hlist_add_head_rcu(&e->hash_link, head);
|
||||
++tun->flow_count;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@ -228,6 +231,7 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)
|
||||
e->rxhash, e->queue_index);
|
||||
hlist_del_rcu(&e->hash_link);
|
||||
kfree_rcu(e, rcu);
|
||||
--tun->flow_count;
|
||||
}
|
||||
|
||||
static void tun_flow_flush(struct tun_struct *tun)
|
||||
@ -317,7 +321,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
|
||||
e->updated = jiffies;
|
||||
} else {
|
||||
spin_lock_bh(&tun->lock);
|
||||
if (!tun_flow_find(head, rxhash))
|
||||
if (!tun_flow_find(head, rxhash) &&
|
||||
tun->flow_count < MAX_TAP_FLOWS)
|
||||
tun_flow_create(tun, head, rxhash, queue_index);
|
||||
|
||||
if (!timer_pending(&tun->flow_gc_timer))
|
||||
@ -490,6 +495,10 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
|
||||
struct tun_file *tfile = file->private_data;
|
||||
int err;
|
||||
|
||||
err = security_tun_dev_attach(tfile->socket.sk, tun->security);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
err = -EINVAL;
|
||||
if (rtnl_dereference(tfile->tun))
|
||||
goto out;
|
||||
@ -1373,6 +1382,7 @@ static void tun_free_netdev(struct net_device *dev)
|
||||
|
||||
BUG_ON(!(list_empty(&tun->disabled)));
|
||||
tun_flow_uninit(tun);
|
||||
security_tun_dev_free_security(tun->security);
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
||||
@ -1562,7 +1572,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
|
||||
if (tun_not_capable(tun))
|
||||
return -EPERM;
|
||||
err = security_tun_dev_attach(tfile->socket.sk);
|
||||
err = security_tun_dev_open(tun->security);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -1577,6 +1587,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
else {
|
||||
char *name;
|
||||
unsigned long flags = 0;
|
||||
int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
|
||||
MAX_TAP_QUEUES : 1;
|
||||
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
@ -1600,8 +1612,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
name = ifr->ifr_name;
|
||||
|
||||
dev = alloc_netdev_mqs(sizeof(struct tun_struct), name,
|
||||
tun_setup,
|
||||
MAX_TAP_QUEUES, MAX_TAP_QUEUES);
|
||||
tun_setup, queues, queues);
|
||||
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1619,7 +1631,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
|
||||
spin_lock_init(&tun->lock);
|
||||
|
||||
security_tun_dev_post_create(&tfile->sk);
|
||||
err = security_tun_dev_alloc_security(&tun->security);
|
||||
if (err < 0)
|
||||
goto err_free_dev;
|
||||
|
||||
tun_net_init(dev);
|
||||
|
||||
@ -1789,10 +1803,14 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
|
||||
|
||||
if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {
|
||||
tun = tfile->detached;
|
||||
if (!tun)
|
||||
if (!tun) {
|
||||
ret = -EINVAL;
|
||||
else
|
||||
ret = tun_attach(tun, file);
|
||||
goto unlock;
|
||||
}
|
||||
ret = security_tun_dev_attach_queue(tun->security);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
ret = tun_attach(tun, file);
|
||||
} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
|
||||
tun = rtnl_dereference(tfile->tun);
|
||||
if (!tun || !(tun->flags & TUN_TAP_MQ))
|
||||
@ -1802,6 +1820,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
|
||||
} else
|
||||
ret = -EINVAL;
|
||||
|
||||
unlock:
|
||||
rtnl_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
@ -374,6 +374,21 @@ static const struct driver_info cdc_mbim_info = {
|
||||
.tx_fixup = cdc_mbim_tx_fixup,
|
||||
};
|
||||
|
||||
/* MBIM and NCM devices should not need a ZLP after NTBs with
|
||||
* dwNtbOutMaxSize length. This driver_info is for the exceptional
|
||||
* devices requiring it anyway, allowing them to be supported without
|
||||
* forcing the performance penalty on all the sane devices.
|
||||
*/
|
||||
static const struct driver_info cdc_mbim_info_zlp = {
|
||||
.description = "CDC MBIM",
|
||||
.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
|
||||
.bind = cdc_mbim_bind,
|
||||
.unbind = cdc_mbim_unbind,
|
||||
.manage_power = cdc_mbim_manage_power,
|
||||
.rx_fixup = cdc_mbim_rx_fixup,
|
||||
.tx_fixup = cdc_mbim_tx_fixup,
|
||||
};
|
||||
|
||||
static const struct usb_device_id mbim_devs[] = {
|
||||
/* This duplicate NCM entry is intentional. MBIM devices can
|
||||
* be disguised as NCM by default, and this is necessary to
|
||||
@ -385,6 +400,10 @@ static const struct usb_device_id mbim_devs[] = {
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&cdc_mbim_info,
|
||||
},
|
||||
/* Sierra Wireless MC7710 need ZLPs */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&cdc_mbim_info_zlp,
|
||||
},
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&cdc_mbim_info,
|
||||
},
|
||||
|
@ -435,6 +435,13 @@ advance:
|
||||
len -= temp;
|
||||
}
|
||||
|
||||
/* some buggy devices have an IAD but no CDC Union */
|
||||
if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) {
|
||||
ctx->control = intf;
|
||||
ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1);
|
||||
dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n");
|
||||
}
|
||||
|
||||
/* check if we got everything */
|
||||
if ((ctx->control == NULL) || (ctx->data == NULL) ||
|
||||
((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf))))
|
||||
@ -497,7 +504,8 @@ advance:
|
||||
error2:
|
||||
usb_set_intfdata(ctx->control, NULL);
|
||||
usb_set_intfdata(ctx->data, NULL);
|
||||
usb_driver_release_interface(driver, ctx->data);
|
||||
if (ctx->data != ctx->control)
|
||||
usb_driver_release_interface(driver, ctx->data);
|
||||
error:
|
||||
cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
|
||||
dev->data[0] = 0;
|
||||
@ -1155,6 +1163,20 @@ static const struct driver_info wwan_info = {
|
||||
.tx_fixup = cdc_ncm_tx_fixup,
|
||||
};
|
||||
|
||||
/* Same as wwan_info, but with FLAG_NOARP */
|
||||
static const struct driver_info wwan_noarp_info = {
|
||||
.description = "Mobile Broadband Network Device (NO ARP)",
|
||||
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
|
||||
| FLAG_WWAN | FLAG_NOARP,
|
||||
.bind = cdc_ncm_bind,
|
||||
.unbind = cdc_ncm_unbind,
|
||||
.check_connect = cdc_ncm_check_connect,
|
||||
.manage_power = usbnet_manage_power,
|
||||
.status = cdc_ncm_status,
|
||||
.rx_fixup = cdc_ncm_rx_fixup,
|
||||
.tx_fixup = cdc_ncm_tx_fixup,
|
||||
};
|
||||
|
||||
static const struct usb_device_id cdc_devs[] = {
|
||||
/* Ericsson MBM devices like F5521gw */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
@ -1194,6 +1216,13 @@ static const struct usb_device_id cdc_devs[] = {
|
||||
.driver_info = (unsigned long)&wwan_info,
|
||||
},
|
||||
|
||||
/* Infineon(now Intel) HSPA Modem platform */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443,
|
||||
USB_CLASS_COMM,
|
||||
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&wwan_noarp_info,
|
||||
},
|
||||
|
||||
/* Generic CDC-NCM devices */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
|
||||
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
|
||||
|
@ -45,6 +45,12 @@
|
||||
#define DM_MCAST_ADDR 0x16 /* 8 bytes */
|
||||
#define DM_GPR_CTRL 0x1e
|
||||
#define DM_GPR_DATA 0x1f
|
||||
#define DM_CHIP_ID 0x2c
|
||||
#define DM_MODE_CTRL 0x91 /* only on dm9620 */
|
||||
|
||||
/* chip id values */
|
||||
#define ID_DM9601 0
|
||||
#define ID_DM9620 1
|
||||
|
||||
#define DM_MAX_MCAST 64
|
||||
#define DM_MCAST_SIZE 8
|
||||
@ -53,7 +59,6 @@
|
||||
#define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */
|
||||
#define DM_TIMEOUT 1000
|
||||
|
||||
|
||||
static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
{
|
||||
int err;
|
||||
@ -84,32 +89,23 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
|
||||
static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
|
||||
{
|
||||
return usbnet_write_cmd(dev, DM_WRITE_REGS,
|
||||
return usbnet_write_cmd(dev, DM_WRITE_REG,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value, reg, NULL, 0);
|
||||
}
|
||||
|
||||
static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
|
||||
u16 length, void *data)
|
||||
static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
{
|
||||
usbnet_write_cmd_async(dev, DM_WRITE_REGS,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value, reg, data, length);
|
||||
}
|
||||
|
||||
static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
{
|
||||
netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length);
|
||||
|
||||
dm_write_async_helper(dev, reg, 0, length, data);
|
||||
0, reg, data, length);
|
||||
}
|
||||
|
||||
static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
|
||||
{
|
||||
netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n",
|
||||
reg, value);
|
||||
|
||||
dm_write_async_helper(dev, reg, value, 0, NULL);
|
||||
usbnet_write_cmd_async(dev, DM_WRITE_REG,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value, reg, NULL, 0);
|
||||
}
|
||||
|
||||
static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
|
||||
@ -358,7 +354,7 @@ static const struct net_device_ops dm9601_netdev_ops = {
|
||||
static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
{
|
||||
int ret;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 mac[ETH_ALEN], id;
|
||||
|
||||
ret = usbnet_get_endpoints(dev, intf);
|
||||
if (ret)
|
||||
@ -399,6 +395,24 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
__dm9601_set_mac_address(dev);
|
||||
}
|
||||
|
||||
if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) {
|
||||
netdev_err(dev->net, "Error reading chip ID\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* put dm9620 devices in dm9601 mode */
|
||||
if (id == ID_DM9620) {
|
||||
u8 mode;
|
||||
|
||||
if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) {
|
||||
netdev_err(dev->net, "Error reading MODE_CTRL\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f);
|
||||
}
|
||||
|
||||
/* power up phy */
|
||||
dm_write_reg(dev, DM_GPR_CTRL, 1);
|
||||
dm_write_reg(dev, DM_GPR_DATA, 0);
|
||||
@ -581,6 +595,10 @@ static const struct usb_device_id products[] = {
|
||||
USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
|
||||
.driver_info = (unsigned long)&dm9601_info,
|
||||
},
|
||||
{
|
||||
USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */
|
||||
.driver_info = (unsigned long)&dm9601_info,
|
||||
},
|
||||
{}, // END
|
||||
};
|
||||
|
||||
|
@ -433,6 +433,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0257, 3)}, /* ZTE MF821 */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0265, 4)}, /* ONDA MT8205 4G LTE */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0284, 4)}, /* ZTE MF880 */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */
|
||||
@ -459,6 +460,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */
|
||||
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
|
||||
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
|
||||
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
|
||||
|
||||
/* 4. Gobi 1000 devices */
|
||||
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
|
@ -1448,6 +1448,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
||||
if ((dev->driver_info->flags & FLAG_WWAN) != 0)
|
||||
strcpy(net->name, "wwan%d");
|
||||
|
||||
/* devices that cannot do ARP */
|
||||
if ((dev->driver_info->flags & FLAG_NOARP) != 0)
|
||||
net->flags |= IFF_NOARP;
|
||||
|
||||
/* maybe the remote can't receive an Ethernet MTU */
|
||||
if (net->mtu > (dev->hard_mtu - net->hard_header_len))
|
||||
net->mtu = dev->hard_mtu - net->hard_header_len;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
static int napi_weight = 128;
|
||||
module_param(napi_weight, int, 0444);
|
||||
@ -123,6 +124,12 @@ struct virtnet_info {
|
||||
|
||||
/* Does the affinity hint is set for virtqueues? */
|
||||
bool affinity_hint_set;
|
||||
|
||||
/* Per-cpu variable to show the mapping from CPU to virtqueue */
|
||||
int __percpu *vq_index;
|
||||
|
||||
/* CPU hot plug notifier */
|
||||
struct notifier_block nb;
|
||||
};
|
||||
|
||||
struct skb_vnet_hdr {
|
||||
@ -1013,32 +1020,75 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
|
||||
static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu)
|
||||
{
|
||||
int i;
|
||||
int cpu;
|
||||
|
||||
if (vi->affinity_hint_set) {
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
virtqueue_set_affinity(vi->rq[i].vq, -1);
|
||||
virtqueue_set_affinity(vi->sq[i].vq, -1);
|
||||
}
|
||||
|
||||
vi->affinity_hint_set = false;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == hcpu) {
|
||||
*per_cpu_ptr(vi->vq_index, cpu) = -1;
|
||||
} else {
|
||||
*per_cpu_ptr(vi->vq_index, cpu) =
|
||||
++i % vi->curr_queue_pairs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void virtnet_set_affinity(struct virtnet_info *vi)
|
||||
{
|
||||
int i;
|
||||
int cpu;
|
||||
|
||||
/* In multiqueue mode, when the number of cpu is equal to the number of
|
||||
* queue pairs, we let the queue pairs to be private to one cpu by
|
||||
* setting the affinity hint to eliminate the contention.
|
||||
*/
|
||||
if ((vi->curr_queue_pairs == 1 ||
|
||||
vi->max_queue_pairs != num_online_cpus()) && set) {
|
||||
if (vi->affinity_hint_set)
|
||||
set = false;
|
||||
else
|
||||
return;
|
||||
if (vi->curr_queue_pairs == 1 ||
|
||||
vi->max_queue_pairs != num_online_cpus()) {
|
||||
virtnet_clean_affinity(vi, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
int cpu = set ? i : -1;
|
||||
i = 0;
|
||||
for_each_online_cpu(cpu) {
|
||||
virtqueue_set_affinity(vi->rq[i].vq, cpu);
|
||||
virtqueue_set_affinity(vi->sq[i].vq, cpu);
|
||||
*per_cpu_ptr(vi->vq_index, cpu) = i;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (set)
|
||||
vi->affinity_hint_set = true;
|
||||
else
|
||||
vi->affinity_hint_set = false;
|
||||
vi->affinity_hint_set = true;
|
||||
}
|
||||
|
||||
static int virtnet_cpu_callback(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
|
||||
|
||||
switch(action & ~CPU_TASKS_FROZEN) {
|
||||
case CPU_ONLINE:
|
||||
case CPU_DOWN_FAILED:
|
||||
case CPU_DEAD:
|
||||
virtnet_set_affinity(vi);
|
||||
break;
|
||||
case CPU_DOWN_PREPARE:
|
||||
virtnet_clean_affinity(vi, (long)hcpu);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static void virtnet_get_ringparam(struct net_device *dev,
|
||||
@ -1082,13 +1132,15 @@ static int virtnet_set_channels(struct net_device *dev,
|
||||
if (queue_pairs > vi->max_queue_pairs)
|
||||
return -EINVAL;
|
||||
|
||||
get_online_cpus();
|
||||
err = virtnet_set_queues(vi, queue_pairs);
|
||||
if (!err) {
|
||||
netif_set_real_num_tx_queues(dev, queue_pairs);
|
||||
netif_set_real_num_rx_queues(dev, queue_pairs);
|
||||
|
||||
virtnet_set_affinity(vi, true);
|
||||
virtnet_set_affinity(vi);
|
||||
}
|
||||
put_online_cpus();
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -1127,12 +1179,19 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
||||
/* To avoid contending a lock hold by a vcpu who would exit to host, select the
|
||||
* txq based on the processor id.
|
||||
* TODO: handle cpu hotplug.
|
||||
*/
|
||||
static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) :
|
||||
smp_processor_id();
|
||||
int txq;
|
||||
struct virtnet_info *vi = netdev_priv(dev);
|
||||
|
||||
if (skb_rx_queue_recorded(skb)) {
|
||||
txq = skb_get_rx_queue(skb);
|
||||
} else {
|
||||
txq = *__this_cpu_ptr(vi->vq_index);
|
||||
if (txq == -1)
|
||||
txq = 0;
|
||||
}
|
||||
|
||||
while (unlikely(txq >= dev->real_num_tx_queues))
|
||||
txq -= dev->real_num_tx_queues;
|
||||
@ -1248,7 +1307,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi)
|
||||
{
|
||||
struct virtio_device *vdev = vi->vdev;
|
||||
|
||||
virtnet_set_affinity(vi, false);
|
||||
virtnet_clean_affinity(vi, -1);
|
||||
|
||||
vdev->config->del_vqs(vdev);
|
||||
|
||||
@ -1371,7 +1430,10 @@ static int init_vqs(struct virtnet_info *vi)
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
virtnet_set_affinity(vi, true);
|
||||
get_online_cpus();
|
||||
virtnet_set_affinity(vi);
|
||||
put_online_cpus();
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
@ -1453,6 +1515,10 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
if (vi->stats == NULL)
|
||||
goto free;
|
||||
|
||||
vi->vq_index = alloc_percpu(int);
|
||||
if (vi->vq_index == NULL)
|
||||
goto free_stats;
|
||||
|
||||
mutex_init(&vi->config_lock);
|
||||
vi->config_enable = true;
|
||||
INIT_WORK(&vi->config_work, virtnet_config_changed_work);
|
||||
@ -1476,7 +1542,7 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
/* Allocate/initialize the rx/tx queues, and invoke find_vqs */
|
||||
err = init_vqs(vi);
|
||||
if (err)
|
||||
goto free_stats;
|
||||
goto free_index;
|
||||
|
||||
netif_set_real_num_tx_queues(dev, 1);
|
||||
netif_set_real_num_rx_queues(dev, 1);
|
||||
@ -1499,6 +1565,13 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
}
|
||||
}
|
||||
|
||||
vi->nb.notifier_call = &virtnet_cpu_callback;
|
||||
err = register_hotcpu_notifier(&vi->nb);
|
||||
if (err) {
|
||||
pr_debug("virtio_net: registering cpu notifier failed\n");
|
||||
goto free_recv_bufs;
|
||||
}
|
||||
|
||||
/* Assume link up if device can't report link status,
|
||||
otherwise get link status from config. */
|
||||
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
|
||||
@ -1520,6 +1593,8 @@ free_recv_bufs:
|
||||
free_vqs:
|
||||
cancel_delayed_work_sync(&vi->refill);
|
||||
virtnet_del_vqs(vi);
|
||||
free_index:
|
||||
free_percpu(vi->vq_index);
|
||||
free_stats:
|
||||
free_percpu(vi->stats);
|
||||
free:
|
||||
@ -1543,6 +1618,8 @@ static void virtnet_remove(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtnet_info *vi = vdev->priv;
|
||||
|
||||
unregister_hotcpu_notifier(&vi->nb);
|
||||
|
||||
/* Prevent config work handler from accessing the device. */
|
||||
mutex_lock(&vi->config_lock);
|
||||
vi->config_enable = false;
|
||||
@ -1554,6 +1631,7 @@ static void virtnet_remove(struct virtio_device *vdev)
|
||||
|
||||
flush_work(&vi->config_work);
|
||||
|
||||
free_percpu(vi->vq_index);
|
||||
free_percpu(vi->stats);
|
||||
free_netdev(vi->dev);
|
||||
}
|
||||
|
@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
AR_PHY_CL_TAB_1,
|
||||
AR_PHY_CL_TAB_2 };
|
||||
|
||||
ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
|
||||
|
||||
if (rtt) {
|
||||
if (!ar9003_hw_rtt_restore(ah, chan))
|
||||
run_rtt_cal = true;
|
||||
|
@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
|
||||
ath9k_hw_synth_delay(ah, chan, synthDelay);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
|
||||
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
|
||||
{
|
||||
switch (rx) {
|
||||
case 0x5:
|
||||
if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
|
||||
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
|
||||
AR_PHY_SWAP_ALT_CHAIN);
|
||||
case 0x3:
|
||||
case 0x1:
|
||||
case 0x2:
|
||||
case 0x7:
|
||||
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
|
||||
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
|
||||
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
|
||||
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
|
||||
tx = 3;
|
||||
|
||||
if (tx == 0x5) {
|
||||
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
|
||||
AR_PHY_SWAP_ALT_CHAIN);
|
||||
}
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -317,7 +317,6 @@ struct ath_rx {
|
||||
u32 *rxlink;
|
||||
u32 num_pkts;
|
||||
unsigned int rxfilter;
|
||||
spinlock_t rxbuflock;
|
||||
struct list_head rxbuf;
|
||||
struct ath_descdma rxdma;
|
||||
struct ath_buf *rx_bufptr;
|
||||
@ -328,7 +327,6 @@ struct ath_rx {
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
|
||||
enum sc_op_flags {
|
||||
SC_OP_INVALID,
|
||||
SC_OP_BEACONS,
|
||||
SC_OP_RXFLUSH,
|
||||
SC_OP_ANI_RUN,
|
||||
SC_OP_PRIM_STA_VIF,
|
||||
SC_OP_HW_RESET,
|
||||
|
@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
|
||||
skb->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_buf_addr = 0;
|
||||
bf->bf_mpdu = NULL;
|
||||
}
|
||||
|
||||
skb = ieee80211_beacon_get(hw, vif);
|
||||
@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
return;
|
||||
|
||||
bf = ath9k_beacon_generate(sc->hw, vif);
|
||||
WARN_ON(!bf);
|
||||
|
||||
if (sc->beacon.bmisscnt != 0) {
|
||||
ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
|
||||
|
@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
|
||||
RXS_ERR("RX-LENGTH-ERR", rx_len_err);
|
||||
RXS_ERR("RX-OOM-ERR", rx_oom_err);
|
||||
RXS_ERR("RX-RATE-ERR", rx_rate_err);
|
||||
RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
|
||||
RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
|
||||
|
||||
PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
|
||||
|
@ -216,7 +216,6 @@ struct ath_tx_stats {
|
||||
* @rx_oom_err: No. of frames dropped due to OOM issues.
|
||||
* @rx_rate_err: No. of frames dropped due to rate errors.
|
||||
* @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
|
||||
* @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
|
||||
* @rx_beacons: No. of beacons received.
|
||||
* @rx_frags: No. of rx-fragements received.
|
||||
*/
|
||||
@ -235,7 +234,6 @@ struct ath_rx_stats {
|
||||
u32 rx_oom_err;
|
||||
u32 rx_rate_err;
|
||||
u32 rx_too_many_frags_err;
|
||||
u32 rx_drop_rxflush;
|
||||
u32 rx_beacons;
|
||||
u32 rx_frags;
|
||||
};
|
||||
|
@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
|
||||
endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
|
||||
skb, htc_hdr->endpoint_id,
|
||||
txok);
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
|
||||
int ar9003_paprd_init_table(struct ath_hw *ah);
|
||||
bool ar9003_paprd_is_done(struct ath_hw *ah);
|
||||
bool ar9003_is_paprd_enabled(struct ath_hw *ah);
|
||||
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
|
||||
|
||||
/* Hardware family op attach helpers */
|
||||
void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
|
||||
|
@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)
|
||||
ath_start_ani(sc);
|
||||
}
|
||||
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
bool ret = true;
|
||||
@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
||||
if (!ath_drain_all_txq(sc, retry_tx))
|
||||
ret = false;
|
||||
|
||||
if (!flush) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
} else {
|
||||
ath_flushrecv(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = NULL;
|
||||
bool fastcc = true;
|
||||
bool flush = false;
|
||||
int r;
|
||||
|
||||
__ath_cancel_work(sc);
|
||||
|
||||
tasklet_disable(&sc->intr_tq);
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
|
||||
@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
||||
|
||||
if (!hchan) {
|
||||
fastcc = false;
|
||||
flush = true;
|
||||
hchan = ah->curchan;
|
||||
}
|
||||
|
||||
if (!ath_prepare_reset(sc, retry_tx, flush))
|
||||
if (!ath_prepare_reset(sc, retry_tx))
|
||||
fastcc = false;
|
||||
|
||||
ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
|
||||
@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
tasklet_enable(&sc->intr_tq);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
|
||||
}
|
||||
|
||||
ath_prepare_reset(sc, false, true);
|
||||
ath_prepare_reset(sc, false);
|
||||
|
||||
if (sc->rx.frag) {
|
||||
dev_kfree_skb_any(sc->rx.frag);
|
||||
@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new)
|
||||
|
||||
static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
|
||||
{
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
return true;
|
||||
|
||||
switch (val & 0x7) {
|
||||
case 0x1:
|
||||
case 0x3:
|
||||
|
@ -254,8 +254,6 @@ rx_init_fail:
|
||||
|
||||
static void ath_edma_start_recv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
ath9k_hw_rxena(sc->sc_ah);
|
||||
|
||||
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
|
||||
@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
|
||||
ath_opmode_init(sc);
|
||||
|
||||
ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
}
|
||||
|
||||
static void ath_edma_stop_recv(struct ath_softc *sc)
|
||||
@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
int error = 0;
|
||||
|
||||
spin_lock_init(&sc->sc_pcu_lock);
|
||||
spin_lock_init(&sc->rx.rxbuflock);
|
||||
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
|
||||
common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
|
||||
sc->sc_ah->caps.rx_status_len;
|
||||
@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
|
||||
@ -468,26 +461,31 @@ start_recv:
|
||||
ath_opmode_init(sc);
|
||||
ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
}
|
||||
|
||||
bool ath_stoprecv(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
bool stopped, reset = false;
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
ath9k_hw_abortpcurecv(ah);
|
||||
ath9k_hw_setrxfilter(ah, 0);
|
||||
stopped = ath9k_hw_stopdmarecv(ah, &reset);
|
||||
|
||||
ath_flushrecv(sc);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_edma_stop_recv(sc);
|
||||
else
|
||||
sc->rx.rxlink = NULL;
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
if (!(ah->ah_flags & AH_UNPLUGGED) &&
|
||||
unlikely(!stopped)) {
|
||||
@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
|
||||
return stopped && !reset;
|
||||
}
|
||||
|
||||
void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
}
|
||||
|
||||
static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
|
||||
{
|
||||
/* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
|
||||
@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_del(&bf->list);
|
||||
if (!bf->bf_mpdu)
|
||||
return bf;
|
||||
|
||||
@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
dma_type = DMA_FROM_DEVICE;
|
||||
|
||||
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
tsf_lower = tsf & 0xffffffff;
|
||||
|
||||
do {
|
||||
bool decrypt_error = false;
|
||||
/* If handling rx interrupt and flush is in progress => exit */
|
||||
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
|
||||
break;
|
||||
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
if (edma)
|
||||
@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
|
||||
ath_debug_stat_rx(sc, &rs);
|
||||
|
||||
/*
|
||||
* If we're asked to flush receive queue, directly
|
||||
* chain it back at the queue without processing it.
|
||||
*/
|
||||
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
|
||||
RX_STAT_INC(rx_drop_rxflush);
|
||||
goto requeue_drop_frag;
|
||||
}
|
||||
|
||||
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
|
||||
|
||||
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
|
||||
@ -1254,19 +1231,18 @@ requeue_drop_frag:
|
||||
sc->rx.frag = NULL;
|
||||
}
|
||||
requeue:
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
if (flush)
|
||||
continue;
|
||||
|
||||
if (edma) {
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
} else {
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
if (!flush)
|
||||
ath9k_hw_rxena(ah);
|
||||
ath9k_hw_rxena(ah);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_RXEOL)) {
|
||||
ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
|
@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
|
||||
#endif
|
||||
t->ms = ms;
|
||||
t->periodic = (bool) periodic;
|
||||
t->set = true;
|
||||
|
||||
atomic_inc(&t->wl->callbacks);
|
||||
if (!t->set) {
|
||||
t->set = true;
|
||||
atomic_inc(&t->wl->callbacks);
|
||||
}
|
||||
|
||||
ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
|
||||
}
|
||||
|
@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il)
|
||||
|
||||
memset(&il->staging, 0, sizeof(il->staging));
|
||||
|
||||
if (!il->vif) {
|
||||
switch (il->iw_mode) {
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
il->staging.dev_type = RXON_DEV_TYPE_ESS;
|
||||
} else if (il->vif->type == NL80211_IFTYPE_STATION) {
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
il->staging.dev_type = RXON_DEV_TYPE_ESS;
|
||||
il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
|
||||
} else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
il->staging.dev_type = RXON_DEV_TYPE_IBSS;
|
||||
il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
|
||||
il->staging.filter_flags =
|
||||
RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
IL_ERR("Unsupported interface type %d\n", il->vif->type);
|
||||
return;
|
||||
}
|
||||
@ -4550,8 +4554,7 @@ out:
|
||||
EXPORT_SYMBOL(il_mac_add_interface);
|
||||
|
||||
static void
|
||||
il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
|
||||
bool mode_change)
|
||||
il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
|
||||
{
|
||||
lockdep_assert_held(&il->mutex);
|
||||
|
||||
@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
|
||||
il_force_scan_end(il);
|
||||
}
|
||||
|
||||
if (!mode_change)
|
||||
il_set_mode(il);
|
||||
|
||||
il_set_mode(il);
|
||||
}
|
||||
|
||||
void
|
||||
@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
|
||||
WARN_ON(il->vif != vif);
|
||||
il->vif = NULL;
|
||||
|
||||
il_teardown_interface(il, vif, false);
|
||||
il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
il_teardown_interface(il, vif);
|
||||
memset(il->bssid, 0, ETH_ALEN);
|
||||
|
||||
D_MAC80211("leave\n");
|
||||
@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
}
|
||||
|
||||
/* success */
|
||||
il_teardown_interface(il, vif, true);
|
||||
vif->type = newtype;
|
||||
vif->p2p = false;
|
||||
err = il_set_mode(il);
|
||||
WARN_ON(err);
|
||||
/*
|
||||
* We've switched internally, but submitting to the
|
||||
* device may have failed for some reason. Mask this
|
||||
* error, because otherwise mac80211 will not switch
|
||||
* (and set the interface type back) and we'll be
|
||||
* out of sync with it.
|
||||
*/
|
||||
il->iw_mode = newtype;
|
||||
il_teardown_interface(il, vif);
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
|
@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
|
||||
{
|
||||
u16 status = le16_to_cpu(tx_resp->status.status);
|
||||
|
||||
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
||||
|
||||
info->status.rates[0].count = tx_resp->failure_frame + 1;
|
||||
info->flags |= iwl_tx_status_to_mac80211(status);
|
||||
iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
|
||||
|
@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
|
||||
struct cfg80211_ssid req_ssid;
|
||||
int ret, auth_type = 0;
|
||||
struct cfg80211_bss *bss = NULL;
|
||||
u8 is_scanning_required = 0, config_bands = 0;
|
||||
u8 is_scanning_required = 0;
|
||||
|
||||
memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
|
||||
|
||||
@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
|
||||
/* disconnect before try to associate */
|
||||
mwifiex_deauthenticate(priv, NULL);
|
||||
|
||||
if (channel) {
|
||||
if (mode == NL80211_IFTYPE_STATION) {
|
||||
if (channel->band == IEEE80211_BAND_2GHZ)
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
else
|
||||
config_bands = BAND_A | BAND_AN;
|
||||
|
||||
if (!((config_bands | priv->adapter->fw_bands) &
|
||||
~priv->adapter->fw_bands))
|
||||
priv->adapter->config_bands = config_bands;
|
||||
}
|
||||
}
|
||||
|
||||
/* As this is new association, clear locally stored
|
||||
* keys and security related flags */
|
||||
priv->sec_info.wpa_enabled = false;
|
||||
@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
|
||||
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) !=
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands |= BAND_GN;
|
||||
config_bands |= BAND_G | BAND_GN;
|
||||
} else {
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) ==
|
||||
NL80211_CHAN_NO_HT)
|
||||
|
@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
|
||||
if (pdev) {
|
||||
card = (struct pcie_service_card *) pci_get_drvdata(pdev);
|
||||
if (!card || card->adapter) {
|
||||
if (!card || !card->adapter) {
|
||||
pr_err("Card or adapter structure is not valid\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
if (bss_desc) {
|
||||
u8 config_bands = 0;
|
||||
|
||||
if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
|
||||
== HostCmd_SCAN_RADIO_TYPE_BG)
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
else
|
||||
config_bands = BAND_A | BAND_AN;
|
||||
|
||||
if (!((config_bands | adapter->fw_bands) &
|
||||
~adapter->fw_bands))
|
||||
adapter->config_bands = config_bands;
|
||||
}
|
||||
|
||||
ret = mwifiex_check_network_compatibility(priv, bss_desc);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
@ -57,12 +57,12 @@ config RTL8192CU
|
||||
|
||||
config RTLWIFI
|
||||
tristate
|
||||
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
|
||||
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
|
||||
default m
|
||||
|
||||
config RTLWIFI_DEBUG
|
||||
bool "Additional debugging output"
|
||||
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
|
||||
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
|
||||
default y
|
||||
|
||||
config RTL8192C_COMMON
|
||||
|
@ -989,17 +989,29 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
|
||||
* tells the LSM to decrement the number of secmark labeling rules loaded
|
||||
* @req_classify_flow:
|
||||
* Sets the flow's sid to the openreq sid.
|
||||
* @tun_dev_alloc_security:
|
||||
* This hook allows a module to allocate a security structure for a TUN
|
||||
* device.
|
||||
* @security pointer to a security structure pointer.
|
||||
* Returns a zero on success, negative values on failure.
|
||||
* @tun_dev_free_security:
|
||||
* This hook allows a module to free the security structure for a TUN
|
||||
* device.
|
||||
* @security pointer to the TUN device's security structure
|
||||
* @tun_dev_create:
|
||||
* Check permissions prior to creating a new TUN device.
|
||||
* @tun_dev_post_create:
|
||||
* This hook allows a module to update or allocate a per-socket security
|
||||
* structure.
|
||||
* @sk contains the newly created sock structure.
|
||||
* @tun_dev_attach_queue:
|
||||
* Check permissions prior to attaching to a TUN device queue.
|
||||
* @security pointer to the TUN device's security structure.
|
||||
* @tun_dev_attach:
|
||||
* Check permissions prior to attaching to a persistent TUN device. This
|
||||
* hook can also be used by the module to update any security state
|
||||
* This hook can be used by the module to update any security state
|
||||
* associated with the TUN device's sock structure.
|
||||
* @sk contains the existing sock structure.
|
||||
* @security pointer to the TUN device's security structure.
|
||||
* @tun_dev_open:
|
||||
* This hook can be used by the module to update any security state
|
||||
* associated with the TUN device's security structure.
|
||||
* @security pointer to the TUN devices's security structure.
|
||||
*
|
||||
* Security hooks for XFRM operations.
|
||||
*
|
||||
@ -1620,9 +1632,12 @@ struct security_operations {
|
||||
void (*secmark_refcount_inc) (void);
|
||||
void (*secmark_refcount_dec) (void);
|
||||
void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
|
||||
int (*tun_dev_create)(void);
|
||||
void (*tun_dev_post_create)(struct sock *sk);
|
||||
int (*tun_dev_attach)(struct sock *sk);
|
||||
int (*tun_dev_alloc_security) (void **security);
|
||||
void (*tun_dev_free_security) (void *security);
|
||||
int (*tun_dev_create) (void);
|
||||
int (*tun_dev_attach_queue) (void *security);
|
||||
int (*tun_dev_attach) (struct sock *sk, void *security);
|
||||
int (*tun_dev_open) (void *security);
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
@ -2566,9 +2581,12 @@ void security_inet_conn_established(struct sock *sk,
|
||||
int security_secmark_relabel_packet(u32 secid);
|
||||
void security_secmark_refcount_inc(void);
|
||||
void security_secmark_refcount_dec(void);
|
||||
int security_tun_dev_alloc_security(void **security);
|
||||
void security_tun_dev_free_security(void *security);
|
||||
int security_tun_dev_create(void);
|
||||
void security_tun_dev_post_create(struct sock *sk);
|
||||
int security_tun_dev_attach(struct sock *sk);
|
||||
int security_tun_dev_attach_queue(void *security);
|
||||
int security_tun_dev_attach(struct sock *sk, void *security);
|
||||
int security_tun_dev_open(void *security);
|
||||
|
||||
#else /* CONFIG_SECURITY_NETWORK */
|
||||
static inline int security_unix_stream_connect(struct sock *sock,
|
||||
@ -2733,16 +2751,31 @@ static inline void security_secmark_refcount_dec(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int security_tun_dev_alloc_security(void **security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void security_tun_dev_free_security(void *security)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int security_tun_dev_create(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void security_tun_dev_post_create(struct sock *sk)
|
||||
static inline int security_tun_dev_attach_queue(void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_tun_dev_attach(struct sock *sk)
|
||||
static inline int security_tun_dev_attach(struct sock *sk, void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_tun_dev_open(void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ struct driver_info {
|
||||
#define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */
|
||||
|
||||
#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */
|
||||
#define FLAG_NOARP 0x2000 /* device can't do ARP */
|
||||
|
||||
/*
|
||||
* Indicates to usbnet, that USB driver accumulates multiple IP packets.
|
||||
|
@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
|
||||
extern int ip4_datagram_connect(struct sock *sk,
|
||||
struct sockaddr *uaddr, int addr_len);
|
||||
|
||||
extern void ip4_datagram_release_cb(struct sock *sk);
|
||||
|
||||
struct ip_reply_arg {
|
||||
struct kvec iov[1];
|
||||
int flags;
|
||||
|
@ -31,6 +31,8 @@ extern void nf_conntrack_cleanup(struct net *net);
|
||||
extern int nf_conntrack_proto_init(struct net *net);
|
||||
extern void nf_conntrack_proto_fini(struct net *net);
|
||||
|
||||
extern void nf_conntrack_cleanup_end(void);
|
||||
|
||||
extern bool
|
||||
nf_ct_get_tuple(const struct sk_buff *skb,
|
||||
unsigned int nhoff,
|
||||
|
@ -738,6 +738,7 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
|
||||
struct arphdr *arphdr;
|
||||
struct ethhdr *ethhdr;
|
||||
__be32 ip_src, ip_dst;
|
||||
uint8_t *hw_src, *hw_dst;
|
||||
uint16_t type = 0;
|
||||
|
||||
/* pull the ethernet header */
|
||||
@ -777,9 +778,23 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
|
||||
ip_src = batadv_arp_ip_src(skb, hdr_size);
|
||||
ip_dst = batadv_arp_ip_dst(skb, hdr_size);
|
||||
if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) ||
|
||||
ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst))
|
||||
ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst) ||
|
||||
ipv4_is_zeronet(ip_src) || ipv4_is_lbcast(ip_src) ||
|
||||
ipv4_is_zeronet(ip_dst) || ipv4_is_lbcast(ip_dst))
|
||||
goto out;
|
||||
|
||||
hw_src = batadv_arp_hw_src(skb, hdr_size);
|
||||
if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src))
|
||||
goto out;
|
||||
|
||||
/* we don't care about the destination MAC address in ARP requests */
|
||||
if (arphdr->ar_op != htons(ARPOP_REQUEST)) {
|
||||
hw_dst = batadv_arp_hw_dst(skb, hdr_size);
|
||||
if (is_zero_ether_addr(hw_dst) ||
|
||||
is_multicast_ether_addr(hw_dst))
|
||||
goto out;
|
||||
}
|
||||
|
||||
type = ntohs(arphdr->ar_op);
|
||||
out:
|
||||
return type;
|
||||
@ -1012,6 +1027,8 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
|
||||
*/
|
||||
ret = !batadv_is_my_client(bat_priv, hw_dst);
|
||||
out:
|
||||
if (ret)
|
||||
kfree_skb(skb);
|
||||
/* if ret == false -> packet has to be delivered to the interface */
|
||||
return ret;
|
||||
}
|
||||
|
@ -2810,14 +2810,6 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
if (conn) {
|
||||
hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
|
||||
mgmt_device_connected(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, 0, NULL, 0,
|
||||
conn->dev_class);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
/* Send to upper protocol */
|
||||
l2cap_recv_acldata(conn, skb, flags);
|
||||
return;
|
||||
|
@ -2688,7 +2688,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
if (ev->opcode != HCI_OP_NOP)
|
||||
del_timer(&hdev->cmd_timer);
|
||||
|
||||
if (ev->ncmd) {
|
||||
if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
|
||||
atomic_set(&hdev->cmd_cnt, 1);
|
||||
if (!skb_queue_empty(&hdev->cmd_q))
|
||||
queue_work(hdev->workqueue, &hdev->cmd_work);
|
||||
|
@ -931,7 +931,7 @@ static int hidp_setup_hid(struct hidp_session *session,
|
||||
hid->version = req->version;
|
||||
hid->country = req->country;
|
||||
|
||||
strncpy(hid->name, req->name, 128);
|
||||
strncpy(hid->name, req->name, sizeof(req->name) - 1);
|
||||
|
||||
snprintf(hid->phys, sizeof(hid->phys), "%pMR",
|
||||
&bt_sk(session->ctrl_sock->sk)->src);
|
||||
|
@ -3727,6 +3727,17 @@ sendresp:
|
||||
static int l2cap_connect_req(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hcon->hdev;
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
|
||||
mgmt_device_connected(hdev, &hcon->dst, hcon->type,
|
||||
hcon->dst_type, 0, NULL, 0,
|
||||
hcon->dev_class);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ static void __sco_sock_close(struct sock *sk)
|
||||
|
||||
case BT_CONNECTED:
|
||||
case BT_CONFIG:
|
||||
if (sco_pi(sk)->conn) {
|
||||
if (sco_pi(sk)->conn->hcon) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
|
||||
hci_conn_put(sco_pi(sk)->conn->hcon);
|
||||
|
@ -186,8 +186,6 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req,
|
||||
struct fastopen_queue *fastopenq =
|
||||
inet_csk(lsk)->icsk_accept_queue.fastopenq;
|
||||
|
||||
BUG_ON(!spin_is_locked(&sk->sk_lock.slock) && !sock_owned_by_user(sk));
|
||||
|
||||
tcp_sk(sk)->fastopen_rsk = NULL;
|
||||
spin_lock_bh(&fastopenq->lock);
|
||||
fastopenq->qlen--;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <net/sock.h>
|
||||
#include <net/compat.h>
|
||||
#include <net/scm.h>
|
||||
#include <net/cls_cgroup.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -302,8 +303,10 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
|
||||
}
|
||||
/* Bump the usage count and install the file. */
|
||||
sock = sock_from_file(fp[i], &err);
|
||||
if (sock)
|
||||
if (sock) {
|
||||
sock_update_netprioidx(sock->sk, current);
|
||||
sock_update_classid(sock->sk, current);
|
||||
}
|
||||
fd_install(new_fd, get_file(fp[i]));
|
||||
}
|
||||
|
||||
|
@ -1649,7 +1649,7 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
|
||||
|
||||
static struct page *linear_to_page(struct page *page, unsigned int *len,
|
||||
unsigned int *offset,
|
||||
struct sk_buff *skb, struct sock *sk)
|
||||
struct sock *sk)
|
||||
{
|
||||
struct page_frag *pfrag = sk_page_frag(sk);
|
||||
|
||||
@ -1682,14 +1682,14 @@ static bool spd_can_coalesce(const struct splice_pipe_desc *spd,
|
||||
static bool spd_fill_page(struct splice_pipe_desc *spd,
|
||||
struct pipe_inode_info *pipe, struct page *page,
|
||||
unsigned int *len, unsigned int offset,
|
||||
struct sk_buff *skb, bool linear,
|
||||
bool linear,
|
||||
struct sock *sk)
|
||||
{
|
||||
if (unlikely(spd->nr_pages == MAX_SKB_FRAGS))
|
||||
return true;
|
||||
|
||||
if (linear) {
|
||||
page = linear_to_page(page, len, &offset, skb, sk);
|
||||
page = linear_to_page(page, len, &offset, sk);
|
||||
if (!page)
|
||||
return true;
|
||||
}
|
||||
@ -1706,23 +1706,9 @@ static bool spd_fill_page(struct splice_pipe_desc *spd,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void __segment_seek(struct page **page, unsigned int *poff,
|
||||
unsigned int *plen, unsigned int off)
|
||||
{
|
||||
unsigned long n;
|
||||
|
||||
*poff += off;
|
||||
n = *poff / PAGE_SIZE;
|
||||
if (n)
|
||||
*page = nth_page(*page, n);
|
||||
|
||||
*poff = *poff % PAGE_SIZE;
|
||||
*plen -= off;
|
||||
}
|
||||
|
||||
static bool __splice_segment(struct page *page, unsigned int poff,
|
||||
unsigned int plen, unsigned int *off,
|
||||
unsigned int *len, struct sk_buff *skb,
|
||||
unsigned int *len,
|
||||
struct splice_pipe_desc *spd, bool linear,
|
||||
struct sock *sk,
|
||||
struct pipe_inode_info *pipe)
|
||||
@ -1737,23 +1723,19 @@ static bool __splice_segment(struct page *page, unsigned int poff,
|
||||
}
|
||||
|
||||
/* ignore any bits we already processed */
|
||||
if (*off) {
|
||||
__segment_seek(&page, &poff, &plen, *off);
|
||||
*off = 0;
|
||||
}
|
||||
poff += *off;
|
||||
plen -= *off;
|
||||
*off = 0;
|
||||
|
||||
do {
|
||||
unsigned int flen = min(*len, plen);
|
||||
|
||||
/* the linear region may spread across several pages */
|
||||
flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
|
||||
|
||||
if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk))
|
||||
if (spd_fill_page(spd, pipe, page, &flen, poff,
|
||||
linear, sk))
|
||||
return true;
|
||||
|
||||
__segment_seek(&page, &poff, &plen, flen);
|
||||
poff += flen;
|
||||
plen -= flen;
|
||||
*len -= flen;
|
||||
|
||||
} while (*len && plen);
|
||||
|
||||
return false;
|
||||
@ -1777,7 +1759,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
|
||||
if (__splice_segment(virt_to_page(skb->data),
|
||||
(unsigned long) skb->data & (PAGE_SIZE - 1),
|
||||
skb_headlen(skb),
|
||||
offset, len, skb, spd,
|
||||
offset, len, spd,
|
||||
skb_head_is_locked(skb),
|
||||
sk, pipe))
|
||||
return true;
|
||||
@ -1790,7 +1772,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
|
||||
|
||||
if (__splice_segment(skb_frag_page(f),
|
||||
f->page_offset, skb_frag_size(f),
|
||||
offset, len, skb, spd, false, sk, pipe))
|
||||
offset, len, spd, false, sk, pipe))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,11 @@ static void ah_input_done(struct crypto_async_request *base, int err)
|
||||
skb->network_header += ah_hlen;
|
||||
memcpy(skb_network_header(skb), work_iph, ihl);
|
||||
__skb_pull(skb, ah_hlen + ihl);
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
out:
|
||||
kfree(AH_SKB_CB(skb)->tmp);
|
||||
xfrm_input_resume(skb, err);
|
||||
@ -381,7 +385,10 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
skb->network_header += ah_hlen;
|
||||
memcpy(skb_network_header(skb), work_iph, ihl);
|
||||
__skb_pull(skb, ah_hlen + ihl);
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
|
||||
err = nexthdr;
|
||||
|
||||
@ -413,9 +420,12 @@ static void ah4_err(struct sk_buff *skb, u32 info)
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
|
||||
atomic_inc(&flow_cache_genid);
|
||||
rt_genid_bump(net);
|
||||
|
||||
ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0);
|
||||
else
|
||||
} else
|
||||
ipv4_redirect(skb, net, 0, 0, IPPROTO_AH, 0);
|
||||
xfrm_state_put(x);
|
||||
}
|
||||
|
@ -85,3 +85,28 @@ out:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(ip4_datagram_connect);
|
||||
|
||||
void ip4_datagram_release_cb(struct sock *sk)
|
||||
{
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
const struct ip_options_rcu *inet_opt;
|
||||
__be32 daddr = inet->inet_daddr;
|
||||
struct flowi4 fl4;
|
||||
struct rtable *rt;
|
||||
|
||||
if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt && inet_opt->opt.srr)
|
||||
daddr = inet_opt->opt.faddr;
|
||||
rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr,
|
||||
inet->inet_saddr, inet->inet_dport,
|
||||
inet->inet_sport, sk->sk_protocol,
|
||||
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
|
||||
if (!IS_ERR(rt))
|
||||
__sk_dst_set(sk, &rt->dst);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
|
||||
|
@ -346,7 +346,10 @@ static int esp_input_done2(struct sk_buff *skb, int err)
|
||||
|
||||
pskb_trim(skb, skb->len - alen - padlen - 2);
|
||||
__skb_pull(skb, hlen);
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -ihl);
|
||||
|
||||
err = nexthdr[1];
|
||||
|
||||
@ -499,9 +502,12 @@ static void esp4_err(struct sk_buff *skb, u32 info)
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
|
||||
atomic_inc(&flow_cache_genid);
|
||||
rt_genid_bump(net);
|
||||
|
||||
ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0);
|
||||
else
|
||||
} else
|
||||
ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0);
|
||||
xfrm_state_put(x);
|
||||
}
|
||||
|
@ -963,8 +963,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||
ptr--;
|
||||
}
|
||||
if (tunnel->parms.o_flags&GRE_CSUM) {
|
||||
int offset = skb_transport_offset(skb);
|
||||
|
||||
*ptr = 0;
|
||||
*(__sum16 *)ptr = ip_compute_csum((void *)(iph+1), skb->len - sizeof(struct iphdr));
|
||||
*(__sum16 *)ptr = csum_fold(skb_checksum(skb, offset,
|
||||
skb->len - offset,
|
||||
0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,12 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
|
||||
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
|
||||
atomic_inc(&flow_cache_genid);
|
||||
rt_genid_bump(net);
|
||||
|
||||
ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0);
|
||||
else
|
||||
} else
|
||||
ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0);
|
||||
xfrm_state_put(x);
|
||||
}
|
||||
|
@ -738,6 +738,7 @@ struct proto ping_prot = {
|
||||
.recvmsg = ping_recvmsg,
|
||||
.bind = ping_bind,
|
||||
.backlog_rcv = ping_queue_rcv_skb,
|
||||
.release_cb = ip4_datagram_release_cb,
|
||||
.hash = ping_v4_hash,
|
||||
.unhash = ping_v4_unhash,
|
||||
.get_port = ping_v4_get_port,
|
||||
|
@ -894,6 +894,7 @@ struct proto raw_prot = {
|
||||
.recvmsg = raw_recvmsg,
|
||||
.bind = raw_bind,
|
||||
.backlog_rcv = raw_rcv_skb,
|
||||
.release_cb = ip4_datagram_release_cb,
|
||||
.hash = raw_hash_sk,
|
||||
.unhash = raw_unhash_sk,
|
||||
.obj_size = sizeof(struct raw_sock),
|
||||
|
@ -912,6 +912,9 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
struct dst_entry *dst = &rt->dst;
|
||||
struct fib_result res;
|
||||
|
||||
if (dst_metric_locked(dst, RTAX_MTU))
|
||||
return;
|
||||
|
||||
if (dst->dev->mtu < mtu)
|
||||
return;
|
||||
|
||||
@ -962,7 +965,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipv4_update_pmtu);
|
||||
|
||||
void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
|
||||
static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
|
||||
{
|
||||
const struct iphdr *iph = (const struct iphdr *) skb->data;
|
||||
struct flowi4 fl4;
|
||||
@ -975,6 +978,53 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
|
||||
ip_rt_put(rt);
|
||||
}
|
||||
}
|
||||
|
||||
void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
|
||||
{
|
||||
const struct iphdr *iph = (const struct iphdr *) skb->data;
|
||||
struct flowi4 fl4;
|
||||
struct rtable *rt;
|
||||
struct dst_entry *dst;
|
||||
bool new = false;
|
||||
|
||||
bh_lock_sock(sk);
|
||||
rt = (struct rtable *) __sk_dst_get(sk);
|
||||
|
||||
if (sock_owned_by_user(sk) || !rt) {
|
||||
__ipv4_sk_update_pmtu(skb, sk, mtu);
|
||||
goto out;
|
||||
}
|
||||
|
||||
__build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
|
||||
|
||||
if (!__sk_dst_check(sk, 0)) {
|
||||
rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
|
||||
if (IS_ERR(rt))
|
||||
goto out;
|
||||
|
||||
new = true;
|
||||
}
|
||||
|
||||
__ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu);
|
||||
|
||||
dst = dst_check(&rt->dst, 0);
|
||||
if (!dst) {
|
||||
if (new)
|
||||
dst_release(&rt->dst);
|
||||
|
||||
rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
|
||||
if (IS_ERR(rt))
|
||||
goto out;
|
||||
|
||||
new = true;
|
||||
}
|
||||
|
||||
if (new)
|
||||
__sk_dst_set(sk, &rt->dst);
|
||||
|
||||
out:
|
||||
bh_unlock_sock(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu);
|
||||
|
||||
void ipv4_redirect(struct sk_buff *skb, struct net *net,
|
||||
@ -1120,7 +1170,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
|
||||
if (!mtu || time_after_eq(jiffies, rt->dst.expires))
|
||||
mtu = dst_metric_raw(dst, RTAX_MTU);
|
||||
|
||||
if (mtu && rt_is_output_route(rt))
|
||||
if (mtu)
|
||||
return mtu;
|
||||
|
||||
mtu = dst->dev->mtu;
|
||||
|
@ -369,11 +369,10 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
|
||||
* We do take care of PMTU discovery (RFC1191) special case :
|
||||
* we can receive locally generated ICMP messages while socket is held.
|
||||
*/
|
||||
if (sock_owned_by_user(sk) &&
|
||||
type != ICMP_DEST_UNREACH &&
|
||||
code != ICMP_FRAG_NEEDED)
|
||||
NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
|
||||
|
||||
if (sock_owned_by_user(sk)) {
|
||||
if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED))
|
||||
NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
|
||||
}
|
||||
if (sk->sk_state == TCP_CLOSE)
|
||||
goto out;
|
||||
|
||||
|
@ -1952,6 +1952,7 @@ struct proto udp_prot = {
|
||||
.recvmsg = udp_recvmsg,
|
||||
.sendpage = udp_sendpage,
|
||||
.backlog_rcv = __udp_queue_rcv_skb,
|
||||
.release_cb = ip4_datagram_release_cb,
|
||||
.hash = udp_lib_hash,
|
||||
.unhash = udp_lib_unhash,
|
||||
.rehash = udp_v4_rehash,
|
||||
|
@ -472,7 +472,10 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
|
||||
skb->network_header += ah_hlen;
|
||||
memcpy(skb_network_header(skb), work_iph, hdr_len);
|
||||
__skb_pull(skb, ah_hlen + hdr_len);
|
||||
skb_set_transport_header(skb, -hdr_len);
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -hdr_len);
|
||||
out:
|
||||
kfree(AH_SKB_CB(skb)->tmp);
|
||||
xfrm_input_resume(skb, err);
|
||||
@ -593,9 +596,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
|
||||
skb->network_header += ah_hlen;
|
||||
memcpy(skb_network_header(skb), work_iph, hdr_len);
|
||||
skb->transport_header = skb->network_header;
|
||||
__skb_pull(skb, ah_hlen + hdr_len);
|
||||
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -hdr_len);
|
||||
|
||||
err = nexthdr;
|
||||
|
||||
out_free:
|
||||
|
@ -300,7 +300,10 @@ static int esp_input_done2(struct sk_buff *skb, int err)
|
||||
|
||||
pskb_trim(skb, skb->len - alen - padlen - 2);
|
||||
__skb_pull(skb, hlen);
|
||||
skb_set_transport_header(skb, -hdr_len);
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL)
|
||||
skb_reset_transport_header(skb);
|
||||
else
|
||||
skb_set_transport_header(skb, -hdr_len);
|
||||
|
||||
err = nexthdr[1];
|
||||
|
||||
|
@ -81,10 +81,22 @@ static inline struct sock *icmpv6_sk(struct net *net)
|
||||
return net->ipv6.icmp_sk[smp_processor_id()];
|
||||
}
|
||||
|
||||
static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
u8 type, u8 code, int offset, __be32 info)
|
||||
{
|
||||
struct net *net = dev_net(skb->dev);
|
||||
|
||||
if (type == ICMPV6_PKT_TOOBIG)
|
||||
ip6_update_pmtu(skb, net, info, 0, 0);
|
||||
else if (type == NDISC_REDIRECT)
|
||||
ip6_redirect(skb, net, 0, 0);
|
||||
}
|
||||
|
||||
static int icmpv6_rcv(struct sk_buff *skb);
|
||||
|
||||
static const struct inet6_protocol icmpv6_protocol = {
|
||||
.handler = icmpv6_rcv,
|
||||
.err_handler = icmpv6_err,
|
||||
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
|
||||
};
|
||||
|
||||
|
@ -1213,10 +1213,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
||||
if (dst_allfrag(rt->dst.path))
|
||||
cork->flags |= IPCORK_ALLFRAG;
|
||||
cork->length = 0;
|
||||
exthdrlen = (opt ? opt->opt_flen : 0) - rt->rt6i_nfheader_len;
|
||||
exthdrlen = (opt ? opt->opt_flen : 0);
|
||||
length += exthdrlen;
|
||||
transhdrlen += exthdrlen;
|
||||
dst_exthdrlen = rt->dst.header_len;
|
||||
dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len;
|
||||
} else {
|
||||
rt = (struct rt6_info *)cork->dst;
|
||||
fl6 = &inet->cork.fl.u.ip6;
|
||||
|
@ -1710,6 +1710,9 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
|
||||
return -EINVAL;
|
||||
if (get_user(v, (u32 __user *)optval))
|
||||
return -EFAULT;
|
||||
/* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */
|
||||
if (v != RT_TABLE_DEFAULT && v >= 100000000)
|
||||
return -EINVAL;
|
||||
if (sk == mrt->mroute6_sk)
|
||||
return -EBUSY;
|
||||
|
||||
|
@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
sta = sta_info_get(sdata, mac_addr);
|
||||
else
|
||||
sta = sta_info_get_bss(sdata, mac_addr);
|
||||
if (!sta) {
|
||||
/*
|
||||
* The ASSOC test makes sure the driver is ready to
|
||||
* receive the key. When wpa_supplicant has roamed
|
||||
* using FT, it attempts to set the key before
|
||||
* association has completed, this rejects that attempt
|
||||
* so it will set the key again after assocation.
|
||||
*
|
||||
* TODO: accept the key if we have a station entry and
|
||||
* add it to the device after the station.
|
||||
*/
|
||||
if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
|
||||
ieee80211_key_free(sdata->local, key);
|
||||
err = -ENOENT;
|
||||
goto out_unlock;
|
||||
|
@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_sched_scan_stopped_work(struct work_struct *work);
|
||||
|
||||
/* off-channel helpers */
|
||||
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
||||
bool offchannel_ps_enable);
|
||||
void ieee80211_offchannel_return(struct ieee80211_local *local,
|
||||
bool offchannel_ps_disable);
|
||||
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
|
||||
void ieee80211_offchannel_return(struct ieee80211_local *local);
|
||||
void ieee80211_roc_setup(struct ieee80211_local *local);
|
||||
void ieee80211_start_next_roc(struct ieee80211_local *local);
|
||||
void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
|
||||
|
@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
|
||||
skb->priority = 7;
|
||||
|
||||
info->control.vif = &sdata->vif;
|
||||
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
|
||||
ieee80211_set_qos_hdr(sdata, skb);
|
||||
}
|
||||
|
||||
@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
|
||||
return -EAGAIN;
|
||||
|
||||
skb = dev_alloc_skb(local->tx_headroom +
|
||||
IEEE80211_ENCRYPT_HEADROOM +
|
||||
IEEE80211_ENCRYPT_TAILROOM +
|
||||
hdr_len +
|
||||
2 + 15 /* PERR IE */);
|
||||
if (!skb)
|
||||
return -1;
|
||||
skb_reserve(skb, local->tx_headroom);
|
||||
skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
|
||||
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
|
||||
memset(mgmt, 0, hdr_len);
|
||||
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
|
@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
|
||||
ieee80211_sta_reset_conn_monitor(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
||||
bool offchannel_ps_enable)
|
||||
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
|
||||
netif_tx_stop_all_queues(sdata->dev);
|
||||
if (offchannel_ps_enable &&
|
||||
(sdata->vif.type == NL80211_IFTYPE_STATION) &&
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||
sdata->u.mgd.associated)
|
||||
ieee80211_offchannel_ps_enable(sdata);
|
||||
}
|
||||
@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
}
|
||||
|
||||
void ieee80211_offchannel_return(struct ieee80211_local *local,
|
||||
bool offchannel_ps_disable)
|
||||
void ieee80211_offchannel_return(struct ieee80211_local *local)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
|
||||
continue;
|
||||
|
||||
/* Tell AP we're back */
|
||||
if (offchannel_ps_disable &&
|
||||
sdata->vif.type == NL80211_IFTYPE_STATION) {
|
||||
if (sdata->u.mgd.associated)
|
||||
ieee80211_offchannel_ps_disable(sdata);
|
||||
}
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||
sdata->u.mgd.associated)
|
||||
ieee80211_offchannel_ps_disable(sdata);
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
|
||||
/*
|
||||
@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
||||
local->tmp_channel = NULL;
|
||||
ieee80211_hw_config(local, 0);
|
||||
|
||||
ieee80211_offchannel_return(local, true);
|
||||
ieee80211_offchannel_return(local);
|
||||
}
|
||||
|
||||
ieee80211_recalc_idle(local);
|
||||
|
@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
|
||||
if (!was_hw_scan) {
|
||||
ieee80211_configure_filter(local);
|
||||
drv_sw_scan_complete(local);
|
||||
ieee80211_offchannel_return(local, true);
|
||||
ieee80211_offchannel_return(local);
|
||||
}
|
||||
|
||||
ieee80211_recalc_idle(local);
|
||||
@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
|
||||
local->next_scan_state = SCAN_DECISION;
|
||||
local->scan_channel_idx = 0;
|
||||
|
||||
ieee80211_offchannel_stop_vifs(local, true);
|
||||
ieee80211_offchannel_stop_vifs(local);
|
||||
|
||||
ieee80211_configure_filter(local);
|
||||
|
||||
@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
|
||||
local->scan_channel = NULL;
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
|
||||
/*
|
||||
* Re-enable vifs and beaconing. Leave PS
|
||||
* in off-channel state..will put that back
|
||||
* on-channel at the end of scanning.
|
||||
*/
|
||||
ieee80211_offchannel_return(local, false);
|
||||
/* disable PS */
|
||||
ieee80211_offchannel_return(local);
|
||||
|
||||
*next_delay = HZ / 5;
|
||||
/* afterwards, resume scan & go to next channel */
|
||||
@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
|
||||
static void ieee80211_scan_state_resume(struct ieee80211_local *local,
|
||||
unsigned long *next_delay)
|
||||
{
|
||||
/* PS already is in off-channel mode */
|
||||
ieee80211_offchannel_stop_vifs(local, false);
|
||||
ieee80211_offchannel_stop_vifs(local);
|
||||
|
||||
if (local->ops->flush) {
|
||||
drv_flush(local, false);
|
||||
|
@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf =
|
||||
rcu_dereference(tmp_sdata->vif.chanctx_conf);
|
||||
}
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
|
||||
chan = chanctx_conf->def.chan;
|
||||
if (chanctx_conf)
|
||||
chan = chanctx_conf->def.chan;
|
||||
else if (!local->use_chanctx)
|
||||
chan = local->_oper_channel;
|
||||
else
|
||||
goto fail_rcu;
|
||||
|
||||
/*
|
||||
* Frame injection is not allowed if beaconing is not allowed
|
||||
|
@ -1376,11 +1376,12 @@ void nf_conntrack_cleanup(struct net *net)
|
||||
synchronize_net();
|
||||
nf_conntrack_proto_fini(net);
|
||||
nf_conntrack_cleanup_net(net);
|
||||
}
|
||||
|
||||
if (net_eq(net, &init_net)) {
|
||||
RCU_INIT_POINTER(nf_ct_destroy, NULL);
|
||||
nf_conntrack_cleanup_init_net();
|
||||
}
|
||||
void nf_conntrack_cleanup_end(void)
|
||||
{
|
||||
RCU_INIT_POINTER(nf_ct_destroy, NULL);
|
||||
nf_conntrack_cleanup_init_net();
|
||||
}
|
||||
|
||||
void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
|
||||
|
@ -575,6 +575,7 @@ static int __init nf_conntrack_standalone_init(void)
|
||||
static void __exit nf_conntrack_standalone_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&nf_conntrack_net_ops);
|
||||
nf_conntrack_cleanup_end();
|
||||
}
|
||||
|
||||
module_init(nf_conntrack_standalone_init);
|
||||
|
@ -345,19 +345,27 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_find_revision);
|
||||
|
||||
static char *textify_hooks(char *buf, size_t size, unsigned int mask)
|
||||
static char *
|
||||
textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto)
|
||||
{
|
||||
static const char *const names[] = {
|
||||
static const char *const inetbr_names[] = {
|
||||
"PREROUTING", "INPUT", "FORWARD",
|
||||
"OUTPUT", "POSTROUTING", "BROUTING",
|
||||
};
|
||||
unsigned int i;
|
||||
static const char *const arp_names[] = {
|
||||
"INPUT", "FORWARD", "OUTPUT",
|
||||
};
|
||||
const char *const *names;
|
||||
unsigned int i, max;
|
||||
char *p = buf;
|
||||
bool np = false;
|
||||
int res;
|
||||
|
||||
names = (nfproto == NFPROTO_ARP) ? arp_names : inetbr_names;
|
||||
max = (nfproto == NFPROTO_ARP) ? ARRAY_SIZE(arp_names) :
|
||||
ARRAY_SIZE(inetbr_names);
|
||||
*p = '\0';
|
||||
for (i = 0; i < ARRAY_SIZE(names); ++i) {
|
||||
for (i = 0; i < max; ++i) {
|
||||
if (!(mask & (1 << i)))
|
||||
continue;
|
||||
res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]);
|
||||
@ -402,8 +410,10 @@ int xt_check_match(struct xt_mtchk_param *par,
|
||||
pr_err("%s_tables: %s match: used from hooks %s, but only "
|
||||
"valid from %s\n",
|
||||
xt_prefix[par->family], par->match->name,
|
||||
textify_hooks(used, sizeof(used), par->hook_mask),
|
||||
textify_hooks(allow, sizeof(allow), par->match->hooks));
|
||||
textify_hooks(used, sizeof(used), par->hook_mask,
|
||||
par->family),
|
||||
textify_hooks(allow, sizeof(allow), par->match->hooks,
|
||||
par->family));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (par->match->proto && (par->match->proto != proto || inv_proto)) {
|
||||
@ -575,8 +585,10 @@ int xt_check_target(struct xt_tgchk_param *par,
|
||||
pr_err("%s_tables: %s target: used from hooks %s, but only "
|
||||
"usable from %s\n",
|
||||
xt_prefix[par->family], par->target->name,
|
||||
textify_hooks(used, sizeof(used), par->hook_mask),
|
||||
textify_hooks(allow, sizeof(allow), par->target->hooks));
|
||||
textify_hooks(used, sizeof(used), par->hook_mask,
|
||||
par->family),
|
||||
textify_hooks(allow, sizeof(allow), par->target->hooks,
|
||||
par->family));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (par->target->proto && (par->target->proto != proto || inv_proto)) {
|
||||
|
@ -109,7 +109,7 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par)
|
||||
struct xt_ct_target_info *info = par->targinfo;
|
||||
struct nf_conntrack_tuple t;
|
||||
struct nf_conn *ct;
|
||||
int ret;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (info->flags & ~XT_CT_NOTRACK)
|
||||
return -EINVAL;
|
||||
@ -247,7 +247,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
|
||||
struct xt_ct_target_info_v1 *info = par->targinfo;
|
||||
struct nf_conntrack_tuple t;
|
||||
struct nf_conn *ct;
|
||||
int ret;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (info->flags & ~XT_CT_NOTRACK)
|
||||
return -EINVAL;
|
||||
|
@ -224,7 +224,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
|
||||
|
||||
/* Free the outqueue structure and any related pending chunks.
|
||||
*/
|
||||
void sctp_outq_teardown(struct sctp_outq *q)
|
||||
static void __sctp_outq_teardown(struct sctp_outq *q)
|
||||
{
|
||||
struct sctp_transport *transport;
|
||||
struct list_head *lchunk, *temp;
|
||||
@ -277,8 +277,6 @@ void sctp_outq_teardown(struct sctp_outq *q)
|
||||
sctp_chunk_free(chunk);
|
||||
}
|
||||
|
||||
q->error = 0;
|
||||
|
||||
/* Throw away any leftover control chunks. */
|
||||
list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
|
||||
list_del_init(&chunk->list);
|
||||
@ -286,11 +284,17 @@ void sctp_outq_teardown(struct sctp_outq *q)
|
||||
}
|
||||
}
|
||||
|
||||
void sctp_outq_teardown(struct sctp_outq *q)
|
||||
{
|
||||
__sctp_outq_teardown(q);
|
||||
sctp_outq_init(q->asoc, q);
|
||||
}
|
||||
|
||||
/* Free the outqueue structure and any related pending chunks. */
|
||||
void sctp_outq_free(struct sctp_outq *q)
|
||||
{
|
||||
/* Throw away leftover chunks. */
|
||||
sctp_outq_teardown(q);
|
||||
__sctp_outq_teardown(q);
|
||||
|
||||
/* If we were kmalloc()'d, free the memory. */
|
||||
if (q->malloced)
|
||||
|
@ -1779,8 +1779,10 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
|
||||
|
||||
/* Update the content of current association. */
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
||||
SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
||||
return SCTP_DISPOSITION_CONSUME;
|
||||
|
||||
nomem_ev:
|
||||
|
@ -366,7 +366,11 @@ int sctp_sysctl_net_register(struct net *net)
|
||||
|
||||
void sctp_sysctl_net_unregister(struct net *net)
|
||||
{
|
||||
struct ctl_table *table;
|
||||
|
||||
table = net->sctp.sysctl_header->ctl_table_arg;
|
||||
unregister_net_sysctl_table(net->sctp.sysctl_header);
|
||||
kfree(table);
|
||||
}
|
||||
|
||||
static struct ctl_table_header * sctp_sysctl_header;
|
||||
|
@ -2656,7 +2656,7 @@ static void xfrm_policy_fini(struct net *net)
|
||||
WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
|
||||
|
||||
htab = &net->xfrm.policy_bydst[dir];
|
||||
sz = (htab->hmask + 1);
|
||||
sz = (htab->hmask + 1) * sizeof(struct hlist_head);
|
||||
WARN_ON(!hlist_empty(htab->table));
|
||||
xfrm_hash_free(htab->table, sz);
|
||||
}
|
||||
|
@ -242,11 +242,13 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
|
||||
u32 diff;
|
||||
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
|
||||
u32 seq = ntohl(net_seq);
|
||||
u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
|
||||
u32 pos;
|
||||
|
||||
if (!replay_esn->replay_window)
|
||||
return;
|
||||
|
||||
pos = (replay_esn->seq - 1) % replay_esn->replay_window;
|
||||
|
||||
if (seq > replay_esn->seq) {
|
||||
diff = seq - replay_esn->seq;
|
||||
|
||||
|
@ -709,16 +709,31 @@ static void cap_req_classify_flow(const struct request_sock *req,
|
||||
{
|
||||
}
|
||||
|
||||
static int cap_tun_dev_alloc_security(void **security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cap_tun_dev_free_security(void *security)
|
||||
{
|
||||
}
|
||||
|
||||
static int cap_tun_dev_create(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cap_tun_dev_post_create(struct sock *sk)
|
||||
static int cap_tun_dev_attach_queue(void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cap_tun_dev_attach(struct sock *sk)
|
||||
static int cap_tun_dev_attach(struct sock *sk, void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cap_tun_dev_open(void *security)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -1050,8 +1065,11 @@ void __init security_fixup_ops(struct security_operations *ops)
|
||||
set_to_cap_if_null(ops, secmark_refcount_inc);
|
||||
set_to_cap_if_null(ops, secmark_refcount_dec);
|
||||
set_to_cap_if_null(ops, req_classify_flow);
|
||||
set_to_cap_if_null(ops, tun_dev_alloc_security);
|
||||
set_to_cap_if_null(ops, tun_dev_free_security);
|
||||
set_to_cap_if_null(ops, tun_dev_create);
|
||||
set_to_cap_if_null(ops, tun_dev_post_create);
|
||||
set_to_cap_if_null(ops, tun_dev_open);
|
||||
set_to_cap_if_null(ops, tun_dev_attach_queue);
|
||||
set_to_cap_if_null(ops, tun_dev_attach);
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
|
@ -1254,24 +1254,42 @@ void security_secmark_refcount_dec(void)
|
||||
}
|
||||
EXPORT_SYMBOL(security_secmark_refcount_dec);
|
||||
|
||||
int security_tun_dev_alloc_security(void **security)
|
||||
{
|
||||
return security_ops->tun_dev_alloc_security(security);
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_alloc_security);
|
||||
|
||||
void security_tun_dev_free_security(void *security)
|
||||
{
|
||||
security_ops->tun_dev_free_security(security);
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_free_security);
|
||||
|
||||
int security_tun_dev_create(void)
|
||||
{
|
||||
return security_ops->tun_dev_create();
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_create);
|
||||
|
||||
void security_tun_dev_post_create(struct sock *sk)
|
||||
int security_tun_dev_attach_queue(void *security)
|
||||
{
|
||||
return security_ops->tun_dev_post_create(sk);
|
||||
return security_ops->tun_dev_attach_queue(security);
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_post_create);
|
||||
EXPORT_SYMBOL(security_tun_dev_attach_queue);
|
||||
|
||||
int security_tun_dev_attach(struct sock *sk)
|
||||
int security_tun_dev_attach(struct sock *sk, void *security)
|
||||
{
|
||||
return security_ops->tun_dev_attach(sk);
|
||||
return security_ops->tun_dev_attach(sk, security);
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_attach);
|
||||
|
||||
int security_tun_dev_open(void *security)
|
||||
{
|
||||
return security_ops->tun_dev_open(security);
|
||||
}
|
||||
EXPORT_SYMBOL(security_tun_dev_open);
|
||||
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
|
@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req,
|
||||
fl->flowi_secid = req->secid;
|
||||
}
|
||||
|
||||
static int selinux_tun_dev_alloc_security(void **security)
|
||||
{
|
||||
struct tun_security_struct *tunsec;
|
||||
|
||||
tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
|
||||
if (!tunsec)
|
||||
return -ENOMEM;
|
||||
tunsec->sid = current_sid();
|
||||
|
||||
*security = tunsec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void selinux_tun_dev_free_security(void *security)
|
||||
{
|
||||
kfree(security);
|
||||
}
|
||||
|
||||
static int selinux_tun_dev_create(void)
|
||||
{
|
||||
u32 sid = current_sid();
|
||||
@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void selinux_tun_dev_post_create(struct sock *sk)
|
||||
static int selinux_tun_dev_attach_queue(void *security)
|
||||
{
|
||||
struct tun_security_struct *tunsec = security;
|
||||
|
||||
return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
|
||||
TUN_SOCKET__ATTACH_QUEUE, NULL);
|
||||
}
|
||||
|
||||
static int selinux_tun_dev_attach(struct sock *sk, void *security)
|
||||
{
|
||||
struct tun_security_struct *tunsec = security;
|
||||
struct sk_security_struct *sksec = sk->sk_security;
|
||||
|
||||
/* we don't currently perform any NetLabel based labeling here and it
|
||||
@ -4425,20 +4452,19 @@ static void selinux_tun_dev_post_create(struct sock *sk)
|
||||
* cause confusion to the TUN user that had no idea network labeling
|
||||
* protocols were being used */
|
||||
|
||||
/* see the comments in selinux_tun_dev_create() about why we don't use
|
||||
* the sockcreate SID here */
|
||||
|
||||
sksec->sid = current_sid();
|
||||
sksec->sid = tunsec->sid;
|
||||
sksec->sclass = SECCLASS_TUN_SOCKET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int selinux_tun_dev_attach(struct sock *sk)
|
||||
static int selinux_tun_dev_open(void *security)
|
||||
{
|
||||
struct sk_security_struct *sksec = sk->sk_security;
|
||||
struct tun_security_struct *tunsec = security;
|
||||
u32 sid = current_sid();
|
||||
int err;
|
||||
|
||||
err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET,
|
||||
err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,
|
||||
TUN_SOCKET__RELABELFROM, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk)
|
||||
TUN_SOCKET__RELABELTO, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sksec->sid = sid;
|
||||
tunsec->sid = sid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = {
|
||||
.secmark_refcount_inc = selinux_secmark_refcount_inc,
|
||||
.secmark_refcount_dec = selinux_secmark_refcount_dec,
|
||||
.req_classify_flow = selinux_req_classify_flow,
|
||||
.tun_dev_alloc_security = selinux_tun_dev_alloc_security,
|
||||
.tun_dev_free_security = selinux_tun_dev_free_security,
|
||||
.tun_dev_create = selinux_tun_dev_create,
|
||||
.tun_dev_post_create = selinux_tun_dev_post_create,
|
||||
.tun_dev_attach_queue = selinux_tun_dev_attach_queue,
|
||||
.tun_dev_attach = selinux_tun_dev_attach,
|
||||
.tun_dev_open = selinux_tun_dev_open,
|
||||
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
.xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
|
||||
|
@ -150,6 +150,6 @@ struct security_class_mapping secclass_map[] = {
|
||||
NULL } },
|
||||
{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
|
||||
{ "tun_socket",
|
||||
{ COMMON_SOCK_PERMS, NULL } },
|
||||
{ COMMON_SOCK_PERMS, "attach_queue", NULL } },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -110,6 +110,10 @@ struct sk_security_struct {
|
||||
u16 sclass; /* sock security class */
|
||||
};
|
||||
|
||||
struct tun_security_struct {
|
||||
u32 sid; /* SID for the tun device sockets */
|
||||
};
|
||||
|
||||
struct key_security_struct {
|
||||
u32 sid; /* SID of key */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user