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

Pull networking fixes from David Miller:
 "It's been a while since my last pull request so quite a few fixes have
  piled up."

Indeed.

 1) Fix nf_{log,queue} compilation with PROC_FS disabled, from Pablo
    Neira Ayuso.

 2) Fix data corruption on some tg3 chips with TSO enabled, from Michael
    Chan.

 3) Fix double insertion of VLAN tags in be2net driver, from Sarveshwar
    Bandi.

 4) Don't have TCP's MD5 support pass > PAGE_SIZE page offsets in
    scatter-gather entries into the crypto layer, the crypto layer can't
    handle that.  From Eric Dumazet.

 5) Fix lockdep splat in 802.1Q MRP code, also from Eric Dumazet.

 6) Fix OOPS in netfilter log module when called from conntrack, from
    Hans Schillstrom.

 7) FEC driver needs to use netif_tx_{lock,unlock}_bh() rather than the
    non-BH disabling variants.  From Fabio Estevam.

 8) TCP GSO can generate out-of-order packets, fix from Eric Dumazet.

 9) vxlan driver doesn't update 'used' field of fdb entries when it
    should, from Sridhar Samudrala.

10) ipv6 should use kzalloc() to allocate inet6 socket cork options,
    otherwise we can OOPS in ip6_cork_release().  From Eric Dumazet.

11) Fix races in bonding set mode, from Nikolay Aleksandrov.

12) Fix checksum generation regression added by "r8169: fix 8168evl
    frame padding.", from Francois Romieu.

13) ip_gre can look at stale SKB data pointer, fix from Eric Dumazet.

14) Fix checksum handling when GSO is enabled in bnx2x driver with
    certain chips, from Yuval Mintz.

15) Fix double free in batman-adv, from Martin Hundebøll.

16) Fix device startup synchronization with firmware in tg3 driver, from
    Nithin Sujit.

17) perf networking dropmonitor doesn't work at all due to mixed up
    trace parameter ordering, from Ben Hutchings.

18) Fix proportional rate reduction handling in tcp_ack(), from Nandita
    Dukkipati.

19) IPSEC layer doesn't return an error when a valid state is detected,
    causing an OOPS.  Fix from Timo Teräs.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (85 commits)
  be2net: bug fix on returning an invalid nic descriptor
  tcp: xps: fix reordering issues
  net: Revert unused variable changes.
  xfrm: properly handle invalid states as an error
  virtio_net: enable napi for all possible queues during open
  tcp: bug fix in proportional rate reduction.
  net: ethernet: sun: drop unused variable
  net: ethernet: korina: drop unused variable
  net: ethernet: apple: drop unused variable
  qmi_wwan: Added support for Cinterion's PLxx WWAN Interface
  perf: net_dropmonitor: Remove progress indicator
  perf: net_dropmonitor: Use bisection in symbol lookup
  perf: net_dropmonitor: Do not assume ordering of dictionaries
  perf: net_dropmonitor: Fix symbol-relative addresses
  perf: net_dropmonitor: Fix trace parameter order
  net: fec: use a more proper compatible string for MVF type device
  qlcnic: Fix updating netdev->features
  qlcnic: remove netdev->trans_start updates within the driver
  qlcnic: Return proper error codes from probe failure paths
  tg3: Update version to 3.132
  ...
This commit is contained in:
Linus Torvalds 2013-05-24 08:27:32 -07:00
commit eb3d33900a
95 changed files with 937 additions and 461 deletions

View File

@ -5524,18 +5524,18 @@ F: Documentation/networking/s2io.txt
F: Documentation/networking/vxge.txt
F: drivers/net/ethernet/neterion/
NETFILTER/IPTABLES/IPCHAINS
P: Harald Welte
P: Jozsef Kadlecsik
NETFILTER/IPTABLES
M: Pablo Neira Ayuso <pablo@netfilter.org>
M: Patrick McHardy <kaber@trash.net>
M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
L: netfilter-devel@vger.kernel.org
L: netfilter@vger.kernel.org
L: coreteam@netfilter.org
W: http://www.netfilter.org/
W: http://www.iptables.org/
T: git git://1984.lsi.us.es/nf
T: git git://1984.lsi.us.es/nf-next
Q: http://patchwork.ozlabs.org/project/netfilter-devel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
S: Supported
F: include/linux/netfilter*
F: include/linux/netfilter/

View File

@ -84,6 +84,8 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = {
{ BCMA_CORE_I2S, "I2S" },
{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
{ BCMA_CORE_SHIM, "SHIM" },
{ BCMA_CORE_PCIE2, "PCIe Gen2" },
{ BCMA_CORE_ARM_CR4, "ARM CR4" },
{ BCMA_CORE_DEFAULT, "Default" },
};

View File

@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr)
static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
{
if (contr - 1 >= CAPI_MAXCONTR)
if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
return NULL;
return capi_controller[contr - 1];
@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
{
lockdep_assert_held(&capi_controller_lock);
if (applid - 1 >= CAPI_MAXAPPL)
if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
return NULL;
return capi_applications[applid - 1];
@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
{
if (applid - 1 >= CAPI_MAXAPPL)
if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
return NULL;
return rcu_dereference(capi_applications[applid - 1]);

View File

@ -2360,14 +2360,15 @@ int bond_3ad_set_carrier(struct bonding *bond)
}
/**
* bond_3ad_get_active_agg_info - get information of the active aggregator
* __bond_3ad_get_active_agg_info - get information of the active aggregator
* @bond: bonding struct to work on
* @ad_info: ad_info struct to fill with the bond's info
*
* Returns: 0 on success
* < 0 on error
*/
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
int __bond_3ad_get_active_agg_info(struct bonding *bond,
struct ad_info *ad_info)
{
struct aggregator *aggregator = NULL;
struct port *port;
@ -2391,6 +2392,18 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
return -1;
}
/* Wrapper used to hold bond->lock so no slave manipulation can occur */
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
{
int ret;
read_lock(&bond->lock);
ret = __bond_3ad_get_active_agg_info(bond, ad_info);
read_unlock(&bond->lock);
return ret;
}
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
{
struct slave *slave, *start_at;
@ -2402,8 +2415,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
struct ad_info ad_info;
int res = 1;
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
dev->name);
goto out;
}

View File

@ -273,6 +273,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave);
void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
int __bond_3ad_get_active_agg_info(struct bonding *bond,
struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
struct slave *slave);

View File

@ -1362,6 +1362,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
slave->dev->features,
mask);
}
features = netdev_add_tso_features(features, mask);
out:
read_unlock(&bond->lock);
@ -2555,8 +2556,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
{
struct sk_buff *skb;
pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
slave_dev->name, dest_ip, src_ip, vlan_id);
pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op,
slave_dev->name, &dest_ip, &src_ip, vlan_id);
skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
NULL, slave_dev->dev_addr, NULL);
@ -2588,7 +2589,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
__be32 addr;
if (!targets[i])
break;
pr_debug("basa: target %x\n", targets[i]);
pr_debug("basa: target %pI4\n", &targets[i]);
if (!bond_vlan_used(bond)) {
pr_debug("basa: empty vlan: arp_send\n");
addr = bond_confirm_addr(bond->dev, targets[i], 0);
@ -4470,7 +4471,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
static int bond_check_params(struct bond_params *params)
{
int arp_validate_value, fail_over_mac_value, primary_reselect_value;
int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
/*
* Convert string parameters.
@ -4650,19 +4651,18 @@ static int bond_check_params(struct bond_params *params)
arp_interval = BOND_LINK_ARP_INTERV;
}
for (arp_ip_count = 0;
(arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count];
arp_ip_count++) {
for (arp_ip_count = 0, i = 0;
(arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) {
/* not complete check, but should be good enough to
catch mistakes */
__be32 ip = in_aton(arp_ip_target[arp_ip_count]);
if (!isdigit(arp_ip_target[arp_ip_count][0]) ||
ip == 0 || ip == htonl(INADDR_BROADCAST)) {
__be32 ip = in_aton(arp_ip_target[i]);
if (!isdigit(arp_ip_target[i][0]) || ip == 0 ||
ip == htonl(INADDR_BROADCAST)) {
pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
arp_ip_target[arp_ip_count]);
arp_ip_target[i]);
arp_interval = 0;
} else {
arp_target[arp_ip_count] = ip;
arp_target[arp_ip_count++] = ip;
}
}
@ -4696,8 +4696,6 @@ static int bond_check_params(struct bond_params *params)
if (miimon) {
pr_info("MII link monitoring set to %d ms\n", miimon);
} else if (arp_interval) {
int i;
pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):",
arp_interval,
arp_validate_tbl[arp_validate_value].modename,

View File

@ -130,7 +130,7 @@ static void bond_info_show_master(struct seq_file *seq)
seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
ad_select_tbl[bond->params.ad_select].modename);
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
seq_printf(seq, "bond %s has no active aggregator\n",
bond->dev->name);
} else {

View File

@ -316,6 +316,9 @@ static ssize_t bonding_store_mode(struct device *d,
int new_value, ret = count;
struct bonding *bond = to_bond(d);
if (!rtnl_trylock())
return restart_syscall();
if (bond->dev->flags & IFF_UP) {
pr_err("unable to update mode of %s because interface is up.\n",
bond->dev->name);
@ -352,6 +355,7 @@ static ssize_t bonding_store_mode(struct device *d,
bond->dev->name, bond_mode_tbl[new_value].modename,
new_value);
out:
rtnl_unlock();
return ret;
}
static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
@ -1315,7 +1319,6 @@ static ssize_t bonding_show_mii_status(struct device *d,
}
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
/*
* Show current 802.3ad aggregator ID.
*/
@ -1329,7 +1332,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
count = sprintf(buf, "%d\n",
(bond_3ad_get_active_agg_info(bond, &ad_info))
bond_3ad_get_active_agg_info(bond, &ad_info)
? 0 : ad_info.aggregator_id);
}
@ -1351,7 +1354,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
count = sprintf(buf, "%d\n",
(bond_3ad_get_active_agg_info(bond, &ad_info))
bond_3ad_get_active_agg_info(bond, &ad_info)
? 0 : ad_info.ports);
}
@ -1373,7 +1376,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
count = sprintf(buf, "%d\n",
(bond_3ad_get_active_agg_info(bond, &ad_info))
bond_3ad_get_active_agg_info(bond, &ad_info)
? 0 : ad_info.actor_key);
}
@ -1395,7 +1398,7 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
count = sprintf(buf, "%d\n",
(bond_3ad_get_active_agg_info(bond, &ad_info))
bond_3ad_get_active_agg_info(bond, &ad_info)
? 0 : ad_info.partner_key);
}

View File

@ -3313,6 +3313,7 @@ static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
*/
static void bnx2x_set_pbd_gso(struct sk_buff *skb,
struct eth_tx_parse_bd_e1x *pbd,
struct eth_tx_start_bd *tx_start_bd,
u32 xmit_type)
{
pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
@ -3326,11 +3327,14 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb,
ip_hdr(skb)->daddr,
0, IPPROTO_TCP, 0));
} else
/* GSO on 57710/57711 needs FW to calculate IP checksum */
tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
} else {
pbd->tcp_pseudo_csum =
bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr,
0, IPPROTO_TCP, 0));
}
pbd->global_data |=
cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN);
@ -3814,7 +3818,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
xmit_type);
else
bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
bnx2x_set_pbd_gso(skb, pbd_e1x, tx_start_bd,
xmit_type);
}
/* Set the PBD's parsing_data field if not zero

View File

@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
#define TG3_MIN_NUM 131
#define TG3_MIN_NUM 132
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
#define DRV_MODULE_RELDATE "April 09, 2013"
#define DRV_MODULE_RELDATE "May 21, 2013"
#define RESET_KIND_SHUTDOWN 0
#define RESET_KIND_INIT 1
@ -2957,6 +2957,31 @@ static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
return 0;
}
static bool tg3_phy_power_bug(struct tg3 *tp)
{
switch (tg3_asic_rev(tp)) {
case ASIC_REV_5700:
case ASIC_REV_5704:
return true;
case ASIC_REV_5780:
if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
return true;
return false;
case ASIC_REV_5717:
if (!tp->pci_fn)
return true;
return false;
case ASIC_REV_5719:
case ASIC_REV_5720:
if ((tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
!tp->pci_fn)
return true;
return false;
}
return false;
}
static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
{
u32 val;
@ -3016,12 +3041,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
/* The PHY should not be powered down on some chips because
* of bugs.
*/
if (tg3_asic_rev(tp) == ASIC_REV_5700 ||
tg3_asic_rev(tp) == ASIC_REV_5704 ||
(tg3_asic_rev(tp) == ASIC_REV_5780 &&
(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) ||
(tg3_asic_rev(tp) == ASIC_REV_5717 &&
!tp->pci_fn))
if (tg3_phy_power_bug(tp))
return;
if (tg3_chip_rev(tp) == CHIPREV_5784_AX ||
@ -7428,6 +7448,20 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
return (base > 0xffffdcc0) && (base + len + 8 < base);
}
/* Test for TSO DMA buffers that cross into regions which are within MSS bytes
* of any 4GB boundaries: 4G, 8G, etc
*/
static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping,
u32 len, u32 mss)
{
if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) {
u32 base = (u32) mapping & 0xffffffff;
return ((base + len + (mss & 0x3fff)) < base);
}
return 0;
}
/* Test for DMA addresses > 40-bit */
static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
int len)
@ -7464,6 +7498,9 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
if (tg3_4g_overflow_test(map, len))
hwbug = true;
if (tg3_4g_tso_overflow_test(tp, map, len, mss))
hwbug = true;
if (tg3_40bit_overflow_test(tp, map, len))
hwbug = true;
@ -8874,6 +8911,10 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_halt_cpu(tp, RX_CPU_BASE);
}
err = tg3_poll_fw(tp);
if (err)
return err;
tw32(GRC_MODE, tp->grc_mode);
if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) {
@ -8904,10 +8945,6 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
err = tg3_poll_fw(tp);
if (err)
return err;
tg3_mdio_start(tp);
if (tg3_flag(tp, PCI_EXPRESS) &&

View File

@ -485,7 +485,8 @@ static void macb_tx_interrupt(struct macb *bp)
status = macb_readl(bp, TSR);
macb_writel(bp, TSR, status);
macb_writel(bp, ISR, MACB_BIT(TCOMP));
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
macb_writel(bp, ISR, MACB_BIT(TCOMP));
netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n",
(unsigned long)status);
@ -738,7 +739,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
* now.
*/
macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
macb_writel(bp, ISR, MACB_BIT(RCOMP));
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
macb_writel(bp, ISR, MACB_BIT(RCOMP));
if (napi_schedule_prep(&bp->napi)) {
netdev_vdbg(bp->dev, "scheduling RX softirq\n");
@ -1062,6 +1064,17 @@ static void macb_configure_dma(struct macb *bp)
}
}
/*
* Configure peripheral capacities according to integration options used
*/
static void macb_configure_caps(struct macb *bp)
{
if (macb_is_gem(bp)) {
if (GEM_BF(IRQCOR, gem_readl(bp, DCFG1)) == 0)
bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
}
}
static void macb_init_hw(struct macb *bp)
{
u32 config;
@ -1084,6 +1097,7 @@ static void macb_init_hw(struct macb *bp)
bp->duplex = DUPLEX_HALF;
macb_configure_dma(bp);
macb_configure_caps(bp);
/* Initialize TX and RX buffers */
macb_writel(bp, RBQP, bp->rx_ring_dma);

View File

@ -300,6 +300,8 @@
#define MACB_REV_SIZE 16
/* Bitfields in DCFG1. */
#define GEM_IRQCOR_OFFSET 23
#define GEM_IRQCOR_SIZE 1
#define GEM_DBWDEF_OFFSET 25
#define GEM_DBWDEF_SIZE 3
@ -323,6 +325,9 @@
#define MACB_MAN_READ 2
#define MACB_MAN_CODE 2
/* Capability mask bits */
#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x1
/* Bit manipulation macros */
#define MACB_BIT(name) \
(1 << MACB_##name##_OFFSET)
@ -574,6 +579,8 @@ struct macb {
unsigned int speed;
unsigned int duplex;
u32 caps;
phy_interface_t phy_interface;
/* AT91RM9200 transmit */

View File

@ -2976,22 +2976,17 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
for (i = 0; i < desc_count; i++) {
desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE;
if (((void *)desc + desc->desc_len) >
(void *)(buf + max_buf_size)) {
desc = NULL;
break;
}
(void *)(buf + max_buf_size))
return NULL;
if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
break;
return desc;
desc = (void *)desc + desc->desc_len;
}
if (!desc || i == MAX_RESOURCE_DESC)
return NULL;
return desc;
return NULL;
}
/* Uses Mbox */

View File

@ -780,26 +780,18 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
if (unlikely(!skb))
return skb;
if (vlan_tx_tag_present(skb)) {
if (vlan_tx_tag_present(skb))
vlan_tag = be_get_tx_vlan_tag(adapter, skb);
skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
if (skb)
skb->vlan_tci = 0;
}
if (qnq_async_evt_rcvd(adapter) && adapter->pvid) {
if (!vlan_tag)
vlan_tag = adapter->pvid;
if (skip_hw_vlan)
*skip_hw_vlan = true;
}
else if (qnq_async_evt_rcvd(adapter) && adapter->pvid)
vlan_tag = adapter->pvid;
if (vlan_tag) {
skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
if (unlikely(!skb))
return skb;
skb->vlan_tci = 0;
if (skip_hw_vlan)
*skip_hw_vlan = true;
}
/* Insert the outer VLAN, if any */

View File

@ -109,7 +109,7 @@ static struct platform_device_id fec_devtype[] = {
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM,
}, {
.name = "mvf-fec",
.name = "mvf600-fec",
.driver_data = FEC_QUIRK_ENET_MAC,
}, {
/* sentinel */
@ -122,7 +122,7 @@ enum imx_fec_type {
IMX27_FEC, /* runs on i.mx27/35/51 */
IMX28_FEC,
IMX6Q_FEC,
MVF_FEC,
MVF600_FEC,
};
static const struct of_device_id fec_dt_ids[] = {
@ -130,7 +130,7 @@ static const struct of_device_id fec_dt_ids[] = {
{ .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], },
{ .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], },
{ .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], },
{ .compatible = "fsl,mvf-fec", .data = &fec_devtype[MVF_FEC], },
{ .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fec_dt_ids);
@ -451,7 +451,7 @@ fec_restart(struct net_device *ndev, int duplex)
netif_device_detach(ndev);
napi_disable(&fep->napi);
netif_stop_queue(ndev);
netif_tx_lock(ndev);
netif_tx_lock_bh(ndev);
}
/* Whack a reset. We should wait for this. */
@ -616,10 +616,10 @@ fec_restart(struct net_device *ndev, int duplex)
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
if (netif_running(ndev)) {
netif_device_attach(ndev);
napi_enable(&fep->napi);
netif_tx_unlock_bh(ndev);
netif_wake_queue(ndev);
netif_tx_unlock(ndev);
napi_enable(&fep->napi);
netif_device_attach(ndev);
}
}

View File

@ -524,6 +524,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
return 0;
no_clock:
iounmap(etsects->regs);
no_ioremap:
release_resource(etsects->rsrc);
no_resource:

View File

@ -195,57 +195,57 @@ enum ipg_regs {
/* TFD data structure masks. */
/* TFDList, TFC */
#define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFF
#define IPG_TFC_FRAMEID 0x000000000000FFFF
#define IPG_TFC_WORDALIGN 0x0000000000030000
#define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000
#define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000
#define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000
#define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000
#define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000
#define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000
#define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000
#define IPG_TFC_TXINDICATE 0x0000000000400000
#define IPG_TFC_TXDMAINDICATE 0x0000000000800000
#define IPG_TFC_FRAGCOUNT 0x000000000F000000
#define IPG_TFC_VLANTAGINSERT 0x0000000010000000
#define IPG_TFC_TFDDONE 0x0000000080000000
#define IPG_TFC_VID 0x00000FFF00000000
#define IPG_TFC_CFI 0x0000100000000000
#define IPG_TFC_USERPRIORITY 0x0000E00000000000
#define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFFULL
#define IPG_TFC_FRAMEID 0x000000000000FFFFULL
#define IPG_TFC_WORDALIGN 0x0000000000030000ULL
#define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000ULL
#define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000ULL
#define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000ULL
#define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000ULL
#define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000ULL
#define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000ULL
#define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000ULL
#define IPG_TFC_TXINDICATE 0x0000000000400000ULL
#define IPG_TFC_TXDMAINDICATE 0x0000000000800000ULL
#define IPG_TFC_FRAGCOUNT 0x000000000F000000ULL
#define IPG_TFC_VLANTAGINSERT 0x0000000010000000ULL
#define IPG_TFC_TFDDONE 0x0000000080000000ULL
#define IPG_TFC_VID 0x00000FFF00000000ULL
#define IPG_TFC_CFI 0x0000100000000000ULL
#define IPG_TFC_USERPRIORITY 0x0000E00000000000ULL
/* TFDList, FragInfo */
#define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFF
#define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFF
#define IPG_TFI_FRAGLEN 0xFFFF000000000000LL
#define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL
#define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFFULL
#define IPG_TFI_FRAGLEN 0xFFFF000000000000ULL
/* RFD data structure masks. */
/* RFDList, RFS */
#define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFF
#define IPG_RFS_RXFRAMELEN 0x000000000000FFFF
#define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000
#define IPG_RFS_RXRUNTFRAME 0x0000000000020000
#define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000
#define IPG_RFS_RXFCSERROR 0x0000000000080000
#define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000
#define IPG_RFS_RXLENGTHERROR 0x0000000000200000
#define IPG_RFS_VLANDETECTED 0x0000000000400000
#define IPG_RFS_TCPDETECTED 0x0000000000800000
#define IPG_RFS_TCPERROR 0x0000000001000000
#define IPG_RFS_UDPDETECTED 0x0000000002000000
#define IPG_RFS_UDPERROR 0x0000000004000000
#define IPG_RFS_IPDETECTED 0x0000000008000000
#define IPG_RFS_IPERROR 0x0000000010000000
#define IPG_RFS_FRAMESTART 0x0000000020000000
#define IPG_RFS_FRAMEEND 0x0000000040000000
#define IPG_RFS_RFDDONE 0x0000000080000000
#define IPG_RFS_TCI 0x0000FFFF00000000
#define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFFULL
#define IPG_RFS_RXFRAMELEN 0x000000000000FFFFULL
#define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000ULL
#define IPG_RFS_RXRUNTFRAME 0x0000000000020000ULL
#define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000ULL
#define IPG_RFS_RXFCSERROR 0x0000000000080000ULL
#define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000ULL
#define IPG_RFS_RXLENGTHERROR 0x0000000000200000ULL
#define IPG_RFS_VLANDETECTED 0x0000000000400000ULL
#define IPG_RFS_TCPDETECTED 0x0000000000800000ULL
#define IPG_RFS_TCPERROR 0x0000000001000000ULL
#define IPG_RFS_UDPDETECTED 0x0000000002000000ULL
#define IPG_RFS_UDPERROR 0x0000000004000000ULL
#define IPG_RFS_IPDETECTED 0x0000000008000000ULL
#define IPG_RFS_IPERROR 0x0000000010000000ULL
#define IPG_RFS_FRAMESTART 0x0000000020000000ULL
#define IPG_RFS_FRAMEEND 0x0000000040000000ULL
#define IPG_RFS_RFDDONE 0x0000000080000000ULL
#define IPG_RFS_TCI 0x0000FFFF00000000ULL
/* RFDList, FragInfo */
#define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFF
#define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFF
#define IPG_RFI_FRAGLEN 0xFFFF000000000000LL
#define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL
#define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFFULL
#define IPG_RFI_FRAGLEN 0xFFFF000000000000ULL
/* I/O Register masks. */

View File

@ -867,7 +867,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
int reclaimed;
__netif_tx_lock(nq, smp_processor_id());
__netif_tx_lock_bh(nq);
reclaimed = 0;
while (reclaimed < budget && txq->tx_desc_count > 0) {
@ -913,7 +913,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
dev_kfree_skb(skb);
}
__netif_tx_unlock(nq);
__netif_tx_unlock_bh(nq);
if (reclaimed < budget)
mp->work_tx &= ~(1 << txq->index);
@ -2745,7 +2745,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128);
netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, NAPI_POLL_WEIGHT);
init_timer(&mp->rx_oom);
mp->rx_oom.data = (unsigned long)mp;

View File

@ -907,8 +907,11 @@ struct qlcnic_ipaddr {
#define QLCNIC_FW_HANG 0x4000
#define QLCNIC_FW_LRO_MSS_CAP 0x8000
#define QLCNIC_TX_INTR_SHARED 0x10000
#define QLCNIC_APP_CHANGED_FLAGS 0x20000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
#define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
#define QLCNIC_MSIX_TBL_SPACE 8192
@ -1034,6 +1037,7 @@ struct qlcnic_adapter {
spinlock_t rx_mac_learn_lock;
u32 file_prd_off; /*File fw product offset*/
u32 fw_version;
u32 offload_flags;
const struct firmware *fw;
};
@ -1542,6 +1546,8 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
int qlcnic_read_mac_addr(struct qlcnic_adapter *);
int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *);
void qlcnic_vf_add_mc_list(struct net_device *, u16);

View File

@ -382,8 +382,6 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter)
clear_bit(__QLCNIC_RESETTING, &adapter->state);
dev_err(&adapter->pdev->dev, "%s:\n", __func__);
adapter->netdev->trans_start = jiffies;
return 0;
}

View File

@ -973,16 +973,57 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
return rc;
}
static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
netdev_features_t features)
{
u32 offload_flags = adapter->offload_flags;
if (offload_flags & BIT_0) {
features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM;
adapter->rx_csum = 1;
if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
if (!(offload_flags & BIT_1))
features &= ~NETIF_F_TSO;
else
features |= NETIF_F_TSO;
if (!(offload_flags & BIT_2))
features &= ~NETIF_F_TSO6;
else
features |= NETIF_F_TSO6;
}
} else {
features &= ~(NETIF_F_RXCSUM |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM);
if (QLCNIC_IS_TSO_CAPABLE(adapter))
features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
adapter->rx_csum = 0;
}
return features;
}
netdev_features_t qlcnic_fix_features(struct net_device *netdev,
netdev_features_t features)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
netdev_features_t changed;
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) &&
qlcnic_82xx_check(adapter)) {
netdev_features_t changed = features ^ netdev->features;
features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
if (qlcnic_82xx_check(adapter) &&
(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) {
features = qlcnic_process_flags(adapter, features);
} else {
changed = features ^ netdev->features;
features ^= changed & (NETIF_F_RXCSUM |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6);
}
}
if (!(features & NETIF_F_RXCSUM))

View File

@ -84,14 +84,9 @@ static int qlcnic_start_firmware(struct qlcnic_adapter *);
static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16);
static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16);
#define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
@ -1074,8 +1069,6 @@ void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
if (!esw_cfg->promisc_mode)
adapter->flags |= QLCNIC_PROMISC_DISABLED;
qlcnic_set_netdev_features(adapter, esw_cfg);
}
int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
@ -1090,51 +1083,23 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
return -EIO;
qlcnic_set_vlan_config(adapter, &esw_cfg);
qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
qlcnic_set_netdev_features(adapter, &esw_cfg);
return 0;
}
static void
qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
{
struct net_device *netdev = adapter->netdev;
unsigned long features, vlan_features;
if (qlcnic_83xx_check(adapter))
return;
features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_IPV6_CSUM | NETIF_F_GRO);
vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM);
if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
features |= (NETIF_F_TSO | NETIF_F_TSO6);
vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
}
if (netdev->features & NETIF_F_LRO)
features |= NETIF_F_LRO;
if (esw_cfg->offload_flags & BIT_0) {
netdev->features |= features;
adapter->rx_csum = 1;
if (!(esw_cfg->offload_flags & BIT_1)) {
netdev->features &= ~NETIF_F_TSO;
features &= ~NETIF_F_TSO;
}
if (!(esw_cfg->offload_flags & BIT_2)) {
netdev->features &= ~NETIF_F_TSO6;
features &= ~NETIF_F_TSO6;
}
} else {
netdev->features &= ~features;
features &= ~features;
adapter->rx_csum = 0;
}
netdev->vlan_features = (features & vlan_features);
adapter->offload_flags = esw_cfg->offload_flags;
adapter->flags |= QLCNIC_APP_CHANGED_FLAGS;
netdev_update_features(netdev);
adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS;
}
static int
@ -2016,8 +1981,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_pcie_error_reporting(pdev);
ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL);
if (!ahw)
if (!ahw) {
err = -ENOMEM;
goto err_out_free_res;
}
switch (ent->device) {
case PCI_DEVICE_ID_QLOGIC_QLE824X:
@ -2053,6 +2020,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic");
if (adapter->qlcnic_wq == NULL) {
err = -ENOMEM;
dev_err(&pdev->dev, "Failed to create workqueue\n");
goto err_out_free_netdev;
}
@ -2133,6 +2101,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_disable_msi;
}
err = qlcnic_get_act_pci_func(adapter);
if (err)
goto err_out_disable_mbx_intr;
err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
if (err)
goto err_out_disable_mbx_intr;
@ -2162,9 +2134,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
if (qlcnic_get_act_pci_func(adapter))
goto err_out_disable_mbx_intr;
if (adapter->drv_mac_learn)
qlcnic_alloc_lb_filters_mem(adapter);
@ -3149,10 +3118,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
if (adapter->need_fw_reset)
goto detach;
if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) {
if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
qlcnic_reset_hw_context(adapter);
adapter->netdev->trans_start = jiffies;
}
return 0;
}

View File

@ -1734,7 +1734,6 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
if (!qlcnic_sriov_vf_reinit_driver(adapter)) {
qlcnic_sriov_vf_attach(adapter);
adapter->netdev->trans_start = jiffies;
adapter->tx_timeo_cnt = 0;
adapter->reset_ctx_cnt = 0;
adapter->fw_fail_cnt = 0;

View File

@ -544,6 +544,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
switch (esw_cfg[i].op_mode) {
case QLCNIC_PORT_DEFAULTS:
qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
rtnl_lock();
qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
rtnl_unlock();
break;
case QLCNIC_ADD_VLAN:
qlcnic_set_vlan_config(adapter, &esw_cfg[i]);

View File

@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_private *cp)
cp->dev->stats.tx_dropped++;
}
}
netdev_reset_queue(cp->dev);
memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);

View File

@ -5856,7 +5856,20 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
return -EIO;
}
static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
static bool rtl_skb_pad(struct sk_buff *skb)
{
if (skb_padto(skb, ETH_ZLEN))
return false;
skb_put(skb, ETH_ZLEN - skb->len);
return true;
}
static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
{
return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
}
static inline bool rtl8169_tso_csum(struct rtl8169_private *tp,
struct sk_buff *skb, u32 *opts)
{
const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
@ -5869,13 +5882,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb);
if (ip->protocol == IPPROTO_TCP)
opts[offset] |= info->checksum.tcp;
else if (ip->protocol == IPPROTO_UDP)
opts[offset] |= info->checksum.udp;
else
WARN_ON_ONCE(1);
} else {
if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
return rtl_skb_pad(skb);
}
return true;
}
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@ -5896,17 +5916,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
goto err_stop_0;
}
/* 8168evl does not automatically pad to minimum length. */
if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 &&
skb->len < ETH_ZLEN)) {
if (skb_padto(skb, ETH_ZLEN))
goto err_update_stats;
skb_put(skb, ETH_ZLEN - skb->len);
}
if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
goto err_stop_0;
opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
opts[0] = DescOwn;
if (!rtl8169_tso_csum(tp, skb, opts))
goto err_update_stats;
len = skb_headlen(skb);
mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(d, mapping))) {
@ -5918,11 +5936,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
tp->tx_skb[entry].len = len;
txd->addr = cpu_to_le64(mapping);
opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
opts[0] = DescOwn;
rtl8169_tso_csum(tp, skb, opts);
frags = rtl8169_xmit_frags(tp, skb, opts);
if (frags < 0)
goto err_dma_1;

View File

@ -638,14 +638,16 @@ static void efx_start_datapath(struct efx_nic *efx)
EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
efx->type->rx_buffer_padding);
rx_buf_len = (sizeof(struct efx_rx_page_state) +
EFX_PAGE_IP_ALIGN + efx->rx_dma_len);
NET_IP_ALIGN + efx->rx_dma_len);
if (rx_buf_len <= PAGE_SIZE) {
efx->rx_scatter = false;
efx->rx_buffer_order = 0;
} else if (efx->type->can_rx_scatter) {
BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES);
BUILD_BUG_ON(sizeof(struct efx_rx_page_state) +
EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE >
PAGE_SIZE / 2);
2 * ALIGN(NET_IP_ALIGN + EFX_RX_USR_BUF_SIZE,
EFX_RX_BUF_ALIGNMENT) >
PAGE_SIZE);
efx->rx_scatter = true;
efx->rx_dma_len = EFX_RX_USR_BUF_SIZE;
efx->rx_buffer_order = 0;

View File

@ -72,8 +72,20 @@
/* Maximum possible MTU the driver supports */
#define EFX_MAX_MTU (9 * 1024)
/* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page. */
#define EFX_RX_USR_BUF_SIZE 1824
/* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page,
* and should be a multiple of the cache line size.
*/
#define EFX_RX_USR_BUF_SIZE (2048 - 256)
/* If possible, we should ensure cache line alignment at start and end
* of every buffer. Otherwise, we just need to ensure 4-byte
* alignment of the network header.
*/
#if NET_IP_ALIGN == 0
#define EFX_RX_BUF_ALIGNMENT L1_CACHE_BYTES
#else
#define EFX_RX_BUF_ALIGNMENT 4
#endif
/* Forward declare Precision Time Protocol (PTP) support structure. */
struct efx_ptp_data;
@ -467,25 +479,12 @@ enum nic_state {
STATE_RECOVERY = 3, /* device recovering from PCI error */
};
/*
* Alignment of page-allocated RX buffers
*
* Controls the number of bytes inserted at the start of an RX buffer.
* This is the equivalent of NET_IP_ALIGN [which controls the alignment
* of the skb->head for hardware DMA].
*/
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
#define EFX_PAGE_IP_ALIGN 0
#else
#define EFX_PAGE_IP_ALIGN NET_IP_ALIGN
#endif
/*
* Alignment of the skb->head which wraps a page-allocated RX buffer
*
* The skb allocated to wrap an rx_buffer can have this alignment. Since
* the data is memcpy'd from the rx_buf, it does not need to be equal to
* EFX_PAGE_IP_ALIGN.
* NET_IP_ALIGN.
*/
#define EFX_PAGE_SKB_ALIGN 2

View File

@ -93,8 +93,8 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx,
void efx_rx_config_page_split(struct efx_nic *efx)
{
efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + EFX_PAGE_IP_ALIGN,
L1_CACHE_BYTES);
efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
EFX_RX_BUF_ALIGNMENT);
efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
efx->rx_page_buf_step);
@ -188,9 +188,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
do {
index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
rx_buf->page = page;
rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
rx_buf->page_offset = page_offset + NET_IP_ALIGN;
rx_buf->len = efx->rx_dma_len;
rx_buf->flags = 0;
++rx_queue->added_count;

View File

@ -582,6 +582,7 @@ static const struct usb_device_id products[] = {
{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 */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
{QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)}, /* Cinterion PLxx */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */

View File

@ -130,19 +130,23 @@ struct rtl8150 {
struct usb_device *udev;
struct tasklet_struct tl;
struct net_device *netdev;
struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
struct urb *rx_urb, *tx_urb, *intr_urb;
struct sk_buff *tx_skb, *rx_skb;
struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE];
spinlock_t rx_pool_lock;
struct usb_ctrlrequest dr;
int intr_interval;
__le16 rx_creg;
u8 *intr_buff;
u8 phy;
};
typedef struct rtl8150 rtl8150_t;
struct async_req {
struct usb_ctrlrequest dr;
u16 rx_creg;
};
static const char driver_name [] = "rtl8150";
/*
@ -164,51 +168,47 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
indx, 0, data, size, 500);
}
static void ctrl_callback(struct urb *urb)
static void async_set_reg_cb(struct urb *urb)
{
rtl8150_t *dev;
struct async_req *req = (struct async_req *)urb->context;
int status = urb->status;
switch (status) {
case 0:
break;
case -EINPROGRESS:
break;
case -ENOENT:
break;
default:
if (printk_ratelimit())
dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
}
dev = urb->context;
clear_bit(RX_REG_SET, &dev->flags);
if (status < 0)
dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status);
kfree(req);
usb_free_urb(urb);
}
static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg)
{
int ret;
int res = -ENOMEM;
struct urb *async_urb;
struct async_req *req;
if (test_bit(RX_REG_SET, &dev->flags))
return -EAGAIN;
dev->dr.bRequestType = RTL8150_REQT_WRITE;
dev->dr.bRequest = RTL8150_REQ_SET_REGS;
dev->dr.wValue = cpu_to_le16(indx);
dev->dr.wIndex = 0;
dev->dr.wLength = cpu_to_le16(size);
dev->ctrl_urb->transfer_buffer_length = size;
usb_fill_control_urb(dev->ctrl_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
&dev->rx_creg, size, ctrl_callback, dev);
if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
if (ret == -ENODEV)
req = kmalloc(sizeof(struct async_req), GFP_ATOMIC);
if (req == NULL)
return res;
async_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (async_urb == NULL) {
kfree(req);
return res;
}
req->rx_creg = cpu_to_le16(reg);
req->dr.bRequestType = RTL8150_REQT_WRITE;
req->dr.bRequest = RTL8150_REQ_SET_REGS;
req->dr.wIndex = 0;
req->dr.wValue = cpu_to_le16(indx);
req->dr.wLength = cpu_to_le16(size);
usb_fill_control_urb(async_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (void *)&req->dr,
&req->rx_creg, size, async_set_reg_cb, req);
res = usb_submit_urb(async_urb, GFP_ATOMIC);
if (res) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
dev_err(&dev->udev->dev,
"control request submission failed: %d\n", ret);
} else
set_bit(RX_REG_SET, &dev->flags);
return ret;
dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res);
}
return res;
}
static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg)
@ -330,13 +330,6 @@ static int alloc_all_urbs(rtl8150_t * dev)
usb_free_urb(dev->tx_urb);
return 0;
}
dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->ctrl_urb) {
usb_free_urb(dev->rx_urb);
usb_free_urb(dev->tx_urb);
usb_free_urb(dev->intr_urb);
return 0;
}
return 1;
}
@ -346,7 +339,6 @@ static void free_all_urbs(rtl8150_t * dev)
usb_free_urb(dev->rx_urb);
usb_free_urb(dev->tx_urb);
usb_free_urb(dev->intr_urb);
usb_free_urb(dev->ctrl_urb);
}
static void unlink_all_urbs(rtl8150_t * dev)
@ -354,7 +346,6 @@ static void unlink_all_urbs(rtl8150_t * dev)
usb_kill_urb(dev->rx_urb);
usb_kill_urb(dev->tx_urb);
usb_kill_urb(dev->intr_urb);
usb_kill_urb(dev->ctrl_urb);
}
static inline struct sk_buff *pull_skb(rtl8150_t *dev)
@ -629,7 +620,6 @@ static int enable_net_traffic(rtl8150_t * dev)
}
/* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
rcr = 0x9e;
dev->rx_creg = cpu_to_le16(rcr);
tcr = 0xd8;
cr = 0x0c;
if (!(rcr & 0x80))
@ -662,20 +652,22 @@ static void rtl8150_tx_timeout(struct net_device *netdev)
static void rtl8150_set_multicast(struct net_device *netdev)
{
rtl8150_t *dev = netdev_priv(netdev);
u16 rx_creg = 0x9e;
netif_stop_queue(netdev);
if (netdev->flags & IFF_PROMISC) {
dev->rx_creg |= cpu_to_le16(0x0001);
rx_creg |= 0x0001;
dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
} else if (!netdev_mc_empty(netdev) ||
(netdev->flags & IFF_ALLMULTI)) {
dev->rx_creg &= cpu_to_le16(0xfffe);
dev->rx_creg |= cpu_to_le16(0x0002);
rx_creg &= 0xfffe;
rx_creg |= 0x0002;
dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
} else {
/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
dev->rx_creg &= cpu_to_le16(0x00fc);
rx_creg &= 0x00fc;
}
async_set_registers(dev, RCR, 2);
async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg);
netif_wake_queue(netdev);
}

View File

@ -636,10 +636,11 @@ static int virtnet_open(struct net_device *dev)
struct virtnet_info *vi = netdev_priv(dev);
int i;
for (i = 0; i < vi->curr_queue_pairs; i++) {
/* Make sure we have some buffers: if oom use wq. */
if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
schedule_delayed_work(&vi->refill, 0);
for (i = 0; i < vi->max_queue_pairs; i++) {
if (i < vi->curr_queue_pairs)
/* Make sure we have some buffers: if oom use wq. */
if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
schedule_delayed_work(&vi->refill, 0);
virtnet_napi_enable(&vi->rq[i]);
}

View File

@ -301,7 +301,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan,
}
/* Look up Ethernet address in forwarding table */
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
@ -316,6 +316,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
return NULL;
}
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
if (f)
f->used = jiffies;
return f;
}
/* Add/update destinations for multicast */
static int vxlan_fdb_append(struct vxlan_fdb *f,
__be32 ip, __be16 port, __u32 vni, __u32 ifindex)
@ -353,7 +365,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
struct vxlan_fdb *f;
int notify = 0;
f = vxlan_find_mac(vxlan, mac);
f = __vxlan_find_mac(vxlan, mac);
if (f) {
if (flags & NLM_F_EXCL) {
netdev_dbg(vxlan->dev,
@ -563,7 +575,6 @@ static void vxlan_snoop(struct net_device *dev,
f = vxlan_find_mac(vxlan, src_mac);
if (likely(f)) {
f->used = jiffies;
if (likely(f->remote.remote_ip == src_ip))
return;

View File

@ -965,7 +965,7 @@ static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
{
int i;
if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah))
if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah))
return;
for (i = 0; i < AR9300_MAX_CHAINS; i++) {

View File

@ -1020,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = {
{0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
{0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
{0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},

View File

@ -254,6 +254,7 @@ struct ath_atx_tid {
int sched;
int paused;
u8 state;
bool stop_cb;
};
struct ath_node {
@ -351,7 +352,8 @@ void ath_tx_tasklet(struct ath_softc *sc);
void ath_tx_edma_tasklet(struct ath_softc *sc);
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
bool flush);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);

View File

@ -2008,6 +2008,14 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
WARN_ON(i != ATH9K_SSTATS_LEN);
}
void ath9k_deinit_debug(struct ath_softc *sc)
{
if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
relay_close(sc->rfs_chan_spec_scan);
sc->rfs_chan_spec_scan = NULL;
}
}
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);

View File

@ -304,6 +304,7 @@ struct ath9k_debug {
};
int ath9k_init_debug(struct ath_hw *ah);
void ath9k_deinit_debug(struct ath_softc *sc);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
@ -339,6 +340,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
return 0;
}
static inline void ath9k_deinit_debug(struct ath_softc *sc)
{
}
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
enum ath9k_int status)
{

View File

@ -906,7 +906,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
if (!ath_is_world_regd(reg)) {
error = regulatory_hint(hw->wiphy, reg->alpha2);
if (error)
goto unregister;
goto debug_cleanup;
}
ath_init_leds(sc);
@ -914,6 +914,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
return 0;
debug_cleanup:
ath9k_deinit_debug(sc);
unregister:
ieee80211_unregister_hw(hw);
rx_cleanup:
@ -942,11 +944,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
sc->dfs_detector->exit(sc->dfs_detector);
ath9k_eeprom_release(sc);
if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
relay_close(sc->rfs_chan_spec_scan);
sc->rfs_chan_spec_scan = NULL;
}
}
void ath9k_deinit_device(struct ath_softc *sc)
@ -960,6 +957,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
ath9k_ps_restore(sc);
ath9k_deinit_debug(sc);
ieee80211_unregister_hw(hw);
ath_rx_cleanup(sc);
ath9k_deinit_softc(sc);

View File

@ -1687,6 +1687,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
u16 tid, u16 *ssn, u8 buf_size)
{
struct ath_softc *sc = hw->priv;
bool flush = false;
int ret = 0;
local_bh_disable();
@ -1703,12 +1704,13 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
ath9k_ps_restore(sc);
break;
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
flush = true;
case IEEE80211_AMPDU_TX_STOP_CONT:
ath9k_ps_wakeup(sc);
ath_tx_aggr_stop(sc, sta, tid);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
if (ath_tx_aggr_stop(sc, sta, tid, flush))
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
ath9k_ps_restore(sc);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:

View File

@ -164,7 +164,20 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
ARRAY_SIZE(bf->rates));
}
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_CLEANUP;
if (!tid->stop_cb)
return;
ieee80211_start_tx_ba_cb_irqsafe(tid->an->vif, tid->an->sta->addr,
tid->tidno);
tid->stop_cb = false;
}
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
bool flush_packets)
{
struct ath_txq *txq = tid->ac->txq;
struct sk_buff *skb;
@ -181,16 +194,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
while ((skb = __skb_dequeue(&tid->buf_q))) {
fi = get_frame_info(skb);
bf = fi->bf;
if (!bf && !flush_packets)
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
if (!bf) {
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
if (!bf) {
ieee80211_free_txskb(sc->hw, skb);
continue;
}
ieee80211_free_txskb(sc->hw, skb);
continue;
}
if (fi->retries) {
if (fi->retries || flush_packets) {
list_add_tail(&bf->list, &bf_head);
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@ -201,12 +213,10 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
}
}
if (tid->baw_head == tid->baw_tail) {
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_CLEANUP;
}
if (tid->baw_head == tid->baw_tail)
ath_tx_clear_tid(sc, tid);
if (sendbar) {
if (sendbar && !flush_packets) {
ath_txq_unlock(sc, txq);
ath_send_bar(tid, tid->seq_start);
ath_txq_lock(sc, txq);
@ -277,9 +287,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
list_add_tail(&bf->list, &bf_head);
if (fi->retries)
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
}
@ -602,7 +610,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
if (tid->state & AGGR_CLEANUP)
ath_tx_flush_tid(sc, tid);
ath_tx_flush_tid(sc, tid, false);
rcu_read_unlock();
@ -620,6 +628,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
struct ath_tx_status *ts, struct ath_buf *bf,
struct list_head *bf_head)
{
struct ieee80211_tx_info *info;
bool txok, flush;
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
@ -631,8 +640,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
txq->axq_ampdu_depth--;
if (!bf_isampdu(bf)) {
if (!flush)
if (!flush) {
info = IEEE80211_SKB_CB(bf->bf_mpdu);
memcpy(info->control.rates, bf->rates,
sizeof(info->control.rates));
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
}
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
} else
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
@ -676,7 +689,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
rates = bf->rates;
/*
* Find the lowest frame length among the rate series that will have a
@ -1256,18 +1269,23 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
return 0;
}
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
bool flush)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
struct ath_txq *txq = txtid->ac->txq;
bool ret = !flush;
if (flush)
txtid->stop_cb = false;
if (txtid->state & AGGR_CLEANUP)
return;
return false;
if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
txtid->state &= ~AGGR_ADDBA_PROGRESS;
return;
return ret;
}
ath_txq_lock(sc, txq);
@ -1279,13 +1297,17 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
* TID can only be reused after all in-progress subframes have been
* completed.
*/
if (txtid->baw_head != txtid->baw_tail)
if (txtid->baw_head != txtid->baw_tail) {
txtid->state |= AGGR_CLEANUP;
else
ret = false;
txtid->stop_cb = !flush;
} else {
txtid->state &= ~AGGR_ADDBA_COMPLETE;
}
ath_tx_flush_tid(sc, txtid);
ath_tx_flush_tid(sc, txtid, flush);
ath_txq_unlock_complete(sc, txq);
return ret;
}
void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
@ -2415,6 +2437,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
tid->ac = &an->ac[acno];
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_ADDBA_PROGRESS;
tid->stop_cb = false;
}
for (acno = 0, ac = &an->ac[acno];
@ -2451,8 +2474,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
}
ath_tid_drain(sc, txq, tid);
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_CLEANUP;
ath_tx_clear_tid(sc, tid);
ath_txq_unlock(sc, txq);
}

View File

@ -4140,6 +4140,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO)
},
{
.max = 1,
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
}
};
static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
{
@ -4197,7 +4201,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE);
wiphy->iface_combinations = brcmf_iface_combos;
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;

View File

@ -1423,7 +1423,7 @@ il_setup_rx_scan_handlers(struct il_priv *il)
}
EXPORT_SYMBOL(il_setup_rx_scan_handlers);
inline u16
u16
il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band,
u8 n_probes)
{

View File

@ -173,6 +173,8 @@ enum {
REPLY_DEBUG_CMD = 0xf0,
DEBUG_LOG_MSG = 0xf7,
MCAST_FILTER_CMD = 0xd0,
/* D3 commands/notifications */
D3_CONFIG_CMD = 0xd3,
PROT_OFFLOAD_CONFIG_CMD = 0xd4,
@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd {
u8 data[0];
} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
#define MAX_PORT_ID_NUM 2
/**
* struct iwl_mcast_filter_cmd - configure multicast filter.
* @filter_own: Set 1 to filter out multicast packets sent by station itself
* @port_id: Multicast MAC addresses array specifier. This is a strange way
* to identify network interface adopted in host-device IF.
* It is used by FW as index in array of addresses. This array has
* MAX_PORT_ID_NUM members.
* @count: Number of MAC addresses in the array
* @pass_all: Set 1 to pass all multicast packets.
* @bssid: current association BSSID.
* @addr_list: Place holder for array of MAC addresses.
* IMPORTANT: add padding if necessary to ensure DWORD alignment.
*/
struct iwl_mcast_filter_cmd {
u8 filter_own;
u8 port_id;
u8 count;
u8 pass_all;
u8 bssid[6];
u8 reserved[2];
u8 addr_list[0];
} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
#endif /* __fw_api_h__ */

View File

@ -586,10 +586,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
*/
static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_mac_data_sta *ctxt_sta)
struct iwl_mac_data_sta *ctxt_sta,
bool force_assoc_off)
{
/* We need the dtim_period to set the MAC as associated */
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) {
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
!force_assoc_off) {
u32 dtim_offs;
/*
@ -659,7 +661,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
/* Fill the data specific for station mode */
iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta,
action == FW_CTXT_ACTION_ADD);
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
}
@ -677,7 +680,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
/* Fill the data specific for station mode */
iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);
iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta,
action == FW_CTXT_ACTION_ADD);
cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
IEEE80211_P2P_OPPPS_CTWINDOW_MASK);

View File

@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
*total_flags = 0;
}
static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mcast_filter_cmd mcast_filter_cmd = {
.pass_all = 1,
};
memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
sizeof(mcast_filter_cmd),
&mcast_filter_cmd);
}
static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
return;
}
iwl_mvm_bt_coex_vif_assoc(mvm, vif);
iwl_mvm_configure_mcast_filter(mvm, vif);
} else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
/* remove AP station now that the MAC is unassoc */
ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@ -931,7 +946,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
switch (cmd) {
case STA_NOTIFY_SLEEP:
if (atomic_read(&mvmsta->pending_frames) > 0)
if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
ieee80211_sta_block_awake(hw, sta, true);
/*
* The fw updates the STA to be asleep. Tx packets on the Tx

View File

@ -292,6 +292,7 @@ struct iwl_mvm {
struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
struct work_struct sta_drained_wk;
unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
atomic_t pending_frames[IWL_MVM_STATION_COUNT];
/* configured by mac80211 */
u32 rts_threshold;

View File

@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(BT_COEX_PROT_ENV),
CMD(BT_PROFILE_NOTIFICATION),
CMD(BT_CONFIG),
CMD(MCAST_FILTER_CMD),
};
#undef CMD

View File

@ -298,6 +298,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
else
cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
/*
* TODO: This is a WA due to a bug in the FW AUX framework that does not
* properly handle time events that fail to be scheduled
*/
cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
cmd->repeats = cpu_to_le32(1);
/*

View File

@ -219,7 +219,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
/* HW restart, don't assume the memory has been zeroed */
atomic_set(&mvm_sta->pending_frames, 0);
atomic_set(&mvm->pending_frames[sta_id], 0);
mvm_sta->tid_disable_agg = 0;
mvm_sta->tfd_queue_msk = 0;
for (i = 0; i < IEEE80211_NUM_ACS; i++)
@ -406,15 +406,22 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
}
/*
* Make sure that the tx response code sees the station as -EBUSY and
* calls the drain worker.
*/
spin_lock_bh(&mvm_sta->lock);
/*
* There are frames pending on the AC queues for this station.
* We need to wait until all the frames are drained...
*/
if (atomic_read(&mvm_sta->pending_frames)) {
ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) {
rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
ERR_PTR(-EBUSY));
spin_unlock_bh(&mvm_sta->lock);
ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
} else {
spin_unlock_bh(&mvm_sta->lock);
ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
}

View File

@ -274,7 +274,6 @@ struct iwl_mvm_tid_data {
* @bt_reduced_txpower: is reduced tx power enabled for this station
* @lock: lock to protect the whole struct. Since %tid_data is access from Tx
* and from Tx response flow, it needs a spinlock.
* @pending_frames: number of frames for this STA on the shared Tx queues.
* @tid_data: per tid data. Look at %iwl_mvm_tid_data.
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
@ -290,7 +289,6 @@ struct iwl_mvm_sta {
u8 max_agg_bufsize;
bool bt_reduced_txpower;
spinlock_t lock;
atomic_t pending_frames;
struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
struct iwl_lq_sta lq_sta;
struct ieee80211_vif *vif;

View File

@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
spin_unlock(&mvmsta->lock);
if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
txq_id < IWL_MVM_FIRST_AGG_QUEUE)
atomic_inc(&mvmsta->pending_frames);
if (txq_id < IWL_MVM_FIRST_AGG_QUEUE)
atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
return 0;
@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/*
* If the txq is not an AMPDU queue, there is no chance we freed
* several skbs. Check that out...
* If there are no pending frames for this STA, notify mac80211 that
* this station can go to sleep in its STA table.
*/
if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
!WARN_ON(skb_freed > 1) &&
mvmsta->vif->type == NL80211_IFTYPE_AP &&
atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
ieee80211_sta_block_awake(mvm->hw, sta, false);
set_bit(sta_id, mvm->sta_drained);
schedule_work(&mvm->sta_drained_wk);
if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) &&
atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
if (mvmsta) {
/*
* If there are no pending frames for this STA, notify
* mac80211 that this station can go to sleep in its
* STA table.
*/
if (mvmsta->vif->type == NL80211_IFTYPE_AP)
ieee80211_sta_block_awake(mvm->hw, sta, false);
/*
* We might very well have taken mvmsta pointer while
* the station was being removed. The remove flow might
* have seen a pending_frame (because we didn't take
* the lock) even if now the queues are drained. So make
* really sure now that this the station is not being
* removed. If it is, run the drain worker to remove it.
*/
spin_lock_bh(&mvmsta->lock);
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
if (IS_ERR_OR_NULL(sta)) {
/*
* Station disappeared in the meantime:
* so we are draining.
*/
set_bit(sta_id, mvm->sta_drained);
schedule_work(&mvm->sta_drained_wk);
}
spin_unlock_bh(&mvmsta->lock);
} else if (!mvmsta) {
/* Tx response without STA, so we are draining */
set_bit(sta_id, mvm->sta_drained);
schedule_work(&mvm->sta_drained_wk);
}
}
rcu_read_unlock();

View File

@ -1723,11 +1723,11 @@ static void mac80211_hwsim_free(void)
class_destroy(hwsim_class);
}
static struct device_driver mac80211_hwsim_driver = {
.name = "mac80211_hwsim",
.bus = &platform_bus_type,
.owner = THIS_MODULE,
static struct platform_driver mac80211_hwsim_driver = {
.driver = {
.name = "mac80211_hwsim",
.owner = THIS_MODULE,
},
};
static const struct net_device_ops hwsim_netdev_ops = {
@ -2219,7 +2219,7 @@ static int __init init_mac80211_hwsim(void)
spin_lock_init(&hwsim_radio_lock);
INIT_LIST_HEAD(&hwsim_radios);
err = driver_register(&mac80211_hwsim_driver);
err = platform_driver_register(&mac80211_hwsim_driver);
if (err)
return err;
@ -2254,7 +2254,7 @@ static int __init init_mac80211_hwsim(void)
err = -ENOMEM;
goto failed_drvdata;
}
data->dev->driver = &mac80211_hwsim_driver;
data->dev->driver = &mac80211_hwsim_driver.driver;
err = device_bind_driver(data->dev);
if (err != 0) {
printk(KERN_DEBUG
@ -2564,7 +2564,7 @@ static int __init init_mac80211_hwsim(void)
failed:
mac80211_hwsim_free();
failed_unregister_driver:
driver_unregister(&mac80211_hwsim_driver);
platform_driver_unregister(&mac80211_hwsim_driver);
return err;
}
module_init(init_mac80211_hwsim);
@ -2577,6 +2577,6 @@ static void __exit exit_mac80211_hwsim(void)
mac80211_hwsim_free();
unregister_netdev(hwsim_mon);
driver_unregister(&mac80211_hwsim_driver);
platform_driver_unregister(&mac80211_hwsim_driver);
}
module_exit(exit_mac80211_hwsim);

View File

@ -550,7 +550,7 @@ do { \
rxmcs == DESC92C_RATE11M)
struct phy_rx_agc_info_t {
#if __LITTLE_ENDIAN
#ifdef __LITTLE_ENDIAN
u8 gain:7, trsw:1;
#else
u8 trsw:1, gain:7;
@ -574,7 +574,7 @@ struct phy_status_rpt {
u8 stream_target_csi[2];
u8 sig_evm;
u8 rsvd_3;
#if __LITTLE_ENDIAN
#ifdef __LITTLE_ENDIAN
u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
u8 sgi_en:1;
u8 rxsc:2;

View File

@ -349,6 +349,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
{RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
{RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/
{RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
{RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
{RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/

View File

@ -134,7 +134,10 @@ struct bcma_host_ops {
#define BCMA_CORE_I2S 0x834
#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
#define BCMA_CORE_ARM_CR4 0x83e
#define BCMA_CORE_PHY_AC 0x83B
#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */
#define BCMA_CORE_USB30_DEV 0x83D
#define BCMA_CORE_ARM_CR4 0x83E
#define BCMA_CORE_DEFAULT 0xFFF
#define BCMA_MAX_NR_CORES 16

View File

@ -1,3 +1,6 @@
#ifndef _LINUX_BRCMPHY_H
#define _LINUX_BRCMPHY_H
#define PHY_ID_BCM50610 0x0143bd60
#define PHY_ID_BCM50610M 0x0143bd70
#define PHY_ID_BCM5241 0x0143bc30
@ -29,3 +32,5 @@
#define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000
#define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000
#define PHY_BCM_FLAGS_VALID 0x80000000
#endif /* _LINUX_BRCMPHY_H */

View File

@ -2733,6 +2733,17 @@ static inline netdev_features_t netdev_get_wanted_features(
}
netdev_features_t netdev_increment_features(netdev_features_t all,
netdev_features_t one, netdev_features_t mask);
/* Allow TSO being used on stacked device :
* Performing the GSO segmentation before last device
* is a performance improvement.
*/
static inline netdev_features_t netdev_add_tso_features(netdev_features_t features,
netdev_features_t mask)
{
return netdev_increment_features(features, NETIF_F_ALL_TSO, mask);
}
int __netdev_update_features(struct net_device *dev);
void netdev_update_features(struct net_device *dev);
void netdev_change_features(struct net_device *dev);

View File

@ -3043,7 +3043,8 @@ void ieee80211_napi_complete(struct ieee80211_hw *hw);
* This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls to
* this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be
* mixed for a single hardware.
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* In process context use instead ieee80211_rx_ni().
*
@ -3059,7 +3060,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
* (internally defers to a tasklet.)
*
* Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not
* be mixed for a single hardware.
* be mixed for a single hardware.Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* @hw: the hardware this frame came in on
* @skb: the buffer to receive, owned by mac80211 after this call
@ -3073,7 +3075,8 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
* (internally disables bottom halves).
*
* Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may
* not be mixed for a single hardware.
* not be mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* @hw: the hardware this frame came in on
* @skb: the buffer to receive, owned by mac80211 after this call
@ -3196,7 +3199,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
* This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls
* to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
* may not be mixed for a single hardware.
* may not be mixed for a single hardware. Must not run concurrently with
* ieee80211_rx() or ieee80211_rx_ni().
*
* @hw: the hardware the frame was transmitted by
* @skb: the frame that was transmitted, owned by mac80211 after this call

View File

@ -30,7 +30,8 @@ struct nf_loginfo {
} u;
};
typedef void nf_logfn(u_int8_t pf,
typedef void nf_logfn(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,

View File

@ -2,7 +2,8 @@
#define _KER_NFNETLINK_LOG_H
void
nfulnl_log_packet(u_int8_t pf,
nfulnl_log_packet(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,

View File

@ -871,10 +871,10 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
*/
del_timer_sync(&app->join_timer);
spin_lock(&app->lock);
spin_lock_bh(&app->lock);
mrp_mad_event(app, MRP_EVENT_TX);
mrp_pdu_queue(app);
spin_unlock(&app->lock);
spin_unlock_bh(&app->lock);
mrp_queue_xmit(app);

View File

@ -181,6 +181,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
batadv_originator_free(bat_priv);
free_percpu(bat_priv->bat_counters);
bat_priv->bat_counters = NULL;
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
}

View File

@ -156,12 +156,28 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
kfree(orig_node);
}
/**
* batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
* schedule an rcu callback for freeing it
* @orig_node: the orig node to free
*/
void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
{
if (atomic_dec_and_test(&orig_node->refcount))
call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
}
/**
* batadv_orig_node_free_ref_now - decrement the orig node refcounter and
* possibly free it (without rcu callback)
* @orig_node: the orig node to free
*/
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node)
{
if (atomic_dec_and_test(&orig_node->refcount))
batadv_orig_node_free_rcu(&orig_node->rcu);
}
void batadv_originator_free(struct batadv_priv *bat_priv)
{
struct batadv_hashtable *hash = bat_priv->orig_hash;

View File

@ -26,6 +26,7 @@ int batadv_originator_init(struct batadv_priv *bat_priv);
void batadv_originator_free(struct batadv_priv *bat_priv);
void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
const uint8_t *addr);
struct batadv_neigh_node *

View File

@ -505,6 +505,7 @@ static int batadv_softif_init_late(struct net_device *dev)
batadv_debugfs_del_meshif(dev);
free_bat_counters:
free_percpu(bat_priv->bat_counters);
bat_priv->bat_counters = NULL;
return ret;
}

View File

@ -144,7 +144,12 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
struct batadv_tt_orig_list_entry *orig_entry;
orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
batadv_orig_node_free_ref(orig_entry->orig_node);
/* We are in an rcu callback here, therefore we cannot use
* batadv_orig_node_free_ref() and its call_rcu():
* An rcu_barrier() wouldn't wait for that to finish
*/
batadv_orig_node_free_ref_now(orig_entry->orig_node);
kfree(orig_entry);
}

View File

@ -72,13 +72,12 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
}
static void
ebt_log_packet(u_int8_t pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *loginfo,
const char *prefix)
ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *loginfo,
const char *prefix)
{
unsigned int bitmask;
struct net *net = dev_net(in ? in : out);
/* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net))
@ -191,7 +190,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
par->in, par->out, &li, "%s", info->prefix);
else
ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in,
par->out, &li, info->prefix);
return EBT_CONTINUE;
}

View File

@ -131,14 +131,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
return skb;
}
static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
const struct ebt_ulog_info *uloginfo, const char *prefix)
static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct ebt_ulog_info *uloginfo,
const char *prefix)
{
ebt_ulog_packet_msg_t *pm;
size_t size, copy_len;
struct nlmsghdr *nlh;
struct net *net = dev_net(in ? in : out);
struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
unsigned int group = uloginfo->nlgroup;
ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group];
@ -233,7 +235,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
}
/* this function is registered with the netfilter core */
static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *li,
const char *prefix)
@ -252,13 +254,15 @@ static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
}
ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
}
static unsigned int
ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
struct net *net = dev_net(par->in ? par->in : par->out);
ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
par->targinfo, NULL);
return EBT_CONTINUE;
}

View File

@ -235,7 +235,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
*/
struct net *net = dev_net(skb->dev);
struct ip_tunnel_net *itn;
const struct iphdr *iph = (const struct iphdr *)skb->data;
const struct iphdr *iph;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
struct ip_tunnel *t;
@ -281,6 +281,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
else
itn = net_generic(net, ipgre_net_id);
iph = (const struct iphdr *)skb->data;
t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags,
iph->daddr, iph->saddr, tpi.key);

View File

@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
return skb;
}
static void ipt_ulog_packet(unsigned int hooknum,
static void ipt_ulog_packet(struct net *net,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum,
size_t size, copy_len;
struct nlmsghdr *nlh;
struct timeval tv;
struct net *net = dev_net(in ? in : out);
struct ulog_net *ulog = ulog_pernet(net);
/* ffs == find first bit set, necessary because userspace
@ -291,12 +291,15 @@ static void ipt_ulog_packet(unsigned int hooknum,
static unsigned int
ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
struct net *net = dev_net(par->in ? par->in : par->out);
ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
par->targinfo, NULL);
return XT_CONTINUE;
}
static void ipt_logfn(u_int8_t pf,
static void ipt_logfn(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -318,7 +321,7 @@ static void ipt_logfn(u_int8_t pf,
strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
}
ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
}
static int ulog_tg_check(const struct xt_tgchk_param *par)

View File

@ -2887,6 +2887,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
unsigned int mss;
struct sk_buff *gso_skb = skb;
__sum16 newcheck;
bool ooo_okay, copy_destructor;
if (!pskb_may_pull(skb, sizeof(*th)))
goto out;
@ -2927,10 +2928,18 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
goto out;
}
copy_destructor = gso_skb->destructor == tcp_wfree;
ooo_okay = gso_skb->ooo_okay;
/* All segments but the first should have ooo_okay cleared */
skb->ooo_okay = 0;
segs = skb_segment(skb, features);
if (IS_ERR(segs))
goto out;
/* Only first segment might have ooo_okay set */
segs->ooo_okay = ooo_okay;
delta = htonl(oldlen + (thlen + mss));
skb = segs;
@ -2950,6 +2959,17 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
thlen, skb->csum));
seq += mss;
if (copy_destructor) {
skb->destructor = gso_skb->destructor;
skb->sk = gso_skb->sk;
/* {tcp|sock}_wfree() use exact truesize accounting :
* sum(skb->truesize) MUST be exactly be gso_skb->truesize
* So we account mss bytes of 'true size' for each segment.
* The last segment will contain the remaining.
*/
skb->truesize = mss;
gso_skb->truesize -= mss;
}
skb = skb->next;
th = tcp_hdr(skb);
@ -2962,7 +2982,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
* is freed at TX completion, and not right now when gso_skb
* is freed by GSO engine
*/
if (gso_skb->destructor == tcp_wfree) {
if (copy_destructor) {
swap(gso_skb->sk, skb->sk);
swap(gso_skb->destructor, skb->destructor);
swap(gso_skb->truesize, skb->truesize);
@ -3269,8 +3289,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
for (i = 0; i < shi->nr_frags; ++i) {
const struct skb_frag_struct *f = &shi->frags[i];
struct page *page = skb_frag_page(f);
sg_set_page(&sg, page, skb_frag_size(f), f->page_offset);
unsigned int offset = f->page_offset;
struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
sg_set_page(&sg, page, skb_frag_size(f),
offset_in_page(offset));
if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
return 1;
}

View File

@ -2743,8 +2743,8 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
* tcp_xmit_retransmit_queue().
*/
static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
int prior_sacked, bool is_dupack,
int flag)
int prior_sacked, int prior_packets,
bool is_dupack, int flag)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
@ -2804,7 +2804,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
tcp_add_reno_sack(sk);
} else
do_lost = tcp_try_undo_partial(sk, pkts_acked);
newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
newly_acked_sacked = prior_packets - tp->packets_out +
tp->sacked_out - prior_sacked;
break;
case TCP_CA_Loss:
tcp_process_loss(sk, flag, is_dupack);
@ -2818,7 +2819,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
if (is_dupack)
tcp_add_reno_sack(sk);
}
newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
newly_acked_sacked = prior_packets - tp->packets_out +
tp->sacked_out - prior_sacked;
if (icsk->icsk_ca_state <= TCP_CA_Disorder)
tcp_try_undo_dsack(sk);
@ -3330,9 +3332,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
bool is_dupack = false;
u32 prior_in_flight;
u32 prior_fackets;
int prior_packets;
int prior_packets = tp->packets_out;
int prior_sacked = tp->sacked_out;
int pkts_acked = 0;
int previous_packets_out = 0;
/* If the ack is older than previous acks
* then we can probably ignore it.
@ -3403,14 +3406,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
sk->sk_err_soft = 0;
icsk->icsk_probes_out = 0;
tp->rcv_tstamp = tcp_time_stamp;
prior_packets = tp->packets_out;
if (!prior_packets)
goto no_queue;
/* See if we can take anything off of the retransmit queue. */
previous_packets_out = tp->packets_out;
flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
pkts_acked = prior_packets - tp->packets_out;
pkts_acked = previous_packets_out - tp->packets_out;
if (tcp_ack_is_dubious(sk, flag)) {
/* Advance CWND, if state allows this. */
@ -3418,7 +3421,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
tcp_cong_avoid(sk, ack, prior_in_flight);
is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
is_dupack, flag);
prior_packets, is_dupack, flag);
} else {
if (flag & FLAG_DATA_ACKED)
tcp_cong_avoid(sk, ack, prior_in_flight);
@ -3441,7 +3444,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
/* If data was DSACKed, see if we can undo a cwnd reduction. */
if (flag & FLAG_DSACKING_ACK)
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
is_dupack, flag);
prior_packets, is_dupack, flag);
/* If this ack opens up a zero window, clear backoff. It was
* being used to time the probes, and is probably far higher than
* it needs to be for normal retransmission.
@ -3464,7 +3467,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
if (TCP_SKB_CB(skb)->sacked) {
flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
is_dupack, flag);
prior_packets, is_dupack, flag);
}
SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);

View File

@ -874,11 +874,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
&md5);
tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
if (tcp_packets_in_flight(tp) == 0) {
if (tcp_packets_in_flight(tp) == 0)
tcp_ca_event(sk, CA_EVENT_TX_START);
skb->ooo_okay = 1;
} else
skb->ooo_okay = 0;
/* if no packet is in qdisc/device queue, then allow XPS to select
* another queue.
*/
skb->ooo_okay = sk_wmem_alloc_get(sk) == 0;
skb_push(skb, tcp_header_size);
skb_reset_transport_header(skb);

View File

@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (WARN_ON(np->cork.opt))
return -EINVAL;
np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
if (unlikely(np->cork.opt == NULL))
return -ENOBUFS;

View File

@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
/*
* We now have some discovery info to deliver!
*/
discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC);
if (!discovery) {
IRDA_WARNING("%s: unable to malloc!\n", __func__);
return;

View File

@ -1267,6 +1267,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
__le16 fc, bool acked);
void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
/* IBSS code */
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);

View File

@ -1015,7 +1015,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
static void
ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
u64 timestamp, struct ieee802_11_elems *elems)
u64 timestamp, struct ieee802_11_elems *elems,
bool beacon)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@ -1032,6 +1033,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct cfg80211_chan_def new_vht_chandef = {};
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
const struct ieee80211_ht_operation *ht_oper;
int secondary_channel_offset = -1;
ASSERT_MGD_MTX(ifmgd);
@ -1048,11 +1050,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
sec_chan_offs = elems->sec_chan_offs;
wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
ht_oper = elems->ht_operation;
if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
IEEE80211_STA_DISABLE_40MHZ)) {
sec_chan_offs = NULL;
wide_bw_chansw_ie = NULL;
/* only used for bandwidth here */
ht_oper = NULL;
}
if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
@ -1094,10 +1099,20 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return;
}
if (sec_chan_offs) {
if (!beacon && sec_chan_offs) {
secondary_channel_offset = sec_chan_offs->sec_chan_offs;
} else if (beacon && ht_oper) {
secondary_channel_offset =
ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
} else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
/* if HT is enabled and the IE not present, it's still HT */
/*
* If it's not a beacon, HT is enabled and the IE not present,
* it's 20 MHz, 802.11-2012 8.5.2.6:
* This element [the Secondary Channel Offset Element] is
* present when switching to a 40 MHz channel. It may be
* present when switching to a 20 MHz channel (in which
* case the secondary channel offset is set to SCN).
*/
secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
}
@ -2796,7 +2811,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&local->iflist_mtx);
}
ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, elems);
ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
elems, true);
}
@ -3210,7 +3226,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_process_chanswitch(sdata,
rx_status->mactime,
&elems);
&elems, false);
} else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
ies_len = skb->len -
offsetof(struct ieee80211_mgmt,
@ -3232,7 +3248,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_process_chanswitch(sdata,
rx_status->mactime,
&elems);
&elems, false);
}
break;
}
@ -3623,6 +3639,31 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
}
}
#ifdef CONFIG_PM
void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
mutex_lock(&ifmgd->mtx);
if (!ifmgd->associated) {
mutex_unlock(&ifmgd->mtx);
return;
}
if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
mlme_dbg(sdata, "driver requested disconnect after resume\n");
ieee80211_sta_connection_lost(sdata,
ifmgd->associated->bssid,
WLAN_REASON_UNSPECIFIED,
true);
mutex_unlock(&ifmgd->mtx);
return;
}
mutex_unlock(&ifmgd->mtx);
}
#endif
/* interface setup */
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
{
@ -4329,7 +4370,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
bool tx = !req->local_state_change;
bool sent_frame = false;
bool report_frame = false;
mutex_lock(&ifmgd->mtx);
@ -4346,7 +4387,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_destroy_auth_data(sdata, false);
mutex_unlock(&ifmgd->mtx);
sent_frame = tx;
report_frame = true;
goto out;
}
@ -4354,12 +4395,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
req->reason_code, tx, frame_buf);
sent_frame = tx;
report_frame = true;
}
mutex_unlock(&ifmgd->mtx);
out:
if (sent_frame)
if (report_frame)
__cfg80211_send_deauth(sdata->dev, frame_buf,
IEEE80211_DEAUTH_FRAME_LEN);

View File

@ -688,8 +688,15 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
struct ieee80211_sta *pubsta,
struct ieee80211_sta_rates *rates)
{
struct ieee80211_sta_rates *old = rcu_dereference(pubsta->rates);
struct ieee80211_sta_rates *old;
/*
* mac80211 guarantees that this function will not be called
* concurrently, so the following RCU access is safe, even without
* extra locking. This can not be checked easily, so we just set
* the condition to true.
*/
old = rcu_dereference_protected(pubsta->rates, true);
rcu_assign_pointer(pubsta->rates, rates);
if (old)
kfree_rcu(old, rcu_head);

View File

@ -3036,6 +3036,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
* and location updates. Note that mac80211
* itself never looks at these frames.
*/
if (!multicast &&
!ether_addr_equal(sdata->vif.addr, hdr->addr1))
return 0;
if (ieee80211_is_public_action(hdr, skb->len))
return 1;
if (!ieee80211_is_beacon(hdr->frame_control))

View File

@ -208,10 +208,10 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
u32 iv32 = get_unaligned_le32(&data[4]);
u16 iv16 = data[2] | (data[0] << 8);
spin_lock_bh(&key->u.tkip.txlock);
spin_lock(&key->u.tkip.txlock);
ieee80211_compute_tkip_p1k(key, iv32);
tkip_mixing_phase2(tk, ctx, iv16, p2k);
spin_unlock_bh(&key->u.tkip.txlock);
spin_unlock(&key->u.tkip.txlock);
}
EXPORT_SYMBOL(ieee80211_get_tkip_p2k);

View File

@ -1740,6 +1740,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mb();
local->resuming = false;
list_for_each_entry(sdata, &local->interfaces, list) {
if (!ieee80211_sdata_running(sdata))
continue;
if (sdata->vif.type == NL80211_IFTYPE_STATION)
ieee80211_sta_restart(sdata);
}
mod_timer(&local->sta_cleanup, jiffies + 1);
#else
WARN_ON(1);

View File

@ -148,7 +148,7 @@ void nf_log_packet(struct net *net,
va_start(args, fmt);
vsnprintf(prefix, sizeof(prefix), fmt, args);
va_end(args);
logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix);
logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix);
}
rcu_read_unlock();
}
@ -368,17 +368,20 @@ static int __net_init nf_log_net_init(struct net *net)
return 0;
out_sysctl:
#ifdef CONFIG_PROC_FS
/* For init_net: errors will trigger panic, don't unroll on error. */
if (!net_eq(net, &init_net))
remove_proc_entry("nf_log", net->nf.proc_netfilter);
#endif
return ret;
}
static void __net_exit nf_log_net_exit(struct net *net)
{
netfilter_log_sysctl_exit(net);
#ifdef CONFIG_PROC_FS
remove_proc_entry("nf_log", net->nf.proc_netfilter);
#endif
}
static struct pernet_operations nf_log_net_ops = {

View File

@ -602,7 +602,8 @@ static struct nf_loginfo default_loginfo = {
/* log handler for internal netfilter logging api */
void
nfulnl_log_packet(u_int8_t pf,
nfulnl_log_packet(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -615,7 +616,6 @@ nfulnl_log_packet(u_int8_t pf,
const struct nf_loginfo *li;
unsigned int qthreshold;
unsigned int plen;
struct net *net = dev_net(in ? in : out);
struct nfnl_log_net *log = nfnl_log_pernet(net);
if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
@ -1045,7 +1045,9 @@ static int __net_init nfnl_log_net_init(struct net *net)
static void __net_exit nfnl_log_net_exit(struct net *net)
{
#ifdef CONFIG_PROC_FS
remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
#endif
}
static struct pernet_operations nfnl_log_net_ops = {

View File

@ -1285,7 +1285,9 @@ static int __net_init nfnl_queue_net_init(struct net *net)
static void __net_exit nfnl_queue_net_exit(struct net *net)
{
#ifdef CONFIG_PROC_FS
remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter);
#endif
}
static struct pernet_operations nfnl_queue_net_ops = {

View File

@ -466,7 +466,8 @@ log_packet_common(struct sbuff *m,
static void
ipt_log_packet(u_int8_t pf,
ipt_log_packet(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -475,7 +476,6 @@ ipt_log_packet(u_int8_t pf,
const char *prefix)
{
struct sbuff *m;
struct net *net = dev_net(in ? in : out);
/* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net))
@ -797,7 +797,8 @@ static void dump_ipv6_mac_header(struct sbuff *m,
}
static void
ip6t_log_packet(u_int8_t pf,
ip6t_log_packet(struct net *net,
u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -806,7 +807,6 @@ ip6t_log_packet(u_int8_t pf,
const char *prefix)
{
struct sbuff *m;
struct net *net = dev_net(in ? in : out);
/* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net))
@ -833,17 +833,18 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_log_info *loginfo = par->targinfo;
struct nf_loginfo li;
struct net *net = dev_net(par->in ? par->in : par->out);
li.type = NF_LOG_TYPE_LOG;
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
if (par->family == NFPROTO_IPV4)
ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in,
par->out, &li, loginfo->prefix);
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
else if (par->family == NFPROTO_IPV6)
ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
par->out, &li, loginfo->prefix);
#endif
else

View File

@ -26,13 +26,14 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_nflog_info *info = par->targinfo;
struct nf_loginfo li;
struct net *net = dev_net(par->in ? par->in : par->out);
li.type = NF_LOG_TYPE_ULOG;
li.u.ulog.copy_len = info->len;
li.u.ulog.group = info->group;
li.u.ulog.qthreshold = info->threshold;
nfulnl_log_packet(par->family, par->hooknum, skb, par->in,
nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in,
par->out, &li, info->prefix);
return XT_CONTINUE;
}

View File

@ -30,17 +30,28 @@ static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
static unsigned int
tcpoptstrip_mangle_packet(struct sk_buff *skb,
const struct xt_tcpoptstrip_target_info *info,
const struct xt_action_param *par,
unsigned int tcphoff, unsigned int minlen)
{
const struct xt_tcpoptstrip_target_info *info = par->targinfo;
unsigned int optl, i, j;
struct tcphdr *tcph;
u_int16_t n, o;
u_int8_t *opt;
int len;
/* This is a fragment, no TCP header is available */
if (par->fragoff != 0)
return XT_CONTINUE;
if (!skb_make_writable(skb, skb->len))
return NF_DROP;
len = skb->len - tcphoff;
if (len < (int)sizeof(struct tcphdr) ||
tcp_hdr(skb)->doff * 4 > len)
return NF_DROP;
tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
opt = (u_int8_t *)tcph;
@ -76,7 +87,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
static unsigned int
tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par)
{
return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb),
return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb),
sizeof(struct iphdr) + sizeof(struct tcphdr));
}
@ -94,7 +105,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
if (tcphoff < 0)
return NF_DROP;
return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff,
return tcpoptstrip_mangle_packet(skb, par, tcphoff,
sizeof(*ipv6h) + sizeof(struct tcphdr));
}
#endif

View File

@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
}
}
/**
* netlbl_domhsh_validate - Validate a new domain mapping entry
* @entry: the entry to validate
*
* This function validates the new domain mapping entry to ensure that it is
* a valid entry. Returns zero on success, negative values on failure.
*
*/
static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
{
struct netlbl_af4list *iter4;
struct netlbl_domaddr4_map *map4;
#if IS_ENABLED(CONFIG_IPV6)
struct netlbl_af6list *iter6;
struct netlbl_domaddr6_map *map6;
#endif /* IPv6 */
if (entry == NULL)
return -EINVAL;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
if (entry->type_def.cipsov4 != NULL ||
entry->type_def.addrsel != NULL)
return -EINVAL;
break;
case NETLBL_NLTYPE_CIPSOV4:
if (entry->type_def.cipsov4 == NULL)
return -EINVAL;
break;
case NETLBL_NLTYPE_ADDRSELECT:
netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) {
map4 = netlbl_domhsh_addr4_entry(iter4);
switch (map4->type) {
case NETLBL_NLTYPE_UNLABELED:
if (map4->type_def.cipsov4 != NULL)
return -EINVAL;
break;
case NETLBL_NLTYPE_CIPSOV4:
if (map4->type_def.cipsov4 == NULL)
return -EINVAL;
break;
default:
return -EINVAL;
}
}
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) {
map6 = netlbl_domhsh_addr6_entry(iter6);
switch (map6->type) {
case NETLBL_NLTYPE_UNLABELED:
break;
default:
return -EINVAL;
}
}
#endif /* IPv6 */
break;
default:
return -EINVAL;
}
return 0;
}
/*
* Domain Hash Table Functions
*/
@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
struct netlbl_af6list *tmp6;
#endif /* IPv6 */
ret_val = netlbl_domhsh_validate(entry);
if (ret_val != 0)
return ret_val;
/* XXX - we can remove this RCU read lock as the spinlock protects the
* entire function, but before we do we need to fixup the
* netlbl_af[4,6]list RCU functions to do "the right thing" with

View File

@ -638,17 +638,21 @@ int wiphy_register(struct wiphy *wiphy)
* cfg80211_mutex lock
*/
res = rfkill_register(rdev->rfkill);
if (res)
goto out_rm_dev;
if (res) {
device_del(&rdev->wiphy.dev);
mutex_lock(&cfg80211_mutex);
debugfs_remove_recursive(rdev->wiphy.debugfsdir);
list_del_rcu(&rdev->list);
wiphy_regulatory_deregister(wiphy);
mutex_unlock(&cfg80211_mutex);
return res;
}
rtnl_lock();
rdev->wiphy.registered = true;
rtnl_unlock();
return 0;
out_rm_dev:
device_del(&rdev->wiphy.dev);
return res;
}
EXPORT_SYMBOL(wiphy_register);
@ -866,7 +870,6 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
#endif
__cfg80211_disconnect(rdev, dev,
WLAN_REASON_DEAUTH_LEAVING, true);
cfg80211_mlme_down(rdev, dev);
wdev_unlock(wdev);
break;
case NL80211_IFTYPE_MESH_POINT:

View File

@ -7577,6 +7577,8 @@ static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
&tcp->payload_tok))
return -ENOBUFS;
nla_nest_end(msg, nl_tcp);
return 0;
}
@ -9970,6 +9972,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
netdev->ifindex)) ||
nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
(sig_dbm &&
nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
@ -10010,6 +10013,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
netdev->ifindex)) ||
nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
(ack && nla_put_flag(msg, NL80211_ATTR_ACK)))

View File

@ -961,7 +961,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
/* was it connected by userspace SME? */
if (!wdev->conn) {
cfg80211_mlme_down(rdev, dev);
return 0;
goto disconnect;
}
if (wdev->sme_state == CFG80211_SME_CONNECTING &&
@ -987,6 +987,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
return err;
}
disconnect:
if (wdev->sme_state == CFG80211_SME_CONNECTED)
__cfg80211_disconnected(dev, NULL, 0, 0, false);
else if (wdev->sme_state == CFG80211_SME_CONNECTING)

View File

@ -2441,6 +2441,7 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup,
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
__field(bool, non_wireless)
__field(bool, disconnect)
__field(bool, magic_pkt)
__field(bool, gtk_rekey_failure)
@ -2449,20 +2450,22 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup,
__field(bool, rfkill_release)
__field(s32, pattern_idx)
__field(u32, packet_len)
__dynamic_array(u8, packet, wakeup->packet_present_len)
__dynamic_array(u8, packet,
wakeup ? wakeup->packet_present_len : 0)
),
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
__entry->disconnect = wakeup->disconnect;
__entry->magic_pkt = wakeup->magic_pkt;
__entry->gtk_rekey_failure = wakeup->gtk_rekey_failure;
__entry->eap_identity_req = wakeup->eap_identity_req;
__entry->four_way_handshake = wakeup->four_way_handshake;
__entry->rfkill_release = wakeup->rfkill_release;
__entry->pattern_idx = wakeup->pattern_idx;
__entry->packet_len = wakeup->packet_len;
if (wakeup->packet && wakeup->packet_present_len)
__entry->non_wireless = !wakeup;
__entry->disconnect = wakeup ? wakeup->disconnect : false;
__entry->magic_pkt = wakeup ? wakeup->magic_pkt : false;
__entry->gtk_rekey_failure = wakeup ? wakeup->gtk_rekey_failure : false;
__entry->eap_identity_req = wakeup ? wakeup->eap_identity_req : false;
__entry->four_way_handshake = wakeup ? wakeup->four_way_handshake : false;
__entry->rfkill_release = wakeup ? wakeup->rfkill_release : false;
__entry->pattern_idx = wakeup ? wakeup->pattern_idx : false;
__entry->packet_len = wakeup ? wakeup->packet_len : false;
if (wakeup && wakeup->packet && wakeup->packet_present_len)
memcpy(__get_dynamic_array(packet), wakeup->packet,
wakeup->packet_present_len);
),

View File

@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
err = -EINVAL;
goto error;
}

View File

@ -15,35 +15,38 @@ kallsyms = []
def get_kallsyms_table():
global kallsyms
try:
f = open("/proc/kallsyms", "r")
linecount = 0
for line in f:
linecount = linecount+1
f.seek(0)
except:
return
j = 0
for line in f:
loc = int(line.split()[0], 16)
name = line.split()[2]
j = j +1
if ((j % 100) == 0):
print "\r" + str(j) + "/" + str(linecount),
kallsyms.append({ 'loc': loc, 'name' : name})
print "\r" + str(j) + "/" + str(linecount)
kallsyms.append((loc, name))
kallsyms.sort()
return
def get_sym(sloc):
loc = int(sloc)
for i in kallsyms:
if (i['loc'] >= loc):
return (i['name'], i['loc']-loc)
return (None, 0)
# Invariant: kallsyms[i][0] <= loc for all 0 <= i <= start
# kallsyms[i][0] > loc for all end <= i < len(kallsyms)
start, end = -1, len(kallsyms)
while end != start + 1:
pivot = (start + end) // 2
if loc < kallsyms[pivot][0]:
end = pivot
else:
start = pivot
# Now (start == -1 or kallsyms[start][0] <= loc)
# and (start == len(kallsyms) - 1 or loc < kallsyms[start + 1][0])
if start >= 0:
symloc, name = kallsyms[start]
return (name, loc - symloc)
else:
return (None, 0)
def print_drop_table():
print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")
@ -64,7 +67,7 @@ def trace_end():
# called from perf, when it finds a correspoinding event
def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm,
skbaddr, protocol, location):
skbaddr, location, protocol):
slocation = str(location)
try:
drop_log[slocation] = drop_log[slocation] + 1