Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (55 commits) ISDN, hfcsusb: Don't leak in hfcsusb_ph_info() netpoll: call dev_put() on error in netpoll_setup() net: ep93xx_eth: fix DMA API violations net: ep93xx_eth: drop GFP_DMA from call to dma_alloc_coherent() net: ep93xx_eth: allocate buffers using kmalloc() net: ep93xx_eth: pass struct device to DMA API functions ep93xx: set DMA masks for the ep93xx_eth vlan: Fix the ingress VLAN_FLAG_REORDER_HDR check dl2k: EEPROM CRC calculation wrong endianess on bigendian machine NET: am79c961: fix assembler warnings NET: am79c961: ensure multicast filter is correctly set at open NET: am79c961: ensure asm() statements are marked volatile ethtool.h: fix typos ep93xx_eth: Update MAINTAINERS ipv4: Fix packet size calculation for raw IPsec packets in __ip_append_data netpoll: prevent netpoll setup on slave devices net: pmtu_expires fixes gianfar:localized filer table iwlegacy: fix channel switch locking mac80211: fix IBSS teardown race ...
This commit is contained in:
commit
152b92db7a
|
@ -1739,7 +1739,7 @@ S: Supported
|
||||||
F: drivers/net/enic/
|
F: drivers/net/enic/
|
||||||
|
|
||||||
CIRRUS LOGIC EP93XX ETHERNET DRIVER
|
CIRRUS LOGIC EP93XX ETHERNET DRIVER
|
||||||
M: Lennert Buytenhek <kernel@wantstofly.org>
|
M: Hartley Sweeten <hsweeten@visionengravers.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/arm/ep93xx_eth.c
|
F: drivers/net/arm/ep93xx_eth.c
|
||||||
|
|
|
@ -402,11 +402,15 @@ static struct resource ep93xx_eth_resource[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static u64 ep93xx_eth_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
static struct platform_device ep93xx_eth_device = {
|
static struct platform_device ep93xx_eth_device = {
|
||||||
.name = "ep93xx-eth",
|
.name = "ep93xx-eth",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.platform_data = &ep93xx_eth_data,
|
.platform_data = &ep93xx_eth_data,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.dma_mask = &ep93xx_eth_dma_mask,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(ep93xx_eth_resource),
|
.num_resources = ARRAY_SIZE(ep93xx_eth_resource),
|
||||||
.resource = ep93xx_eth_resource,
|
.resource = ep93xx_eth_resource,
|
||||||
|
|
|
@ -283,6 +283,7 @@ hfcsusb_ph_info(struct hfcsusb *hw)
|
||||||
_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
|
_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
|
||||||
sizeof(struct ph_info_dch) + dch->dev.nrbchan *
|
sizeof(struct ph_info_dch) + dch->dev.nrbchan *
|
||||||
sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
|
sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
|
||||||
|
kfree(phi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -50,7 +50,7 @@ static const char version[] =
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
static void write_rreg(u_long base, u_int reg, u_int val)
|
static void write_rreg(u_long base, u_int reg, u_int val)
|
||||||
{
|
{
|
||||||
__asm__(
|
asm volatile(
|
||||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||||
"str%?h %0, [%2, #-4] @ NET_RDP"
|
"str%?h %0, [%2, #-4] @ NET_RDP"
|
||||||
:
|
:
|
||||||
|
@ -60,7 +60,7 @@ static void write_rreg(u_long base, u_int reg, u_int val)
|
||||||
static inline unsigned short read_rreg(u_long base_addr, u_int reg)
|
static inline unsigned short read_rreg(u_long base_addr, u_int reg)
|
||||||
{
|
{
|
||||||
unsigned short v;
|
unsigned short v;
|
||||||
__asm__(
|
asm volatile(
|
||||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||||
"ldr%?h %0, [%2, #-4] @ NET_RDP"
|
"ldr%?h %0, [%2, #-4] @ NET_RDP"
|
||||||
: "=r" (v)
|
: "=r" (v)
|
||||||
|
@ -70,7 +70,7 @@ static inline unsigned short read_rreg(u_long base_addr, u_int reg)
|
||||||
|
|
||||||
static inline void write_ireg(u_long base, u_int reg, u_int val)
|
static inline void write_ireg(u_long base, u_int reg, u_int val)
|
||||||
{
|
{
|
||||||
__asm__(
|
asm volatile(
|
||||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||||
"str%?h %0, [%2, #8] @ NET_IDP"
|
"str%?h %0, [%2, #8] @ NET_IDP"
|
||||||
:
|
:
|
||||||
|
@ -80,7 +80,7 @@ static inline void write_ireg(u_long base, u_int reg, u_int val)
|
||||||
static inline unsigned short read_ireg(u_long base_addr, u_int reg)
|
static inline unsigned short read_ireg(u_long base_addr, u_int reg)
|
||||||
{
|
{
|
||||||
u_short v;
|
u_short v;
|
||||||
__asm__(
|
asm volatile(
|
||||||
"str%?h %1, [%2] @ NAT_RAP\n\t"
|
"str%?h %1, [%2] @ NAT_RAP\n\t"
|
||||||
"ldr%?h %0, [%2, #8] @ NET_IDP\n\t"
|
"ldr%?h %0, [%2, #8] @ NET_IDP\n\t"
|
||||||
: "=r" (v)
|
: "=r" (v)
|
||||||
|
@ -91,47 +91,48 @@ static inline unsigned short read_ireg(u_long base_addr, u_int reg)
|
||||||
#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
|
#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
|
||||||
#define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1))
|
#define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1))
|
||||||
|
|
||||||
static inline void
|
static void
|
||||||
am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
|
am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
|
||||||
{
|
{
|
||||||
offset = ISAMEM_BASE + (offset << 1);
|
offset = ISAMEM_BASE + (offset << 1);
|
||||||
length = (length + 1) & ~1;
|
length = (length + 1) & ~1;
|
||||||
if ((int)buf & 2) {
|
if ((int)buf & 2) {
|
||||||
__asm__ __volatile__("str%?h %2, [%0], #4"
|
asm volatile("str%?h %2, [%0], #4"
|
||||||
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
||||||
buf += 2;
|
buf += 2;
|
||||||
length -= 2;
|
length -= 2;
|
||||||
}
|
}
|
||||||
while (length > 8) {
|
while (length > 8) {
|
||||||
unsigned int tmp, tmp2;
|
register unsigned int tmp asm("r2"), tmp2 asm("r3");
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
"ldm%?ia %1!, {%2, %3}\n\t"
|
"ldm%?ia %0!, {%1, %2}"
|
||||||
|
: "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
|
||||||
|
length -= 8;
|
||||||
|
asm volatile(
|
||||||
|
"str%?h %1, [%0], #4\n\t"
|
||||||
|
"mov%? %1, %1, lsr #16\n\t"
|
||||||
|
"str%?h %1, [%0], #4\n\t"
|
||||||
"str%?h %2, [%0], #4\n\t"
|
"str%?h %2, [%0], #4\n\t"
|
||||||
"mov%? %2, %2, lsr #16\n\t"
|
"mov%? %2, %2, lsr #16\n\t"
|
||||||
"str%?h %2, [%0], #4\n\t"
|
"str%?h %2, [%0], #4"
|
||||||
"str%?h %3, [%0], #4\n\t"
|
: "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
|
||||||
"mov%? %3, %3, lsr #16\n\t"
|
|
||||||
"str%?h %3, [%0], #4"
|
|
||||||
: "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
|
|
||||||
: "0" (offset), "1" (buf));
|
|
||||||
length -= 8;
|
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
__asm__ __volatile__("str%?h %2, [%0], #4"
|
asm volatile("str%?h %2, [%0], #4"
|
||||||
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
||||||
buf += 2;
|
buf += 2;
|
||||||
length -= 2;
|
length -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static void
|
||||||
am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
|
am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
|
||||||
{
|
{
|
||||||
offset = ISAMEM_BASE + (offset << 1);
|
offset = ISAMEM_BASE + (offset << 1);
|
||||||
length = (length + 1) & ~1;
|
length = (length + 1) & ~1;
|
||||||
if ((int)buf & 2) {
|
if ((int)buf & 2) {
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
"ldr%?h %2, [%0], #4\n\t"
|
"ldr%?h %2, [%0], #4\n\t"
|
||||||
"str%?b %2, [%1], #1\n\t"
|
"str%?b %2, [%1], #1\n\t"
|
||||||
"mov%? %2, %2, lsr #8\n\t"
|
"mov%? %2, %2, lsr #8\n\t"
|
||||||
|
@ -140,12 +141,12 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
|
||||||
length -= 2;
|
length -= 2;
|
||||||
}
|
}
|
||||||
while (length > 8) {
|
while (length > 8) {
|
||||||
unsigned int tmp, tmp2, tmp3;
|
register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
"ldr%?h %2, [%0], #4\n\t"
|
"ldr%?h %2, [%0], #4\n\t"
|
||||||
|
"ldr%?h %4, [%0], #4\n\t"
|
||||||
"ldr%?h %3, [%0], #4\n\t"
|
"ldr%?h %3, [%0], #4\n\t"
|
||||||
"orr%? %2, %2, %3, lsl #16\n\t"
|
"orr%? %2, %2, %4, lsl #16\n\t"
|
||||||
"ldr%?h %3, [%0], #4\n\t"
|
|
||||||
"ldr%?h %4, [%0], #4\n\t"
|
"ldr%?h %4, [%0], #4\n\t"
|
||||||
"orr%? %3, %3, %4, lsl #16\n\t"
|
"orr%? %3, %3, %4, lsl #16\n\t"
|
||||||
"stm%?ia %1!, {%2, %3}"
|
"stm%?ia %1!, {%2, %3}"
|
||||||
|
@ -155,7 +156,7 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
__asm__ __volatile__(
|
asm volatile(
|
||||||
"ldr%?h %2, [%0], #4\n\t"
|
"ldr%?h %2, [%0], #4\n\t"
|
||||||
"str%?b %2, [%1], #1\n\t"
|
"str%?b %2, [%1], #1\n\t"
|
||||||
"mov%? %2, %2, lsr #8\n\t"
|
"mov%? %2, %2, lsr #8\n\t"
|
||||||
|
@ -196,6 +197,42 @@ am79c961_ramtest(struct net_device *dev, unsigned int val)
|
||||||
return errorcount;
|
return errorcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void am79c961_mc_hash(char *addr, u16 *hash)
|
||||||
|
{
|
||||||
|
if (addr[0] & 0x01) {
|
||||||
|
int idx, bit;
|
||||||
|
u32 crc;
|
||||||
|
|
||||||
|
crc = ether_crc_le(ETH_ALEN, addr);
|
||||||
|
|
||||||
|
idx = crc >> 30;
|
||||||
|
bit = (crc >> 26) & 15;
|
||||||
|
|
||||||
|
hash[idx] |= 1 << bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash)
|
||||||
|
{
|
||||||
|
unsigned int mode = MODE_PORT_10BT;
|
||||||
|
|
||||||
|
if (dev->flags & IFF_PROMISC) {
|
||||||
|
mode |= MODE_PROMISC;
|
||||||
|
memset(hash, 0xff, 4 * sizeof(*hash));
|
||||||
|
} else if (dev->flags & IFF_ALLMULTI) {
|
||||||
|
memset(hash, 0xff, 4 * sizeof(*hash));
|
||||||
|
} else {
|
||||||
|
struct netdev_hw_addr *ha;
|
||||||
|
|
||||||
|
memset(hash, 0, 4 * sizeof(*hash));
|
||||||
|
|
||||||
|
netdev_for_each_mc_addr(ha, dev)
|
||||||
|
am79c961_mc_hash(ha->addr, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
am79c961_init_for_open(struct net_device *dev)
|
am79c961_init_for_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -203,6 +240,7 @@ am79c961_init_for_open(struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
u_int hdr_addr, first_free_addr;
|
u_int hdr_addr, first_free_addr;
|
||||||
|
u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,16 +256,12 @@ am79c961_init_for_open(struct net_device *dev)
|
||||||
write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
|
write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
|
||||||
|
|
||||||
for (i = LADRL; i <= LADRH; i++)
|
for (i = LADRL; i <= LADRH; i++)
|
||||||
write_rreg (dev->base_addr, i, 0);
|
write_rreg (dev->base_addr, i, multi_hash[i - LADRL]);
|
||||||
|
|
||||||
for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
|
for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
|
||||||
write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
|
write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
|
||||||
|
|
||||||
i = MODE_PORT_10BT;
|
write_rreg (dev->base_addr, MODE, mode);
|
||||||
if (dev->flags & IFF_PROMISC)
|
|
||||||
i |= MODE_PROMISC;
|
|
||||||
|
|
||||||
write_rreg (dev->base_addr, MODE, i);
|
|
||||||
write_rreg (dev->base_addr, POLLINT, 0);
|
write_rreg (dev->base_addr, POLLINT, 0);
|
||||||
write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
|
write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
|
||||||
write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
|
write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
|
||||||
|
@ -340,21 +374,6 @@ am79c961_close(struct net_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void am79c961_mc_hash(char *addr, unsigned short *hash)
|
|
||||||
{
|
|
||||||
if (addr[0] & 0x01) {
|
|
||||||
int idx, bit;
|
|
||||||
u32 crc;
|
|
||||||
|
|
||||||
crc = ether_crc_le(ETH_ALEN, addr);
|
|
||||||
|
|
||||||
idx = crc >> 30;
|
|
||||||
bit = (crc >> 26) & 15;
|
|
||||||
|
|
||||||
hash[idx] |= 1 << bit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set or clear promiscuous/multicast mode filter for this adapter.
|
* Set or clear promiscuous/multicast mode filter for this adapter.
|
||||||
*/
|
*/
|
||||||
|
@ -362,24 +381,9 @@ static void am79c961_setmulticastlist (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct dev_priv *priv = netdev_priv(dev);
|
struct dev_priv *priv = netdev_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned short multi_hash[4], mode;
|
u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
|
||||||
int i, stopped;
|
int i, stopped;
|
||||||
|
|
||||||
mode = MODE_PORT_10BT;
|
|
||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
|
||||||
mode |= MODE_PROMISC;
|
|
||||||
} else if (dev->flags & IFF_ALLMULTI) {
|
|
||||||
memset(multi_hash, 0xff, sizeof(multi_hash));
|
|
||||||
} else {
|
|
||||||
struct netdev_hw_addr *ha;
|
|
||||||
|
|
||||||
memset(multi_hash, 0x00, sizeof(multi_hash));
|
|
||||||
|
|
||||||
netdev_for_each_mc_addr(ha, dev)
|
|
||||||
am79c961_mc_hash(ha->addr, multi_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->chip_lock, flags);
|
spin_lock_irqsave(&priv->chip_lock, flags);
|
||||||
|
|
||||||
stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
|
stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
|
||||||
|
|
|
@ -283,10 +283,14 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
|
||||||
|
|
||||||
skb = dev_alloc_skb(length + 2);
|
skb = dev_alloc_skb(length + 2);
|
||||||
if (likely(skb != NULL)) {
|
if (likely(skb != NULL)) {
|
||||||
|
struct ep93xx_rdesc *rxd = &ep->descs->rdesc[entry];
|
||||||
skb_reserve(skb, 2);
|
skb_reserve(skb, 2);
|
||||||
dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr,
|
dma_sync_single_for_cpu(dev->dev.parent, rxd->buf_addr,
|
||||||
length, DMA_FROM_DEVICE);
|
length, DMA_FROM_DEVICE);
|
||||||
skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
|
skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
|
||||||
|
dma_sync_single_for_device(dev->dev.parent,
|
||||||
|
rxd->buf_addr, length,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
skb_put(skb, length);
|
skb_put(skb, length);
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
|
|
||||||
|
@ -348,6 +352,7 @@ poll_some_more:
|
||||||
static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
|
static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ep93xx_priv *ep = netdev_priv(dev);
|
struct ep93xx_priv *ep = netdev_priv(dev);
|
||||||
|
struct ep93xx_tdesc *txd;
|
||||||
int entry;
|
int entry;
|
||||||
|
|
||||||
if (unlikely(skb->len > MAX_PKT_SIZE)) {
|
if (unlikely(skb->len > MAX_PKT_SIZE)) {
|
||||||
|
@ -359,11 +364,14 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
entry = ep->tx_pointer;
|
entry = ep->tx_pointer;
|
||||||
ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1);
|
ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1);
|
||||||
|
|
||||||
ep->descs->tdesc[entry].tdesc1 =
|
txd = &ep->descs->tdesc[entry];
|
||||||
TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
|
|
||||||
|
txd->tdesc1 = TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
|
||||||
|
dma_sync_single_for_cpu(dev->dev.parent, txd->buf_addr, skb->len,
|
||||||
|
DMA_TO_DEVICE);
|
||||||
skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
|
skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
|
||||||
dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr,
|
dma_sync_single_for_device(dev->dev.parent, txd->buf_addr, skb->len,
|
||||||
skb->len, DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
spin_lock_irq(&ep->tx_pending_lock);
|
spin_lock_irq(&ep->tx_pending_lock);
|
||||||
|
@ -457,89 +465,80 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id)
|
||||||
|
|
||||||
static void ep93xx_free_buffers(struct ep93xx_priv *ep)
|
static void ep93xx_free_buffers(struct ep93xx_priv *ep)
|
||||||
{
|
{
|
||||||
|
struct device *dev = ep->dev->dev.parent;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
|
for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
|
||||||
dma_addr_t d;
|
dma_addr_t d;
|
||||||
|
|
||||||
d = ep->descs->rdesc[i].buf_addr;
|
d = ep->descs->rdesc[i].buf_addr;
|
||||||
if (d)
|
if (d)
|
||||||
dma_unmap_single(NULL, d, PAGE_SIZE, DMA_FROM_DEVICE);
|
dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_FROM_DEVICE);
|
||||||
|
|
||||||
if (ep->rx_buf[i] != NULL)
|
if (ep->rx_buf[i] != NULL)
|
||||||
free_page((unsigned long)ep->rx_buf[i]);
|
kfree(ep->rx_buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
|
for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
|
||||||
dma_addr_t d;
|
dma_addr_t d;
|
||||||
|
|
||||||
d = ep->descs->tdesc[i].buf_addr;
|
d = ep->descs->tdesc[i].buf_addr;
|
||||||
if (d)
|
if (d)
|
||||||
dma_unmap_single(NULL, d, PAGE_SIZE, DMA_TO_DEVICE);
|
dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_TO_DEVICE);
|
||||||
|
|
||||||
if (ep->tx_buf[i] != NULL)
|
if (ep->tx_buf[i] != NULL)
|
||||||
free_page((unsigned long)ep->tx_buf[i]);
|
kfree(ep->tx_buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_free_coherent(NULL, sizeof(struct ep93xx_descs), ep->descs,
|
dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs,
|
||||||
ep->descs_dma_addr);
|
ep->descs_dma_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The hardware enforces a sub-2K maximum packet size, so we put
|
|
||||||
* two buffers on every hardware page.
|
|
||||||
*/
|
|
||||||
static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
|
static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
|
||||||
{
|
{
|
||||||
|
struct device *dev = ep->dev->dev.parent;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ep->descs = dma_alloc_coherent(NULL, sizeof(struct ep93xx_descs),
|
ep->descs = dma_alloc_coherent(dev, sizeof(struct ep93xx_descs),
|
||||||
&ep->descs_dma_addr, GFP_KERNEL | GFP_DMA);
|
&ep->descs_dma_addr, GFP_KERNEL);
|
||||||
if (ep->descs == NULL)
|
if (ep->descs == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
|
for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
|
||||||
void *page;
|
void *buf;
|
||||||
dma_addr_t d;
|
dma_addr_t d;
|
||||||
|
|
||||||
page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
|
buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL);
|
||||||
if (page == NULL)
|
if (buf == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE);
|
d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_FROM_DEVICE);
|
||||||
if (dma_mapping_error(NULL, d)) {
|
if (dma_mapping_error(dev, d)) {
|
||||||
free_page((unsigned long)page);
|
kfree(buf);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep->rx_buf[i] = page;
|
ep->rx_buf[i] = buf;
|
||||||
ep->descs->rdesc[i].buf_addr = d;
|
ep->descs->rdesc[i].buf_addr = d;
|
||||||
ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE;
|
ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE;
|
||||||
|
|
||||||
ep->rx_buf[i + 1] = page + PKT_BUF_SIZE;
|
|
||||||
ep->descs->rdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
|
|
||||||
ep->descs->rdesc[i + 1].rdesc1 = ((i + 1) << 16) | PKT_BUF_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
|
for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
|
||||||
void *page;
|
void *buf;
|
||||||
dma_addr_t d;
|
dma_addr_t d;
|
||||||
|
|
||||||
page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
|
buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL);
|
||||||
if (page == NULL)
|
if (buf == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE);
|
d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_TO_DEVICE);
|
||||||
if (dma_mapping_error(NULL, d)) {
|
if (dma_mapping_error(dev, d)) {
|
||||||
free_page((unsigned long)page);
|
kfree(buf);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep->tx_buf[i] = page;
|
ep->tx_buf[i] = buf;
|
||||||
ep->descs->tdesc[i].buf_addr = d;
|
ep->descs->tdesc[i].buf_addr = d;
|
||||||
|
|
||||||
ep->tx_buf[i + 1] = page + PKT_BUF_SIZE;
|
|
||||||
ep->descs->tdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -829,6 +828,7 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
ep = netdev_priv(dev);
|
ep = netdev_priv(dev);
|
||||||
ep->dev = dev;
|
ep->dev = dev;
|
||||||
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
netif_napi_add(dev, &ep->napi, ep93xx_poll, 64);
|
netif_napi_add(dev, &ep->napi, ep93xx_poll, 64);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, dev);
|
platform_set_drvdata(pdev, dev);
|
||||||
|
|
|
@ -388,6 +388,8 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bond_dev_queue_xmit - Prepare skb for xmit.
|
* bond_dev_queue_xmit - Prepare skb for xmit.
|
||||||
*
|
*
|
||||||
|
@ -400,6 +402,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
skb->dev = slave_dev;
|
skb->dev = slave_dev;
|
||||||
skb->priority = 1;
|
skb->priority = 1;
|
||||||
|
|
||||||
|
skb->queue_mapping = bond_queue_mapping(skb);
|
||||||
|
|
||||||
if (unlikely(netpoll_tx_running(slave_dev)))
|
if (unlikely(netpoll_tx_running(slave_dev)))
|
||||||
bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
|
bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
|
||||||
else
|
else
|
||||||
|
@ -4206,6 +4211,7 @@ static inline int bond_slave_override(struct bonding *bond,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
|
static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -4216,6 +4222,11 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
|
u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the original txq to restore before passing to the driver
|
||||||
|
*/
|
||||||
|
bond_queue_mapping(skb) = skb->queue_mapping;
|
||||||
|
|
||||||
if (unlikely(txq >= dev->real_num_tx_queues)) {
|
if (unlikely(txq >= dev->real_num_tx_queues)) {
|
||||||
do {
|
do {
|
||||||
txq -= dev->real_num_tx_queues;
|
txq -= dev->real_num_tx_queues;
|
||||||
|
|
|
@ -346,7 +346,7 @@ parse_eeprom (struct net_device *dev)
|
||||||
if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */
|
if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */
|
||||||
/* Check CRC */
|
/* Check CRC */
|
||||||
crc = ~ether_crc_le (256 - 4, sromdata);
|
crc = ~ether_crc_le (256 - 4, sromdata);
|
||||||
if (psrom->crc != crc) {
|
if (psrom->crc != cpu_to_le32(crc)) {
|
||||||
printk (KERN_ERR "%s: EEPROM data CRC error.\n",
|
printk (KERN_ERR "%s: EEPROM data CRC error.\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* Maintainer: Kumar Gala
|
* Maintainer: Kumar Gala
|
||||||
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
||||||
*
|
*
|
||||||
* Copyright 2002-2009 Freescale Semiconductor, Inc.
|
* Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
|
||||||
* Copyright 2007 MontaVista Software, Inc.
|
* Copyright 2007 MontaVista Software, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -476,9 +476,6 @@ static const struct net_device_ops gfar_netdev_ops = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
|
|
||||||
unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
|
|
||||||
|
|
||||||
void lock_rx_qs(struct gfar_private *priv)
|
void lock_rx_qs(struct gfar_private *priv)
|
||||||
{
|
{
|
||||||
int i = 0x0;
|
int i = 0x0;
|
||||||
|
@ -868,28 +865,28 @@ static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
|
||||||
|
|
||||||
rqfar--;
|
rqfar--;
|
||||||
rqfcr = RQFCR_CLE | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
|
rqfcr = RQFCR_CLE | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
|
||||||
ftp_rqfpr[rqfar] = rqfpr;
|
priv->ftp_rqfpr[rqfar] = rqfpr;
|
||||||
ftp_rqfcr[rqfar] = rqfcr;
|
priv->ftp_rqfcr[rqfar] = rqfcr;
|
||||||
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
||||||
|
|
||||||
rqfar--;
|
rqfar--;
|
||||||
rqfcr = RQFCR_CMP_NOMATCH;
|
rqfcr = RQFCR_CMP_NOMATCH;
|
||||||
ftp_rqfpr[rqfar] = rqfpr;
|
priv->ftp_rqfpr[rqfar] = rqfpr;
|
||||||
ftp_rqfcr[rqfar] = rqfcr;
|
priv->ftp_rqfcr[rqfar] = rqfcr;
|
||||||
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
||||||
|
|
||||||
rqfar--;
|
rqfar--;
|
||||||
rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND;
|
rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND;
|
||||||
rqfpr = class;
|
rqfpr = class;
|
||||||
ftp_rqfcr[rqfar] = rqfcr;
|
priv->ftp_rqfcr[rqfar] = rqfcr;
|
||||||
ftp_rqfpr[rqfar] = rqfpr;
|
priv->ftp_rqfpr[rqfar] = rqfpr;
|
||||||
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
||||||
|
|
||||||
rqfar--;
|
rqfar--;
|
||||||
rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_MASK | RQFCR_AND;
|
rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_MASK | RQFCR_AND;
|
||||||
rqfpr = class;
|
rqfpr = class;
|
||||||
ftp_rqfcr[rqfar] = rqfcr;
|
priv->ftp_rqfcr[rqfar] = rqfcr;
|
||||||
ftp_rqfpr[rqfar] = rqfpr;
|
priv->ftp_rqfpr[rqfar] = rqfpr;
|
||||||
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
||||||
|
|
||||||
return rqfar;
|
return rqfar;
|
||||||
|
@ -904,8 +901,8 @@ static void gfar_init_filer_table(struct gfar_private *priv)
|
||||||
|
|
||||||
/* Default rule */
|
/* Default rule */
|
||||||
rqfcr = RQFCR_CMP_MATCH;
|
rqfcr = RQFCR_CMP_MATCH;
|
||||||
ftp_rqfcr[rqfar] = rqfcr;
|
priv->ftp_rqfcr[rqfar] = rqfcr;
|
||||||
ftp_rqfpr[rqfar] = rqfpr;
|
priv->ftp_rqfpr[rqfar] = rqfpr;
|
||||||
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
|
||||||
|
|
||||||
rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6);
|
rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6);
|
||||||
|
@ -921,8 +918,8 @@ static void gfar_init_filer_table(struct gfar_private *priv)
|
||||||
/* Rest are masked rules */
|
/* Rest are masked rules */
|
||||||
rqfcr = RQFCR_CMP_NOMATCH;
|
rqfcr = RQFCR_CMP_NOMATCH;
|
||||||
for (i = 0; i < rqfar; i++) {
|
for (i = 0; i < rqfar; i++) {
|
||||||
ftp_rqfcr[i] = rqfcr;
|
priv->ftp_rqfcr[i] = rqfcr;
|
||||||
ftp_rqfpr[i] = rqfpr;
|
priv->ftp_rqfpr[i] = rqfpr;
|
||||||
gfar_write_filer(priv, i, rqfcr, rqfpr);
|
gfar_write_filer(priv, i, rqfcr, rqfpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* Maintainer: Kumar Gala
|
* Maintainer: Kumar Gala
|
||||||
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
||||||
*
|
*
|
||||||
* Copyright 2002-2009 Freescale Semiconductor, Inc.
|
* Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
@ -1107,10 +1107,12 @@ struct gfar_private {
|
||||||
/* HW time stamping enabled flag */
|
/* HW time stamping enabled flag */
|
||||||
int hwts_rx_en;
|
int hwts_rx_en;
|
||||||
int hwts_tx_en;
|
int hwts_tx_en;
|
||||||
|
|
||||||
|
/*Filer table*/
|
||||||
|
unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
|
||||||
|
unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
|
|
||||||
extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
|
|
||||||
|
|
||||||
static inline int gfar_has_errata(struct gfar_private *priv,
|
static inline int gfar_has_errata(struct gfar_private *priv,
|
||||||
enum gfar_errata err)
|
enum gfar_errata err)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* Maintainer: Kumar Gala
|
* Maintainer: Kumar Gala
|
||||||
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
* Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc.
|
* Copyright 2003-2006, 2008-2009, 2011 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This software may be used and distributed according to
|
* This software may be used and distributed according to
|
||||||
* the terms of the GNU Public License, Version 2, incorporated herein
|
* the terms of the GNU Public License, Version 2, incorporated herein
|
||||||
|
@ -609,15 +609,15 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
if (ethflow & RXH_L2DA) {
|
if (ethflow & RXH_L2DA) {
|
||||||
fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
|
fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
|
||||||
RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
|
|
||||||
fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
|
fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
|
||||||
RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -626,16 +626,16 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ethflow & RXH_IP_SRC) {
|
if (ethflow & RXH_IP_SRC) {
|
||||||
fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
if (ethflow & (RXH_IP_DST)) {
|
if (ethflow & (RXH_IP_DST)) {
|
||||||
fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -652,8 +652,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
if (ethflow & RXH_L3_PROTO) {
|
if (ethflow & RXH_L3_PROTO) {
|
||||||
fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -661,8 +661,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
if (ethflow & RXH_L4_B_0_1) {
|
if (ethflow & RXH_L4_B_0_1) {
|
||||||
fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -670,8 +670,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
|
||||||
if (ethflow & RXH_L4_B_2_3) {
|
if (ethflow & RXH_L4_B_2_3) {
|
||||||
fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
|
||||||
RQFCR_AND | RQFCR_HASHTBL_0;
|
RQFCR_AND | RQFCR_HASHTBL_0;
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
|
||||||
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
priv->cur_filer_idx = priv->cur_filer_idx - 1;
|
||||||
}
|
}
|
||||||
|
@ -705,12 +705,12 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_FILER_IDX + 1; i++) {
|
for (i = 0; i < MAX_FILER_IDX + 1; i++) {
|
||||||
local_rqfpr[j] = ftp_rqfpr[i];
|
local_rqfpr[j] = priv->ftp_rqfpr[i];
|
||||||
local_rqfcr[j] = ftp_rqfcr[i];
|
local_rqfcr[j] = priv->ftp_rqfcr[i];
|
||||||
j--;
|
j--;
|
||||||
if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE |
|
if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE |
|
||||||
RQFCR_CLE |RQFCR_AND)) &&
|
RQFCR_CLE |RQFCR_AND)) &&
|
||||||
(ftp_rqfpr[i] == cmp_rqfpr))
|
(priv->ftp_rqfpr[i] == cmp_rqfpr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,20 +724,22 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
|
||||||
* if it was already programmed, we need to overwrite these rules
|
* if it was already programmed, we need to overwrite these rules
|
||||||
*/
|
*/
|
||||||
for (l = i+1; l < MAX_FILER_IDX; l++) {
|
for (l = i+1; l < MAX_FILER_IDX; l++) {
|
||||||
if ((ftp_rqfcr[l] & RQFCR_CLE) &&
|
if ((priv->ftp_rqfcr[l] & RQFCR_CLE) &&
|
||||||
!(ftp_rqfcr[l] & RQFCR_AND)) {
|
!(priv->ftp_rqfcr[l] & RQFCR_AND)) {
|
||||||
ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
|
priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
|
||||||
RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
|
RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
|
||||||
ftp_rqfpr[l] = FPR_FILER_MASK;
|
priv->ftp_rqfpr[l] = FPR_FILER_MASK;
|
||||||
gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]);
|
gfar_write_filer(priv, l, priv->ftp_rqfcr[l],
|
||||||
|
priv->ftp_rqfpr[l]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND))
|
if (!(priv->ftp_rqfcr[l] & RQFCR_CLE) &&
|
||||||
|
(priv->ftp_rqfcr[l] & RQFCR_AND))
|
||||||
continue;
|
continue;
|
||||||
else {
|
else {
|
||||||
local_rqfpr[j] = ftp_rqfpr[l];
|
local_rqfpr[j] = priv->ftp_rqfpr[l];
|
||||||
local_rqfcr[j] = ftp_rqfcr[l];
|
local_rqfcr[j] = priv->ftp_rqfcr[l];
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,8 +752,8 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
|
||||||
|
|
||||||
/* Write back the popped out rules again */
|
/* Write back the popped out rules again */
|
||||||
for (k = j+1; k < MAX_FILER_IDX; k++) {
|
for (k = j+1; k < MAX_FILER_IDX; k++) {
|
||||||
ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
|
priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
|
||||||
ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
|
priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
|
||||||
gfar_write_filer(priv, priv->cur_filer_idx,
|
gfar_write_filer(priv, priv->cur_filer_idx,
|
||||||
local_rqfcr[k], local_rqfpr[k]);
|
local_rqfcr[k], local_rqfpr[k]);
|
||||||
if (!priv->cur_filer_idx)
|
if (!priv->cur_filer_idx)
|
||||||
|
|
|
@ -2373,6 +2373,9 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PCI_IOV */
|
#endif /* CONFIG_PCI_IOV */
|
||||||
adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
|
adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
|
||||||
|
/* i350 cannot do RSS and SR-IOV at the same time */
|
||||||
|
if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count)
|
||||||
|
adapter->rss_queues = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if rss_queues > 4 or vfs are going to be allocated with rss_queues
|
* if rss_queues > 4 or vfs are going to be allocated with rss_queues
|
||||||
|
|
|
@ -1406,6 +1406,7 @@ qlcnic_dump_que(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
|
||||||
|
|
||||||
for (loop = 0; loop < que->no_ops; loop++) {
|
for (loop = 0; loop < que->no_ops; loop++) {
|
||||||
QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
|
QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
|
||||||
|
addr = que->read_addr;
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
QLCNIC_RD_DUMP_REG(addr, base, &data);
|
QLCNIC_RD_DUMP_REG(addr, base, &data);
|
||||||
*buffer++ = cpu_to_le32(data);
|
*buffer++ = cpu_to_le32(data);
|
||||||
|
|
|
@ -2159,6 +2159,7 @@ qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb,
|
||||||
|
|
||||||
nf = &pbuf->frag_array[0];
|
nf = &pbuf->frag_array[0];
|
||||||
pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
|
pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
|
||||||
|
pbuf->skb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -2400,8 +2400,10 @@ static const struct of_device_id smc91x_match[] = {
|
||||||
{ .compatible = "smsc,lan91c94", },
|
{ .compatible = "smsc,lan91c94", },
|
||||||
{ .compatible = "smsc,lan91c111", },
|
{ .compatible = "smsc,lan91c111", },
|
||||||
{},
|
{},
|
||||||
}
|
};
|
||||||
MODULE_DEVICE_TABLE(of, smc91x_match);
|
MODULE_DEVICE_TABLE(of, smc91x_match);
|
||||||
|
#else
|
||||||
|
#define smc91x_match NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct dev_pm_ops smc_drv_pm_ops = {
|
static struct dev_pm_ops smc_drv_pm_ops = {
|
||||||
|
@ -2416,9 +2418,7 @@ static struct platform_driver smc_driver = {
|
||||||
.name = CARDNAME,
|
.name = CARDNAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &smc_drv_pm_ops,
|
.pm = &smc_drv_pm_ops,
|
||||||
#ifdef CONFIG_OF
|
|
||||||
.of_match_table = smc91x_match,
|
.of_match_table = smc91x_match,
|
||||||
#endif
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,11 @@ static int modparam_all_channels;
|
||||||
module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
|
module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
|
||||||
MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
|
MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
|
||||||
|
|
||||||
|
static int modparam_fastchanswitch;
|
||||||
|
module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
|
||||||
|
|
||||||
|
|
||||||
/* Module info */
|
/* Module info */
|
||||||
MODULE_AUTHOR("Jiri Slaby");
|
MODULE_AUTHOR("Jiri Slaby");
|
||||||
MODULE_AUTHOR("Nick Kossifidis");
|
MODULE_AUTHOR("Nick Kossifidis");
|
||||||
|
@ -2686,6 +2691,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
||||||
struct ath5k_hw *ah = sc->ah;
|
struct ath5k_hw *ah = sc->ah;
|
||||||
struct ath_common *common = ath5k_hw_common(ah);
|
struct ath_common *common = ath5k_hw_common(ah);
|
||||||
int ret, ani_mode;
|
int ret, ani_mode;
|
||||||
|
bool fast;
|
||||||
|
|
||||||
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
|
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
|
||||||
|
|
||||||
|
@ -2705,7 +2711,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
||||||
ath5k_drain_tx_buffs(sc);
|
ath5k_drain_tx_buffs(sc);
|
||||||
if (chan)
|
if (chan)
|
||||||
sc->curchan = chan;
|
sc->curchan = chan;
|
||||||
ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
|
|
||||||
|
fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
|
||||||
|
|
||||||
|
ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
|
||||||
skip_pcu);
|
skip_pcu);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
|
ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
|
||||||
|
|
|
@ -1124,9 +1124,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||||
/* Non fatal, can happen eg.
|
/* Non fatal, can happen eg.
|
||||||
* on mode change */
|
* on mode change */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else
|
} else {
|
||||||
|
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
|
||||||
|
"fast chan change successful\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save some registers before a reset
|
* Save some registers before a reset
|
||||||
|
|
|
@ -1218,10 +1218,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
|
||||||
* receive commit_rxon request
|
* receive commit_rxon request
|
||||||
* abort any previous channel switch if still in process
|
* abort any previous channel switch if still in process
|
||||||
*/
|
*/
|
||||||
if (priv->switch_rxon.switch_in_progress &&
|
if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
|
||||||
(priv->switch_rxon.channel != ctx->staging.channel)) {
|
(priv->switch_channel != ctx->staging.channel)) {
|
||||||
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
|
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
|
||||||
le16_to_cpu(priv->switch_rxon.channel));
|
le16_to_cpu(priv->switch_channel));
|
||||||
iwl_legacy_chswitch_done(priv, false);
|
iwl_legacy_chswitch_done(priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,7 +1237,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
|
||||||
|
|
||||||
memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
|
memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
|
||||||
iwl_legacy_print_rx_config_cmd(priv, ctx);
|
iwl_legacy_print_rx_config_cmd(priv, ctx);
|
||||||
return 0;
|
goto set_tx_power;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are currently associated and the new config requires
|
/* If we are currently associated and the new config requires
|
||||||
|
@ -1317,6 +1317,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
|
||||||
|
|
||||||
iwl4965_init_sensitivity(priv);
|
iwl4965_init_sensitivity(priv);
|
||||||
|
|
||||||
|
set_tx_power:
|
||||||
/* If we issue a new RXON command which required a tune then we must
|
/* If we issue a new RXON command which required a tune then we must
|
||||||
* send a new TXPOWER command or we won't be able to Tx any frames */
|
* send a new TXPOWER command or we won't be able to Tx any frames */
|
||||||
ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
|
ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
|
||||||
|
@ -1403,9 +1404,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->switch_rxon.channel = cmd.channel;
|
|
||||||
priv->switch_rxon.switch_in_progress = true;
|
|
||||||
|
|
||||||
return iwl_legacy_send_cmd_pdu(priv,
|
return iwl_legacy_send_cmd_pdu(priv,
|
||||||
REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
|
REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -859,12 +859,8 @@ void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success)
|
||||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->switch_rxon.switch_in_progress) {
|
if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
ieee80211_chswitch_done(ctx->vif, is_success);
|
ieee80211_chswitch_done(ctx->vif, is_success);
|
||||||
mutex_lock(&priv->mutex);
|
|
||||||
priv->switch_rxon.switch_in_progress = false;
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_legacy_chswitch_done);
|
EXPORT_SYMBOL(iwl_legacy_chswitch_done);
|
||||||
|
|
||||||
|
@ -876,9 +872,10 @@ void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||||
struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active;
|
struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active;
|
||||||
|
|
||||||
if (priv->switch_rxon.switch_in_progress) {
|
if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
if (!le32_to_cpu(csa->status) &&
|
return;
|
||||||
(csa->channel == priv->switch_rxon.channel)) {
|
|
||||||
|
if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
|
||||||
rxon->channel = csa->channel;
|
rxon->channel = csa->channel;
|
||||||
ctx->staging.channel = csa->channel;
|
ctx->staging.channel = csa->channel;
|
||||||
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
||||||
|
@ -890,7 +887,6 @@ void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
iwl_legacy_chswitch_done(priv, false);
|
iwl_legacy_chswitch_done(priv, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(iwl_legacy_rx_csa);
|
EXPORT_SYMBOL(iwl_legacy_rx_csa);
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
|
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
|
||||||
|
|
|
@ -560,7 +560,7 @@ void iwl_legacy_free_geos(struct iwl_priv *priv);
|
||||||
#define STATUS_SCAN_HW 15
|
#define STATUS_SCAN_HW 15
|
||||||
#define STATUS_POWER_PMI 16
|
#define STATUS_POWER_PMI 16
|
||||||
#define STATUS_FW_ERROR 17
|
#define STATUS_FW_ERROR 17
|
||||||
|
#define STATUS_CHANNEL_SWITCH_PENDING 18
|
||||||
|
|
||||||
static inline int iwl_legacy_is_ready(struct iwl_priv *priv)
|
static inline int iwl_legacy_is_ready(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -854,17 +854,6 @@ struct traffic_stats {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* iwl_switch_rxon: "channel switch" structure
|
|
||||||
*
|
|
||||||
* @ switch_in_progress: channel switch in progress
|
|
||||||
* @ channel: new channel
|
|
||||||
*/
|
|
||||||
struct iwl_switch_rxon {
|
|
||||||
bool switch_in_progress;
|
|
||||||
__le16 channel;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
|
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
|
||||||
* to perform continuous uCode event logging operation if enabled
|
* to perform continuous uCode event logging operation if enabled
|
||||||
|
@ -1115,7 +1104,7 @@ struct iwl_priv {
|
||||||
|
|
||||||
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
|
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
|
||||||
|
|
||||||
struct iwl_switch_rxon switch_rxon;
|
__le16 switch_channel;
|
||||||
|
|
||||||
/* 1st responses from initialize and runtime uCode images.
|
/* 1st responses from initialize and runtime uCode images.
|
||||||
* _4965's initialize alive response contains some calibration data. */
|
* _4965's initialize alive response contains some calibration data. */
|
||||||
|
|
|
@ -2861,16 +2861,13 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
||||||
test_bit(STATUS_SCANNING, &priv->status))
|
test_bit(STATUS_SCANNING, &priv->status) ||
|
||||||
|
test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!iwl_legacy_is_associated_ctx(ctx))
|
if (!iwl_legacy_is_associated_ctx(ctx))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* channel switch in progress */
|
|
||||||
if (priv->switch_rxon.switch_in_progress == true)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (priv->cfg->ops->lib->set_channel_switch) {
|
if (priv->cfg->ops->lib->set_channel_switch) {
|
||||||
|
|
||||||
ch = channel->hw_value;
|
ch = channel->hw_value;
|
||||||
|
@ -2919,15 +2916,18 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||||
* at this point, staging_rxon has the
|
* at this point, staging_rxon has the
|
||||||
* configuration for channel switch
|
* configuration for channel switch
|
||||||
*/
|
*/
|
||||||
if (priv->cfg->ops->lib->set_channel_switch(priv,
|
set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
|
||||||
ch_switch))
|
priv->switch_channel = cpu_to_le16(ch);
|
||||||
priv->switch_rxon.switch_in_progress = false;
|
if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
|
||||||
|
clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
|
||||||
|
&priv->status);
|
||||||
|
priv->switch_channel = 0;
|
||||||
|
ieee80211_chswitch_done(ctx->vif, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&priv->mutex);
|
mutex_unlock(&priv->mutex);
|
||||||
if (!priv->switch_rxon.switch_in_progress)
|
|
||||||
ieee80211_chswitch_done(ctx->vif, false);
|
|
||||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,79 +177,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
|
|
||||||
struct ieee80211_channel_switch *ch_switch)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* MULTI-FIXME
|
|
||||||
* See iwl_mac_channel_switch.
|
|
||||||
*/
|
|
||||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
|
||||||
struct iwl6000_channel_switch_cmd cmd;
|
|
||||||
const struct iwl_channel_info *ch_info;
|
|
||||||
u32 switch_time_in_usec, ucode_switch_time;
|
|
||||||
u16 ch;
|
|
||||||
u32 tsf_low;
|
|
||||||
u8 switch_count;
|
|
||||||
u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
|
|
||||||
struct ieee80211_vif *vif = ctx->vif;
|
|
||||||
struct iwl_host_cmd hcmd = {
|
|
||||||
.id = REPLY_CHANNEL_SWITCH,
|
|
||||||
.len = { sizeof(cmd), },
|
|
||||||
.flags = CMD_SYNC,
|
|
||||||
.data = { &cmd, },
|
|
||||||
};
|
|
||||||
|
|
||||||
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
|
|
||||||
ch = ch_switch->channel->hw_value;
|
|
||||||
IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
|
|
||||||
ctx->active.channel, ch);
|
|
||||||
cmd.channel = cpu_to_le16(ch);
|
|
||||||
cmd.rxon_flags = ctx->staging.flags;
|
|
||||||
cmd.rxon_filter_flags = ctx->staging.filter_flags;
|
|
||||||
switch_count = ch_switch->count;
|
|
||||||
tsf_low = ch_switch->timestamp & 0x0ffffffff;
|
|
||||||
/*
|
|
||||||
* calculate the ucode channel switch time
|
|
||||||
* adding TSF as one of the factor for when to switch
|
|
||||||
*/
|
|
||||||
if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
|
|
||||||
if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
|
|
||||||
beacon_interval)) {
|
|
||||||
switch_count -= (priv->ucode_beacon_time -
|
|
||||||
tsf_low) / beacon_interval;
|
|
||||||
} else
|
|
||||||
switch_count = 0;
|
|
||||||
}
|
|
||||||
if (switch_count <= 1)
|
|
||||||
cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
|
|
||||||
else {
|
|
||||||
switch_time_in_usec =
|
|
||||||
vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
|
|
||||||
ucode_switch_time = iwl_usecs_to_beacons(priv,
|
|
||||||
switch_time_in_usec,
|
|
||||||
beacon_interval);
|
|
||||||
cmd.switch_time = iwl_add_beacon_time(priv,
|
|
||||||
priv->ucode_beacon_time,
|
|
||||||
ucode_switch_time,
|
|
||||||
beacon_interval);
|
|
||||||
}
|
|
||||||
IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
|
|
||||||
cmd.switch_time);
|
|
||||||
ch_info = iwl_get_channel_info(priv, priv->band, ch);
|
|
||||||
if (ch_info)
|
|
||||||
cmd.expect_beacon = is_channel_radar(ch_info);
|
|
||||||
else {
|
|
||||||
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
|
|
||||||
ctx->active.channel, ch);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
priv->switch_rxon.channel = cmd.channel;
|
|
||||||
priv->switch_rxon.switch_in_progress = true;
|
|
||||||
|
|
||||||
return iwl_send_cmd_sync(priv, &hcmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct iwl_lib_ops iwl2000_lib = {
|
static struct iwl_lib_ops iwl2000_lib = {
|
||||||
.set_hw_params = iwl2000_hw_set_hw_params,
|
.set_hw_params = iwl2000_hw_set_hw_params,
|
||||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||||
|
@ -258,7 +185,6 @@ static struct iwl_lib_ops iwl2000_lib = {
|
||||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||||
.send_tx_power = iwlagn_send_tx_power,
|
.send_tx_power = iwlagn_send_tx_power,
|
||||||
.update_chain_flags = iwl_update_chain_flags,
|
.update_chain_flags = iwl_update_chain_flags,
|
||||||
.set_channel_switch = iwl2030_hw_channel_switch,
|
|
||||||
.apm_ops = {
|
.apm_ops = {
|
||||||
.init = iwl_apm_init,
|
.init = iwl_apm_init,
|
||||||
.config = iwl2000_nic_config,
|
.config = iwl2000_nic_config,
|
||||||
|
|
|
@ -331,8 +331,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
|
||||||
ctx->active.channel, ch);
|
ctx->active.channel, ch);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
priv->switch_rxon.channel = cmd.channel;
|
|
||||||
priv->switch_rxon.switch_in_progress = true;
|
|
||||||
|
|
||||||
return iwl_send_cmd_sync(priv, &hcmd);
|
return iwl_send_cmd_sync(priv, &hcmd);
|
||||||
}
|
}
|
||||||
|
@ -425,7 +423,6 @@ static struct iwl_base_params iwl5000_base_params = {
|
||||||
};
|
};
|
||||||
static struct iwl_ht_params iwl5000_ht_params = {
|
static struct iwl_ht_params iwl5000_ht_params = {
|
||||||
.ht_greenfield_support = true,
|
.ht_greenfield_support = true,
|
||||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IWL_DEVICE_5000 \
|
#define IWL_DEVICE_5000 \
|
||||||
|
|
|
@ -270,8 +270,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
|
||||||
ctx->active.channel, ch);
|
ctx->active.channel, ch);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
priv->switch_rxon.channel = cmd.channel;
|
|
||||||
priv->switch_rxon.switch_in_progress = true;
|
|
||||||
|
|
||||||
return iwl_send_cmd_sync(priv, &hcmd);
|
return iwl_send_cmd_sync(priv, &hcmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,17 +163,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
|
||||||
__le16 fc, __le32 *tx_flags)
|
__le16 fc, __le32 *tx_flags)
|
||||||
{
|
{
|
||||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
|
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
|
||||||
info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
|
||||||
|
info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||||
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->cfg->ht_params &&
|
|
||||||
priv->cfg->ht_params->use_rts_for_aggregation &&
|
|
||||||
info->flags & IEEE80211_TX_CTL_AMPDU) {
|
|
||||||
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||||
|
|
|
@ -325,6 +325,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* force CTS-to-self frames protection if RTS-CTS is not preferred
|
||||||
|
* one aggregation protection method
|
||||||
|
*/
|
||||||
|
if (!(priv->cfg->ht_params &&
|
||||||
|
priv->cfg->ht_params->use_rts_for_aggregation))
|
||||||
|
ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
|
||||||
|
|
||||||
if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
|
if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
|
||||||
!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
|
!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
|
||||||
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
|
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
|
||||||
|
@ -342,10 +350,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||||
* receive commit_rxon request
|
* receive commit_rxon request
|
||||||
* abort any previous channel switch if still in process
|
* abort any previous channel switch if still in process
|
||||||
*/
|
*/
|
||||||
if (priv->switch_rxon.switch_in_progress &&
|
if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
|
||||||
(priv->switch_rxon.channel != ctx->staging.channel)) {
|
(priv->switch_channel != ctx->staging.channel)) {
|
||||||
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
|
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
|
||||||
le16_to_cpu(priv->switch_rxon.channel));
|
le16_to_cpu(priv->switch_channel));
|
||||||
iwl_chswitch_done(priv, false);
|
iwl_chswitch_done(priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +370,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(active, &ctx->staging, sizeof(*active));
|
memcpy(active, &ctx->staging, sizeof(*active));
|
||||||
|
/*
|
||||||
|
* We do not commit tx power settings while channel changing,
|
||||||
|
* do it now if after settings changed.
|
||||||
|
*/
|
||||||
|
iwl_set_tx_power(priv, priv->tx_power_next, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2843,16 +2843,13 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
||||||
test_bit(STATUS_SCANNING, &priv->status))
|
test_bit(STATUS_SCANNING, &priv->status) ||
|
||||||
|
test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!iwl_is_associated_ctx(ctx))
|
if (!iwl_is_associated_ctx(ctx))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* channel switch in progress */
|
|
||||||
if (priv->switch_rxon.switch_in_progress == true)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (priv->cfg->ops->lib->set_channel_switch) {
|
if (priv->cfg->ops->lib->set_channel_switch) {
|
||||||
|
|
||||||
ch = channel->hw_value;
|
ch = channel->hw_value;
|
||||||
|
@ -2901,15 +2898,19 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||||
* at this point, staging_rxon has the
|
* at this point, staging_rxon has the
|
||||||
* configuration for channel switch
|
* configuration for channel switch
|
||||||
*/
|
*/
|
||||||
|
set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
|
||||||
|
priv->switch_channel = cpu_to_le16(ch);
|
||||||
if (priv->cfg->ops->lib->set_channel_switch(priv,
|
if (priv->cfg->ops->lib->set_channel_switch(priv,
|
||||||
ch_switch))
|
ch_switch)) {
|
||||||
priv->switch_rxon.switch_in_progress = false;
|
clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
|
||||||
|
&priv->status);
|
||||||
|
priv->switch_channel = 0;
|
||||||
|
ieee80211_chswitch_done(ctx->vif, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&priv->mutex);
|
mutex_unlock(&priv->mutex);
|
||||||
if (!priv->switch_rxon.switch_in_progress)
|
|
||||||
ieee80211_chswitch_done(ctx->vif, false);
|
|
||||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -843,12 +843,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
|
||||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->switch_rxon.switch_in_progress) {
|
if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
ieee80211_chswitch_done(ctx->vif, is_success);
|
ieee80211_chswitch_done(ctx->vif, is_success);
|
||||||
mutex_lock(&priv->mutex);
|
|
||||||
priv->switch_rxon.switch_in_progress = false;
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
|
|
|
@ -560,6 +560,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
|
||||||
#define STATUS_POWER_PMI 16
|
#define STATUS_POWER_PMI 16
|
||||||
#define STATUS_FW_ERROR 17
|
#define STATUS_FW_ERROR 17
|
||||||
#define STATUS_DEVICE_ENABLED 18
|
#define STATUS_DEVICE_ENABLED 18
|
||||||
|
#define STATUS_CHANNEL_SWITCH_PENDING 19
|
||||||
|
|
||||||
|
|
||||||
static inline int iwl_is_ready(struct iwl_priv *priv)
|
static inline int iwl_is_ready(struct iwl_priv *priv)
|
||||||
|
|
|
@ -981,17 +981,6 @@ struct traffic_stats {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* iwl_switch_rxon: "channel switch" structure
|
|
||||||
*
|
|
||||||
* @ switch_in_progress: channel switch in progress
|
|
||||||
* @ channel: new channel
|
|
||||||
*/
|
|
||||||
struct iwl_switch_rxon {
|
|
||||||
bool switch_in_progress;
|
|
||||||
__le16 channel;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
|
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
|
||||||
* to perform continuous uCode event logging operation if enabled
|
* to perform continuous uCode event logging operation if enabled
|
||||||
|
@ -1287,7 +1276,7 @@ struct iwl_priv {
|
||||||
|
|
||||||
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
|
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
|
||||||
|
|
||||||
struct iwl_switch_rxon switch_rxon;
|
__le16 switch_channel;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u32 error_event_table;
|
u32 error_event_table;
|
||||||
|
|
|
@ -250,9 +250,10 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||||
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
|
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
|
||||||
|
|
||||||
if (priv->switch_rxon.switch_in_progress) {
|
if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||||
if (!le32_to_cpu(csa->status) &&
|
return;
|
||||||
(csa->channel == priv->switch_rxon.channel)) {
|
|
||||||
|
if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
|
||||||
rxon->channel = csa->channel;
|
rxon->channel = csa->channel;
|
||||||
ctx->staging.channel = csa->channel;
|
ctx->staging.channel = csa->channel;
|
||||||
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
||||||
|
@ -264,7 +265,6 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
iwl_chswitch_done(priv, false);
|
iwl_chswitch_done(priv, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||||
|
|
|
@ -907,7 +907,7 @@ static void if_sdio_interrupt(struct sdio_func *func)
|
||||||
card = sdio_get_drvdata(func);
|
card = sdio_get_drvdata(func);
|
||||||
|
|
||||||
cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
|
cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
|
||||||
if (ret)
|
if (ret || !cause)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
|
lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
|
||||||
|
@ -1008,10 +1008,6 @@ static int if_sdio_probe(struct sdio_func *func,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto release;
|
goto release;
|
||||||
|
|
||||||
ret = sdio_claim_irq(func, if_sdio_interrupt);
|
|
||||||
if (ret)
|
|
||||||
goto disable;
|
|
||||||
|
|
||||||
/* For 1-bit transfers to the 8686 model, we need to enable the
|
/* For 1-bit transfers to the 8686 model, we need to enable the
|
||||||
* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
|
* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
|
||||||
* bit to allow access to non-vendor registers. */
|
* bit to allow access to non-vendor registers. */
|
||||||
|
@ -1082,6 +1078,21 @@ static int if_sdio_probe(struct sdio_func *func,
|
||||||
else
|
else
|
||||||
card->rx_unit = 0;
|
card->rx_unit = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the interrupt handler late.
|
||||||
|
*
|
||||||
|
* If we set it up earlier, the (buggy) hardware generates a spurious
|
||||||
|
* interrupt, even before the interrupt has been enabled, with
|
||||||
|
* CCCR_INTx = 0.
|
||||||
|
*
|
||||||
|
* We register the interrupt handler late so that we can handle any
|
||||||
|
* spurious interrupts, and also to avoid generation of that known
|
||||||
|
* spurious interrupt in the first place.
|
||||||
|
*/
|
||||||
|
ret = sdio_claim_irq(func, if_sdio_interrupt);
|
||||||
|
if (ret)
|
||||||
|
goto disable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable interrupts now that everything is set up
|
* Enable interrupts now that everything is set up
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -250,7 +250,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||||
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
|
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
|
||||||
rt2x00link_reset_tuner(rt2x00dev, false);
|
rt2x00link_reset_tuner(rt2x00dev, false);
|
||||||
|
|
||||||
if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
|
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
|
||||||
|
test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
|
||||||
(ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
|
(ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
|
||||||
(conf->flags & IEEE80211_CONF_PS)) {
|
(conf->flags & IEEE80211_CONF_PS)) {
|
||||||
beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
|
beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
|
||||||
|
|
|
@ -146,6 +146,9 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
|
||||||
struct rt2x00_dev *rt2x00dev =
|
struct rt2x00_dev *rt2x00dev =
|
||||||
container_of(work, struct rt2x00_dev, autowakeup_work.work);
|
container_of(work, struct rt2x00_dev, autowakeup_work.work);
|
||||||
|
|
||||||
|
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||||
|
return;
|
||||||
|
|
||||||
if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
|
if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
|
||||||
ERROR(rt2x00dev, "Device failed to wakeup.\n");
|
ERROR(rt2x00dev, "Device failed to wakeup.\n");
|
||||||
clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
|
clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
|
||||||
|
@ -1160,6 +1163,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
|
||||||
* Stop all work.
|
* Stop all work.
|
||||||
*/
|
*/
|
||||||
cancel_work_sync(&rt2x00dev->intf_work);
|
cancel_work_sync(&rt2x00dev->intf_work);
|
||||||
|
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
|
||||||
if (rt2x00_is_usb(rt2x00dev)) {
|
if (rt2x00_is_usb(rt2x00dev)) {
|
||||||
del_timer_sync(&rt2x00dev->txstatus_timer);
|
del_timer_sync(&rt2x00dev->txstatus_timer);
|
||||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||||
|
|
|
@ -669,6 +669,19 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||||
&rx_status,
|
&rx_status,
|
||||||
(u8 *) pdesc, skb);
|
(u8 *) pdesc, skb);
|
||||||
|
|
||||||
|
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
||||||
|
if (unlikely(!new_skb)) {
|
||||||
|
RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
|
||||||
|
DBG_DMESG,
|
||||||
|
("can't alloc skb for rx\n"));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_unmap_single(rtlpci->pdev,
|
||||||
|
*((dma_addr_t *) skb->cb),
|
||||||
|
rtlpci->rxbuffersize,
|
||||||
|
PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
|
skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
|
||||||
false,
|
false,
|
||||||
HW_DESC_RXPKT_LEN));
|
HW_DESC_RXPKT_LEN));
|
||||||
|
@ -685,22 +698,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||||
hdr = rtl_get_hdr(skb);
|
hdr = rtl_get_hdr(skb);
|
||||||
fc = rtl_get_fc(skb);
|
fc = rtl_get_fc(skb);
|
||||||
|
|
||||||
/* try for new buffer - if allocation fails, drop
|
if (!stats.crc && !stats.hwerror) {
|
||||||
* frame and reuse old buffer
|
|
||||||
*/
|
|
||||||
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
|
||||||
if (unlikely(!new_skb)) {
|
|
||||||
RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
|
|
||||||
DBG_DMESG,
|
|
||||||
("can't alloc skb for rx\n"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
pci_unmap_single(rtlpci->pdev,
|
|
||||||
*((dma_addr_t *) skb->cb),
|
|
||||||
rtlpci->rxbuffersize,
|
|
||||||
PCI_DMA_FROMDEVICE);
|
|
||||||
|
|
||||||
if (!stats.crc || !stats.hwerror) {
|
|
||||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
|
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
|
||||||
sizeof(rx_status));
|
sizeof(rx_status));
|
||||||
|
|
||||||
|
|
|
@ -539,11 +539,13 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
|
||||||
if (!pc->hostmode)
|
if (!pc->hostmode)
|
||||||
ssb_pcicore_init_clientmode(pc);
|
ssb_pcicore_init_clientmode(pc);
|
||||||
|
|
||||||
/* Additional always once-executed workarounds */
|
/* Additional PCIe always once-executed workarounds */
|
||||||
|
if (dev->id.coreid == SSB_DEV_PCIE) {
|
||||||
ssb_pcicore_serdes_workaround(pc);
|
ssb_pcicore_serdes_workaround(pc);
|
||||||
/* TODO: ASPM */
|
/* TODO: ASPM */
|
||||||
/* TODO: Clock Request Update */
|
/* TODO: Clock Request Update */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
|
static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
|
||||||
{
|
{
|
||||||
|
|
|
@ -268,7 +268,7 @@ struct ethtool_pauseparam {
|
||||||
__u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
|
__u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
|
||||||
|
|
||||||
/* If the link is being auto-negotiated (via ethtool_cmd.autoneg
|
/* If the link is being auto-negotiated (via ethtool_cmd.autoneg
|
||||||
* being true) the user may set 'autonet' here non-zero to have the
|
* being true) the user may set 'autoneg' here non-zero to have the
|
||||||
* pause parameters be auto-negotiated too. In such a case, the
|
* pause parameters be auto-negotiated too. In such a case, the
|
||||||
* {rx,tx}_pause values below determine what capabilities are
|
* {rx,tx}_pause values below determine what capabilities are
|
||||||
* advertised.
|
* advertised.
|
||||||
|
@ -811,7 +811,7 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
|
||||||
* @get_tx_csum: Deprecated as redundant. Report whether transmit checksums
|
* @get_tx_csum: Deprecated as redundant. Report whether transmit checksums
|
||||||
* are turned on or off.
|
* are turned on or off.
|
||||||
* @set_tx_csum: Deprecated in favour of generic netdev features. Turn
|
* @set_tx_csum: Deprecated in favour of generic netdev features. Turn
|
||||||
* transmit checksums on or off. Returns a egative error code or zero.
|
* transmit checksums on or off. Returns a negative error code or zero.
|
||||||
* @get_sg: Deprecated as redundant. Report whether scatter-gather is
|
* @get_sg: Deprecated as redundant. Report whether scatter-gather is
|
||||||
* enabled.
|
* enabled.
|
||||||
* @set_sg: Deprecated in favour of generic netdev features. Turn
|
* @set_sg: Deprecated in favour of generic netdev features. Turn
|
||||||
|
@ -1087,7 +1087,7 @@ struct ethtool_ops {
|
||||||
/* The following are all involved in forcing a particular link
|
/* The following are all involved in forcing a particular link
|
||||||
* mode for the device for setting things. When getting the
|
* mode for the device for setting things. When getting the
|
||||||
* devices settings, these indicate the current mode and whether
|
* devices settings, these indicate the current mode and whether
|
||||||
* it was foced up into this mode or autonegotiated.
|
* it was forced up into this mode or autonegotiated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
|
/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct tpacket_auxdata {
|
||||||
__u16 tp_mac;
|
__u16 tp_mac;
|
||||||
__u16 tp_net;
|
__u16 tp_net;
|
||||||
__u16 tp_vlan_tci;
|
__u16 tp_vlan_tci;
|
||||||
|
__u16 tp_padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Rx ring - header status */
|
/* Rx ring - header status */
|
||||||
|
@ -101,6 +102,7 @@ struct tpacket2_hdr {
|
||||||
__u32 tp_sec;
|
__u32 tp_sec;
|
||||||
__u32 tp_nsec;
|
__u32 tp_nsec;
|
||||||
__u16 tp_vlan_tci;
|
__u16 tp_vlan_tci;
|
||||||
|
__u16 tp_padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
|
#define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
|
||||||
|
|
|
@ -225,7 +225,7 @@ static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __vlan_put_tag - regular VLAN tag inserting
|
* vlan_insert_tag - regular VLAN tag inserting
|
||||||
* @skb: skbuff to tag
|
* @skb: skbuff to tag
|
||||||
* @vlan_tci: VLAN TCI to insert
|
* @vlan_tci: VLAN TCI to insert
|
||||||
*
|
*
|
||||||
|
@ -234,8 +234,10 @@ static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
|
||||||
*
|
*
|
||||||
* Following the skb_unshare() example, in case of error, the calling function
|
* Following the skb_unshare() example, in case of error, the calling function
|
||||||
* doesn't have to worry about freeing the original skb.
|
* doesn't have to worry about freeing the original skb.
|
||||||
|
*
|
||||||
|
* Does not change skb->protocol so this function can be used during receive.
|
||||||
*/
|
*/
|
||||||
static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
|
static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||||
{
|
{
|
||||||
struct vlan_ethhdr *veth;
|
struct vlan_ethhdr *veth;
|
||||||
|
|
||||||
|
@ -255,8 +257,25 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||||
/* now, the TCI */
|
/* now, the TCI */
|
||||||
veth->h_vlan_TCI = htons(vlan_tci);
|
veth->h_vlan_TCI = htons(vlan_tci);
|
||||||
|
|
||||||
skb->protocol = htons(ETH_P_8021Q);
|
return skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __vlan_put_tag - regular VLAN tag inserting
|
||||||
|
* @skb: skbuff to tag
|
||||||
|
* @vlan_tci: VLAN TCI to insert
|
||||||
|
*
|
||||||
|
* Inserts the VLAN tag into @skb as part of the payload
|
||||||
|
* Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
|
||||||
|
*
|
||||||
|
* Following the skb_unshare() example, in case of error, the calling function
|
||||||
|
* doesn't have to worry about freeing the original skb.
|
||||||
|
*/
|
||||||
|
static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
|
||||||
|
{
|
||||||
|
skb = vlan_insert_tag(skb, vlan_tci);
|
||||||
|
if (skb)
|
||||||
|
skb->protocol = htons(ETH_P_8021Q);
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2555,7 +2555,7 @@ extern void netdev_class_remove_file(struct class_attribute *class_attr);
|
||||||
|
|
||||||
extern struct kobj_ns_type_operations net_ns_type_operations;
|
extern struct kobj_ns_type_operations net_ns_type_operations;
|
||||||
|
|
||||||
extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len);
|
extern const char *netdev_drivername(const struct net_device *dev);
|
||||||
|
|
||||||
extern void linkwatch_run_queue(void);
|
extern void linkwatch_run_queue(void);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@ enum ip_conntrack_info {
|
||||||
/* >= this indicates reply direction */
|
/* >= this indicates reply direction */
|
||||||
IP_CT_IS_REPLY,
|
IP_CT_IS_REPLY,
|
||||||
|
|
||||||
|
IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
|
||||||
|
IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
|
||||||
|
IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,
|
||||||
/* Number of distinct IP_CT types (no NEW in reply dirn). */
|
/* Number of distinct IP_CT types (no NEW in reply dirn). */
|
||||||
IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
|
IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
|
||||||
};
|
};
|
||||||
|
|
|
@ -1256,6 +1256,11 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
|
||||||
skb->tail += len;
|
skb->tail += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void skb_reset_mac_len(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
skb->mac_len = skb->network_header - skb->mac_header;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
||||||
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
|
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,31 @@ bool vlan_do_receive(struct sk_buff **skbp)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
skb->dev = vlan_dev;
|
skb->dev = vlan_dev;
|
||||||
|
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||||
|
/* Our lower layer thinks this is not local, let's make sure.
|
||||||
|
* This allows the VLAN to have a different MAC than the
|
||||||
|
* underlying device, and still route correctly. */
|
||||||
|
if (!compare_ether_addr(eth_hdr(skb)->h_dest,
|
||||||
|
vlan_dev->dev_addr))
|
||||||
|
skb->pkt_type = PACKET_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(vlan_dev_info(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) {
|
||||||
|
unsigned int offset = skb->data - skb_mac_header(skb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vlan_insert_tag expect skb->data pointing to mac header.
|
||||||
|
* So change skb->data before calling it and change back to
|
||||||
|
* original position later
|
||||||
|
*/
|
||||||
|
skb_push(skb, offset);
|
||||||
|
skb = *skbp = vlan_insert_tag(skb, skb->vlan_tci);
|
||||||
|
if (!skb)
|
||||||
|
return false;
|
||||||
|
skb_pull(skb, offset + VLAN_HLEN);
|
||||||
|
skb_reset_mac_len(skb);
|
||||||
|
}
|
||||||
|
|
||||||
skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
|
skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
|
||||||
skb->vlan_tci = 0;
|
skb->vlan_tci = 0;
|
||||||
|
|
||||||
|
@ -31,22 +56,8 @@ bool vlan_do_receive(struct sk_buff **skbp)
|
||||||
u64_stats_update_begin(&rx_stats->syncp);
|
u64_stats_update_begin(&rx_stats->syncp);
|
||||||
rx_stats->rx_packets++;
|
rx_stats->rx_packets++;
|
||||||
rx_stats->rx_bytes += skb->len;
|
rx_stats->rx_bytes += skb->len;
|
||||||
|
if (skb->pkt_type == PACKET_MULTICAST)
|
||||||
switch (skb->pkt_type) {
|
|
||||||
case PACKET_BROADCAST:
|
|
||||||
break;
|
|
||||||
case PACKET_MULTICAST:
|
|
||||||
rx_stats->rx_multicast++;
|
rx_stats->rx_multicast++;
|
||||||
break;
|
|
||||||
case PACKET_OTHERHOST:
|
|
||||||
/* Our lower layer thinks this is not local, let's make sure.
|
|
||||||
* This allows the VLAN to have a different MAC than the
|
|
||||||
* underlying device, and still route correctly. */
|
|
||||||
if (!compare_ether_addr(eth_hdr(skb)->h_dest,
|
|
||||||
vlan_dev->dev_addr))
|
|
||||||
skb->pkt_type = PACKET_HOST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
u64_stats_update_end(&rx_stats->syncp);
|
u64_stats_update_end(&rx_stats->syncp);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,18 +100,13 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vlan_gro_frags);
|
EXPORT_SYMBOL(vlan_gro_frags);
|
||||||
|
|
||||||
static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
|
static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
|
|
||||||
if (skb_cow(skb, skb_headroom(skb)) < 0)
|
if (skb_cow(skb, skb_headroom(skb)) < 0)
|
||||||
skb = NULL;
|
return NULL;
|
||||||
if (skb) {
|
memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
|
||||||
/* Lifted from Gleb's VLAN code... */
|
|
||||||
memmove(skb->data - ETH_HLEN,
|
|
||||||
skb->data - VLAN_ETH_HLEN, 12);
|
|
||||||
skb->mac_header += VLAN_HLEN;
|
skb->mac_header += VLAN_HLEN;
|
||||||
}
|
skb_reset_mac_len(skb);
|
||||||
}
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +167,7 @@ struct sk_buff *vlan_untag(struct sk_buff *skb)
|
||||||
skb_pull_rcsum(skb, VLAN_HLEN);
|
skb_pull_rcsum(skb, VLAN_HLEN);
|
||||||
vlan_set_encap_proto(skb, vhdr);
|
vlan_set_encap_proto(skb, vhdr);
|
||||||
|
|
||||||
skb = vlan_check_reorder_header(skb);
|
skb = vlan_reorder_header(skb);
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
|
|
|
@ -104,10 +104,16 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dst_ops fake_dst_ops = {
|
static struct dst_ops fake_dst_ops = {
|
||||||
.family = AF_INET,
|
.family = AF_INET,
|
||||||
.protocol = cpu_to_be16(ETH_P_IP),
|
.protocol = cpu_to_be16(ETH_P_IP),
|
||||||
.update_pmtu = fake_update_pmtu,
|
.update_pmtu = fake_update_pmtu,
|
||||||
|
.cow_metrics = fake_cow_metrics,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3114,7 +3114,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
|
||||||
|
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
skb->mac_len = skb->network_header - skb->mac_header;
|
skb_reset_mac_len(skb);
|
||||||
|
|
||||||
pt_prev = NULL;
|
pt_prev = NULL;
|
||||||
|
|
||||||
|
@ -6178,6 +6178,11 @@ static int dev_cpu_callback(struct notifier_block *nfb,
|
||||||
oldsd->output_queue = NULL;
|
oldsd->output_queue = NULL;
|
||||||
oldsd->output_queue_tailp = &oldsd->output_queue;
|
oldsd->output_queue_tailp = &oldsd->output_queue;
|
||||||
}
|
}
|
||||||
|
/* Append NAPI poll list from offline CPU. */
|
||||||
|
if (!list_empty(&oldsd->poll_list)) {
|
||||||
|
list_splice_init(&oldsd->poll_list, &sd->poll_list);
|
||||||
|
raise_softirq_irqoff(NET_RX_SOFTIRQ);
|
||||||
|
}
|
||||||
|
|
||||||
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
@ -6264,29 +6269,23 @@ err_name:
|
||||||
/**
|
/**
|
||||||
* netdev_drivername - network driver for the device
|
* netdev_drivername - network driver for the device
|
||||||
* @dev: network device
|
* @dev: network device
|
||||||
* @buffer: buffer for resulting name
|
|
||||||
* @len: size of buffer
|
|
||||||
*
|
*
|
||||||
* Determine network driver for device.
|
* Determine network driver for device.
|
||||||
*/
|
*/
|
||||||
char *netdev_drivername(const struct net_device *dev, char *buffer, int len)
|
const char *netdev_drivername(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
const struct device_driver *driver;
|
const struct device_driver *driver;
|
||||||
const struct device *parent;
|
const struct device *parent;
|
||||||
|
const char *empty = "";
|
||||||
if (len <= 0 || !buffer)
|
|
||||||
return buffer;
|
|
||||||
buffer[0] = 0;
|
|
||||||
|
|
||||||
parent = dev->dev.parent;
|
parent = dev->dev.parent;
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return buffer;
|
return empty;
|
||||||
|
|
||||||
driver = parent->driver;
|
driver = parent->driver;
|
||||||
if (driver && driver->name)
|
if (driver && driver->name)
|
||||||
strlcpy(buffer, driver->name, len);
|
return driver->name;
|
||||||
return buffer;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __netdev_printk(const char *level, const struct net_device *dev,
|
static int __netdev_printk(const char *level, const struct net_device *dev,
|
||||||
|
|
|
@ -310,18 +310,16 @@ struct net *get_net_ns_by_fd(int fd)
|
||||||
struct file *file;
|
struct file *file;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
net = ERR_PTR(-EINVAL);
|
|
||||||
file = proc_ns_fget(fd);
|
file = proc_ns_fget(fd);
|
||||||
if (!file)
|
if (IS_ERR(file))
|
||||||
goto out;
|
return ERR_CAST(file);
|
||||||
|
|
||||||
ei = PROC_I(file->f_dentry->d_inode);
|
ei = PROC_I(file->f_dentry->d_inode);
|
||||||
if (ei->ns_ops != &netns_operations)
|
if (ei->ns_ops == &netns_operations)
|
||||||
goto out;
|
|
||||||
|
|
||||||
net = get_net(ei->ns);
|
net = get_net(ei->ns);
|
||||||
out:
|
else
|
||||||
if (file)
|
net = ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
fput(file);
|
fput(file);
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
|
|
|
@ -792,6 +792,13 @@ int netpoll_setup(struct netpoll *np)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ndev->master) {
|
||||||
|
printk(KERN_ERR "%s: %s is a slave device, aborting.\n",
|
||||||
|
np->name, np->dev_name);
|
||||||
|
err = -EBUSY;
|
||||||
|
goto put;
|
||||||
|
}
|
||||||
|
|
||||||
if (!netif_running(ndev)) {
|
if (!netif_running(ndev)) {
|
||||||
unsigned long atmost, atleast;
|
unsigned long atmost, atleast;
|
||||||
|
|
||||||
|
|
|
@ -799,7 +799,9 @@ static int __ip_append_data(struct sock *sk,
|
||||||
int csummode = CHECKSUM_NONE;
|
int csummode = CHECKSUM_NONE;
|
||||||
struct rtable *rt = (struct rtable *)cork->dst;
|
struct rtable *rt = (struct rtable *)cork->dst;
|
||||||
|
|
||||||
exthdrlen = transhdrlen ? rt->dst.header_len : 0;
|
skb = skb_peek_tail(queue);
|
||||||
|
|
||||||
|
exthdrlen = !skb ? rt->dst.header_len : 0;
|
||||||
length += exthdrlen;
|
length += exthdrlen;
|
||||||
transhdrlen += exthdrlen;
|
transhdrlen += exthdrlen;
|
||||||
mtu = cork->fragsize;
|
mtu = cork->fragsize;
|
||||||
|
@ -825,8 +827,6 @@ static int __ip_append_data(struct sock *sk,
|
||||||
!exthdrlen)
|
!exthdrlen)
|
||||||
csummode = CHECKSUM_PARTIAL;
|
csummode = CHECKSUM_PARTIAL;
|
||||||
|
|
||||||
skb = skb_peek_tail(queue);
|
|
||||||
|
|
||||||
cork->length += length;
|
cork->length += length;
|
||||||
if (((length > mtu) || (skb && skb_is_gso(skb))) &&
|
if (((length > mtu) || (skb && skb_is_gso(skb))) &&
|
||||||
(sk->sk_protocol == IPPROTO_UDP) &&
|
(sk->sk_protocol == IPPROTO_UDP) &&
|
||||||
|
|
|
@ -402,7 +402,8 @@ ipq_dev_drop(int ifindex)
|
||||||
static inline void
|
static inline void
|
||||||
__ipq_rcv_skb(struct sk_buff *skb)
|
__ipq_rcv_skb(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int status, type, pid, flags, nlmsglen, skblen;
|
int status, type, pid, flags;
|
||||||
|
unsigned int nlmsglen, skblen;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
|
|
||||||
skblen = skb->len;
|
skblen = skb->len;
|
||||||
|
|
|
@ -307,7 +307,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
* error messages (RELATED) and information requests (see below) */
|
* error messages (RELATED) and information requests (see below) */
|
||||||
if (ip_hdr(skb)->protocol == IPPROTO_ICMP &&
|
if (ip_hdr(skb)->protocol == IPPROTO_ICMP &&
|
||||||
(ctinfo == IP_CT_RELATED ||
|
(ctinfo == IP_CT_RELATED ||
|
||||||
ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY))
|
ctinfo == IP_CT_RELATED_REPLY))
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
|
|
||||||
/* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO,
|
/* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO,
|
||||||
|
@ -321,12 +321,12 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
ct->mark = hash;
|
ct->mark = hash;
|
||||||
break;
|
break;
|
||||||
case IP_CT_RELATED:
|
case IP_CT_RELATED:
|
||||||
case IP_CT_RELATED+IP_CT_IS_REPLY:
|
case IP_CT_RELATED_REPLY:
|
||||||
/* FIXME: we don't handle expectations at the
|
/* FIXME: we don't handle expectations at the
|
||||||
* moment. they can arrive on a different node than
|
* moment. they can arrive on a different node than
|
||||||
* the master connection (e.g. FTP passive mode) */
|
* the master connection (e.g. FTP passive mode) */
|
||||||
case IP_CT_ESTABLISHED:
|
case IP_CT_ESTABLISHED:
|
||||||
case IP_CT_ESTABLISHED+IP_CT_IS_REPLY:
|
case IP_CT_ESTABLISHED_REPLY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,7 +60,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
nat = nfct_nat(ct);
|
nat = nfct_nat(ct);
|
||||||
|
|
||||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
|
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
|
||||||
ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
|
ctinfo == IP_CT_RELATED_REPLY));
|
||||||
|
|
||||||
/* Source address is 0.0.0.0 - locally generated packet that is
|
/* Source address is 0.0.0.0 - locally generated packet that is
|
||||||
* probably not supposed to be masqueraded.
|
* probably not supposed to be masqueraded.
|
||||||
|
|
|
@ -101,7 +101,7 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
|
||||||
|
|
||||||
/* This is where we call the helper: as the packet goes out. */
|
/* This is where we call the helper: as the packet goes out. */
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
|
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
help = nfct_help(ct);
|
help = nfct_help(ct);
|
||||||
|
|
|
@ -160,7 +160,7 @@ icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
|
||||||
/* Update skb to refer to this connection */
|
/* Update skb to refer to this connection */
|
||||||
skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
|
skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
|
||||||
skb->nfctinfo = *ctinfo;
|
skb->nfctinfo = *ctinfo;
|
||||||
return -NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small and modified version of icmp_rcv */
|
/* Small and modified version of icmp_rcv */
|
||||||
|
|
|
@ -433,7 +433,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||||
|
|
||||||
/* Must be RELATED */
|
/* Must be RELATED */
|
||||||
NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
|
NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
|
||||||
skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
|
skb->nfctinfo == IP_CT_RELATED_REPLY);
|
||||||
|
|
||||||
/* Redirects on non-null nats must be dropped, else they'll
|
/* Redirects on non-null nats must be dropped, else they'll
|
||||||
start talking to each other without our translation, and be
|
start talking to each other without our translation, and be
|
||||||
|
|
|
@ -160,7 +160,7 @@ static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data
|
||||||
|
|
||||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||||
if (!(rt->rt_flags & RTCF_LOCAL) &&
|
if (!(rt->rt_flags & RTCF_LOCAL) &&
|
||||||
skb->dev->features & NETIF_F_V4_CSUM) {
|
(!skb->dev || skb->dev->features & NETIF_F_V4_CSUM)) {
|
||||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||||
skb->csum_start = skb_headroom(skb) +
|
skb->csum_start = skb_headroom(skb) +
|
||||||
skb_network_offset(skb) +
|
skb_network_offset(skb) +
|
||||||
|
|
|
@ -53,7 +53,7 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
|
|
||||||
/* Connection must be valid and new. */
|
/* Connection must be valid and new. */
|
||||||
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
|
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
|
||||||
ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
|
ctinfo == IP_CT_RELATED_REPLY));
|
||||||
NF_CT_ASSERT(par->out != NULL);
|
NF_CT_ASSERT(par->out != NULL);
|
||||||
|
|
||||||
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
|
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
|
||||||
|
|
|
@ -116,7 +116,7 @@ nf_nat_fn(unsigned int hooknum,
|
||||||
|
|
||||||
switch (ctinfo) {
|
switch (ctinfo) {
|
||||||
case IP_CT_RELATED:
|
case IP_CT_RELATED:
|
||||||
case IP_CT_RELATED+IP_CT_IS_REPLY:
|
case IP_CT_RELATED_REPLY:
|
||||||
if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
|
if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
|
||||||
if (!nf_nat_icmp_reply_translation(ct, ctinfo,
|
if (!nf_nat_icmp_reply_translation(ct, ctinfo,
|
||||||
hooknum, skb))
|
hooknum, skb))
|
||||||
|
@ -144,7 +144,7 @@ nf_nat_fn(unsigned int hooknum,
|
||||||
default:
|
default:
|
||||||
/* ESTABLISHED */
|
/* ESTABLISHED */
|
||||||
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
|
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
|
||||||
ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
|
ctinfo == IP_CT_ESTABLISHED_REPLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nf_nat_packet(ct, ctinfo, hooknum, skb);
|
return nf_nat_packet(ct, ctinfo, hooknum, skb);
|
||||||
|
|
|
@ -1316,6 +1316,23 @@ reject_redirect:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool peer_pmtu_expired(struct inet_peer *peer)
|
||||||
|
{
|
||||||
|
unsigned long orig = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
|
|
||||||
|
return orig &&
|
||||||
|
time_after_eq(jiffies, orig) &&
|
||||||
|
cmpxchg(&peer->pmtu_expires, orig, 0) == orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool peer_pmtu_cleaned(struct inet_peer *peer)
|
||||||
|
{
|
||||||
|
unsigned long orig = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
|
|
||||||
|
return orig &&
|
||||||
|
cmpxchg(&peer->pmtu_expires, orig, 0) == orig;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
struct rtable *rt = (struct rtable *)dst;
|
struct rtable *rt = (struct rtable *)dst;
|
||||||
|
@ -1331,14 +1348,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
||||||
rt_genid(dev_net(dst->dev)));
|
rt_genid(dev_net(dst->dev)));
|
||||||
rt_del(hash, rt);
|
rt_del(hash, rt);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
} else if (rt->peer &&
|
} else if (rt->peer && peer_pmtu_expired(rt->peer)) {
|
||||||
rt->peer->pmtu_expires &&
|
dst_metric_set(dst, RTAX_MTU, rt->peer->pmtu_orig);
|
||||||
time_after_eq(jiffies, rt->peer->pmtu_expires)) {
|
|
||||||
unsigned long orig = rt->peer->pmtu_expires;
|
|
||||||
|
|
||||||
if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig)
|
|
||||||
dst_metric_set(dst, RTAX_MTU,
|
|
||||||
rt->peer->pmtu_orig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1531,8 +1542,10 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
|
||||||
|
|
||||||
static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
|
static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
|
||||||
{
|
{
|
||||||
unsigned long expires = peer->pmtu_expires;
|
unsigned long expires = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
|
|
||||||
|
if (!expires)
|
||||||
|
return;
|
||||||
if (time_before(jiffies, expires)) {
|
if (time_before(jiffies, expires)) {
|
||||||
u32 orig_dst_mtu = dst_mtu(dst);
|
u32 orig_dst_mtu = dst_mtu(dst);
|
||||||
if (peer->pmtu_learned < orig_dst_mtu) {
|
if (peer->pmtu_learned < orig_dst_mtu) {
|
||||||
|
@ -1555,10 +1568,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
|
||||||
rt_bind_peer(rt, rt->rt_dst, 1);
|
rt_bind_peer(rt, rt->rt_dst, 1);
|
||||||
peer = rt->peer;
|
peer = rt->peer;
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
|
|
||||||
if (mtu < ip_rt_min_pmtu)
|
if (mtu < ip_rt_min_pmtu)
|
||||||
mtu = ip_rt_min_pmtu;
|
mtu = ip_rt_min_pmtu;
|
||||||
if (!peer->pmtu_expires || mtu < peer->pmtu_learned) {
|
if (!pmtu_expires || mtu < peer->pmtu_learned) {
|
||||||
unsigned long pmtu_expires;
|
|
||||||
|
|
||||||
pmtu_expires = jiffies + ip_rt_mtu_expires;
|
pmtu_expires = jiffies + ip_rt_mtu_expires;
|
||||||
if (!pmtu_expires)
|
if (!pmtu_expires)
|
||||||
|
@ -1612,14 +1626,15 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
|
||||||
rt_bind_peer(rt, rt->rt_dst, 0);
|
rt_bind_peer(rt, rt->rt_dst, 0);
|
||||||
|
|
||||||
peer = rt->peer;
|
peer = rt->peer;
|
||||||
if (peer && peer->pmtu_expires)
|
if (peer) {
|
||||||
check_peer_pmtu(dst, peer);
|
check_peer_pmtu(dst, peer);
|
||||||
|
|
||||||
if (peer && peer->redirect_learned.a4 &&
|
if (peer->redirect_learned.a4 &&
|
||||||
peer->redirect_learned.a4 != rt->rt_gateway) {
|
peer->redirect_learned.a4 != rt->rt_gateway) {
|
||||||
if (check_peer_redir(dst, peer))
|
if (check_peer_redir(dst, peer))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rt->rt_peer_genid = rt_peer_genid();
|
rt->rt_peer_genid = rt_peer_genid();
|
||||||
}
|
}
|
||||||
|
@ -1649,15 +1664,9 @@ static void ipv4_link_failure(struct sk_buff *skb)
|
||||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
||||||
|
|
||||||
rt = skb_rtable(skb);
|
rt = skb_rtable(skb);
|
||||||
if (rt &&
|
if (rt && rt->peer && peer_pmtu_cleaned(rt->peer))
|
||||||
rt->peer &&
|
|
||||||
rt->peer->pmtu_expires) {
|
|
||||||
unsigned long orig = rt->peer->pmtu_expires;
|
|
||||||
|
|
||||||
if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig)
|
|
||||||
dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig);
|
dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static int ip_rt_bug(struct sk_buff *skb)
|
static int ip_rt_bug(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -1770,7 +1779,6 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
|
||||||
sizeof(u32) * RTAX_MAX);
|
sizeof(u32) * RTAX_MAX);
|
||||||
dst_init_metrics(&rt->dst, peer->metrics, false);
|
dst_init_metrics(&rt->dst, peer->metrics, false);
|
||||||
|
|
||||||
if (peer->pmtu_expires)
|
|
||||||
check_peer_pmtu(&rt->dst, peer);
|
check_peer_pmtu(&rt->dst, peer);
|
||||||
if (peer->redirect_learned.a4 &&
|
if (peer->redirect_learned.a4 &&
|
||||||
peer->redirect_learned.a4 != rt->rt_gateway) {
|
peer->redirect_learned.a4 != rt->rt_gateway) {
|
||||||
|
@ -2775,7 +2783,8 @@ static int rt_fill_info(struct net *net,
|
||||||
struct rtable *rt = skb_rtable(skb);
|
struct rtable *rt = skb_rtable(skb);
|
||||||
struct rtmsg *r;
|
struct rtmsg *r;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
long expires;
|
long expires = 0;
|
||||||
|
const struct inet_peer *peer = rt->peer;
|
||||||
u32 id = 0, ts = 0, tsage = 0, error;
|
u32 id = 0, ts = 0, tsage = 0, error;
|
||||||
|
|
||||||
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
|
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
|
||||||
|
@ -2823,15 +2832,16 @@ static int rt_fill_info(struct net *net,
|
||||||
NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark);
|
NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark);
|
||||||
|
|
||||||
error = rt->dst.error;
|
error = rt->dst.error;
|
||||||
expires = (rt->peer && rt->peer->pmtu_expires) ?
|
if (peer) {
|
||||||
rt->peer->pmtu_expires - jiffies : 0;
|
|
||||||
if (rt->peer) {
|
|
||||||
inet_peer_refcheck(rt->peer);
|
inet_peer_refcheck(rt->peer);
|
||||||
id = atomic_read(&rt->peer->ip_id_count) & 0xffff;
|
id = atomic_read(&peer->ip_id_count) & 0xffff;
|
||||||
if (rt->peer->tcp_ts_stamp) {
|
if (peer->tcp_ts_stamp) {
|
||||||
ts = rt->peer->tcp_ts;
|
ts = peer->tcp_ts;
|
||||||
tsage = get_seconds() - rt->peer->tcp_ts_stamp;
|
tsage = get_seconds() - peer->tcp_ts_stamp;
|
||||||
}
|
}
|
||||||
|
expires = ACCESS_ONCE(peer->pmtu_expires);
|
||||||
|
if (expires)
|
||||||
|
expires -= jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt_is_input_route(rt)) {
|
if (rt_is_input_route(rt)) {
|
||||||
|
|
|
@ -272,6 +272,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||||
|
|
||||||
if (addr_len < SIN6_LEN_RFC2133)
|
if (addr_len < SIN6_LEN_RFC2133)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (addr->sin6_family != AF_INET6)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
addr_type = ipv6_addr_type(&addr->sin6_addr);
|
addr_type = ipv6_addr_type(&addr->sin6_addr);
|
||||||
if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
|
if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -403,7 +403,8 @@ ipq_dev_drop(int ifindex)
|
||||||
static inline void
|
static inline void
|
||||||
__ipq_rcv_skb(struct sk_buff *skb)
|
__ipq_rcv_skb(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int status, type, pid, flags, nlmsglen, skblen;
|
int status, type, pid, flags;
|
||||||
|
unsigned int nlmsglen, skblen;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
|
|
||||||
skblen = skb->len;
|
skblen = skb->len;
|
||||||
|
|
|
@ -160,7 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
|
||||||
|
|
||||||
/* This is where we call the helper: as the packet goes out. */
|
/* This is where we call the helper: as the packet goes out. */
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
|
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
help = nfct_help(ct);
|
help = nfct_help(ct);
|
||||||
|
|
|
@ -177,7 +177,7 @@ icmpv6_error_message(struct net *net, struct nf_conn *tmpl,
|
||||||
/* Update skb to refer to this connection */
|
/* Update skb to refer to this connection */
|
||||||
skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
|
skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
|
||||||
skb->nfctinfo = *ctinfo;
|
skb->nfctinfo = *ctinfo;
|
||||||
return -NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -87,6 +87,8 @@ static inline void iriap_start_watchdog_timer(struct iriap_cb *self,
|
||||||
iriap_watchdog_timer_expired);
|
iriap_watchdog_timer_expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct lock_class_key irias_objects_key;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function iriap_init (void)
|
* Function iriap_init (void)
|
||||||
*
|
*
|
||||||
|
@ -114,6 +116,9 @@ int __init iriap_init(void)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockdep_set_class_and_name(&irias_objects->hb_spinlock, &irias_objects_key,
|
||||||
|
"irias_objects");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register some default services for IrLMP
|
* Register some default services for IrLMP
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -258,7 +258,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file)
|
||||||
*/
|
*/
|
||||||
pd->net = get_net_ns_by_pid(current->pid);
|
pd->net = get_net_ns_by_pid(current->pid);
|
||||||
if (IS_ERR(pd->net)) {
|
if (IS_ERR(pd->net)) {
|
||||||
rc = -PTR_ERR(pd->net);
|
rc = PTR_ERR(pd->net);
|
||||||
goto err_free_pd;
|
goto err_free_pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -965,6 +965,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
||||||
|
|
||||||
mutex_lock(&sdata->u.ibss.mtx);
|
mutex_lock(&sdata->u.ibss.mtx);
|
||||||
|
|
||||||
|
sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
|
||||||
|
memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
|
||||||
|
sdata->u.ibss.ssid_len = 0;
|
||||||
|
|
||||||
active_ibss = ieee80211_sta_active_ibss(sdata);
|
active_ibss = ieee80211_sta_active_ibss(sdata);
|
||||||
|
|
||||||
if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
|
if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
|
||||||
|
@ -999,8 +1003,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
|
||||||
skb_queue_purge(&sdata->skb_queue);
|
skb_queue_purge(&sdata->skb_queue);
|
||||||
memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
|
|
||||||
sdata->u.ibss.ssid_len = 0;
|
|
||||||
|
|
||||||
del_timer_sync(&sdata->u.ibss.timer);
|
del_timer_sync(&sdata->u.ibss.timer);
|
||||||
|
|
||||||
|
|
|
@ -775,9 +775,6 @@ struct ieee80211_local {
|
||||||
|
|
||||||
int tx_headroom; /* required headroom for hardware/radiotap */
|
int tx_headroom; /* required headroom for hardware/radiotap */
|
||||||
|
|
||||||
/* count for keys needing tailroom space allocation */
|
|
||||||
int crypto_tx_tailroom_needed_cnt;
|
|
||||||
|
|
||||||
/* Tasklet and skb queue to process calls from IRQ mode. All frames
|
/* Tasklet and skb queue to process calls from IRQ mode. All frames
|
||||||
* added to skb_queue will be processed, but frames in
|
* added to skb_queue will be processed, but frames in
|
||||||
* skb_queue_unreliable may be dropped if the total length of these
|
* skb_queue_unreliable may be dropped if the total length of these
|
||||||
|
|
|
@ -1145,6 +1145,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
||||||
+ IEEE80211_ENCRYPT_HEADROOM;
|
+ IEEE80211_ENCRYPT_HEADROOM;
|
||||||
ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
||||||
|
|
||||||
|
ret = dev_alloc_name(ndev, ndev->name);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
ieee80211_assign_perm_addr(local, ndev, type);
|
ieee80211_assign_perm_addr(local, ndev, type);
|
||||||
memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
|
memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
|
||||||
SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
|
SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
|
||||||
|
|
|
@ -101,11 +101,6 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
|
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||||
|
|
||||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
|
||||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
|
|
||||||
key->local->crypto_tx_tailroom_needed_cnt--;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +156,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
|
||||||
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
|
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
|
||||||
|
|
||||||
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
|
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||||
|
|
||||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
|
||||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
|
|
||||||
key->local->crypto_tx_tailroom_needed_cnt++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
|
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
|
||||||
|
@ -403,10 +394,8 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
|
||||||
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
||||||
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
||||||
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
||||||
if (key->local) {
|
if (key->local)
|
||||||
ieee80211_debugfs_key_remove(key);
|
ieee80211_debugfs_key_remove(key);
|
||||||
key->local->crypto_tx_tailroom_needed_cnt--;
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(key);
|
kfree(key);
|
||||||
}
|
}
|
||||||
|
@ -468,8 +457,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
||||||
|
|
||||||
ieee80211_debugfs_key_add(key);
|
ieee80211_debugfs_key_add(key);
|
||||||
|
|
||||||
key->local->crypto_tx_tailroom_needed_cnt++;
|
|
||||||
|
|
||||||
ret = ieee80211_key_enable_hw_accel(key);
|
ret = ieee80211_key_enable_hw_accel(key);
|
||||||
|
|
||||||
mutex_unlock(&sdata->local->key_mtx);
|
mutex_unlock(&sdata->local->key_mtx);
|
||||||
|
@ -511,12 +498,8 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
||||||
|
|
||||||
mutex_lock(&sdata->local->key_mtx);
|
mutex_lock(&sdata->local->key_mtx);
|
||||||
|
|
||||||
sdata->local->crypto_tx_tailroom_needed_cnt = 0;
|
list_for_each_entry(key, &sdata->key_list, list)
|
||||||
|
|
||||||
list_for_each_entry(key, &sdata->key_list, list) {
|
|
||||||
sdata->local->crypto_tx_tailroom_needed_cnt++;
|
|
||||||
ieee80211_key_enable_hw_accel(key);
|
ieee80211_key_enable_hw_accel(key);
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&sdata->local->key_mtx);
|
mutex_unlock(&sdata->local->key_mtx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,9 +232,6 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
||||||
WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
|
WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_stop_queues_by_reason(&sdata->local->hw,
|
|
||||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
|
||||||
|
|
||||||
/* channel_type change automatically detected */
|
/* channel_type change automatically detected */
|
||||||
ieee80211_hw_config(local, 0);
|
ieee80211_hw_config(local, 0);
|
||||||
|
|
||||||
|
@ -248,9 +245,6 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
|
||||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
|
||||||
|
|
||||||
ht_opmode = le16_to_cpu(hti->operation_mode);
|
ht_opmode = le16_to_cpu(hti->operation_mode);
|
||||||
|
|
||||||
/* if bss configuration changed store the new one */
|
/* if bss configuration changed store the new one */
|
||||||
|
|
|
@ -1480,7 +1480,12 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
|
||||||
{
|
{
|
||||||
int tail_need = 0;
|
int tail_need = 0;
|
||||||
|
|
||||||
if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) {
|
/*
|
||||||
|
* This could be optimised, devices that do full hardware
|
||||||
|
* crypto (including TKIP MMIC) need no tailroom... But we
|
||||||
|
* have no drivers for such devices currently.
|
||||||
|
*/
|
||||||
|
if (may_encrypt) {
|
||||||
tail_need = IEEE80211_ENCRYPT_TAILROOM;
|
tail_need = IEEE80211_ENCRYPT_TAILROOM;
|
||||||
tail_need -= skb_tailroom(skb);
|
tail_need -= skb_tailroom(skb);
|
||||||
tail_need = max_t(int, tail_need, 0);
|
tail_need = max_t(int, tail_need, 0);
|
||||||
|
|
|
@ -767,7 +767,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
|
||||||
if (!attr[IPSET_ATTR_SETNAME]) {
|
if (!attr[IPSET_ATTR_SETNAME]) {
|
||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] != NULL && ip_set_list[i]->ref) {
|
if (ip_set_list[i] != NULL && ip_set_list[i]->ref) {
|
||||||
ret = IPSET_ERR_BUSY;
|
ret = -IPSET_ERR_BUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,9 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_ipportnet4_elem data =
|
struct hash_ipportnet4_elem data = {
|
||||||
{ .cidr = h->nets[0].cidr || HOST_MASK };
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -394,8 +395,9 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_ipportnet6_elem data =
|
struct hash_ipportnet6_elem data = {
|
||||||
{ .cidr = h->nets[0].cidr || HOST_MASK };
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -131,7 +131,9 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_net4_elem data = { .cidr = h->nets[0].cidr || HOST_MASK };
|
struct hash_net4_elem data = {
|
||||||
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -296,7 +298,9 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_net6_elem data = { .cidr = h->nets[0].cidr || HOST_MASK };
|
struct hash_net6_elem data = {
|
||||||
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -144,7 +144,8 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_netport4_elem data = {
|
struct hash_netport4_elem data = {
|
||||||
.cidr = h->nets[0].cidr || HOST_MASK };
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -357,7 +358,8 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||||
const struct ip_set_hash *h = set->data;
|
const struct ip_set_hash *h = set->data;
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_netport6_elem data = {
|
struct hash_netport6_elem data = {
|
||||||
.cidr = h->nets[0].cidr || HOST_MASK };
|
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
|
||||||
|
};
|
||||||
|
|
||||||
if (data.cidr == 0)
|
if (data.cidr == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -1772,7 +1772,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET,
|
.pf = PF_INET,
|
||||||
.hooknum = NF_INET_LOCAL_IN,
|
.hooknum = NF_INET_LOCAL_IN,
|
||||||
.priority = 99,
|
.priority = NF_IP_PRI_NAT_SRC - 2,
|
||||||
},
|
},
|
||||||
/* After packet filtering, forward packet through VS/DR, VS/TUN,
|
/* After packet filtering, forward packet through VS/DR, VS/TUN,
|
||||||
* or VS/NAT(change destination), so that filtering rules can be
|
* or VS/NAT(change destination), so that filtering rules can be
|
||||||
|
@ -1782,7 +1782,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET,
|
.pf = PF_INET,
|
||||||
.hooknum = NF_INET_LOCAL_IN,
|
.hooknum = NF_INET_LOCAL_IN,
|
||||||
.priority = 101,
|
.priority = NF_IP_PRI_NAT_SRC - 1,
|
||||||
},
|
},
|
||||||
/* Before ip_vs_in, change source only for VS/NAT */
|
/* Before ip_vs_in, change source only for VS/NAT */
|
||||||
{
|
{
|
||||||
|
@ -1790,7 +1790,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET,
|
.pf = PF_INET,
|
||||||
.hooknum = NF_INET_LOCAL_OUT,
|
.hooknum = NF_INET_LOCAL_OUT,
|
||||||
.priority = -99,
|
.priority = NF_IP_PRI_NAT_DST + 1,
|
||||||
},
|
},
|
||||||
/* After mangle, schedule and forward local requests */
|
/* After mangle, schedule and forward local requests */
|
||||||
{
|
{
|
||||||
|
@ -1798,7 +1798,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET,
|
.pf = PF_INET,
|
||||||
.hooknum = NF_INET_LOCAL_OUT,
|
.hooknum = NF_INET_LOCAL_OUT,
|
||||||
.priority = -98,
|
.priority = NF_IP_PRI_NAT_DST + 2,
|
||||||
},
|
},
|
||||||
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
|
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
|
||||||
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
|
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
|
||||||
|
@ -1824,7 +1824,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET6,
|
.pf = PF_INET6,
|
||||||
.hooknum = NF_INET_LOCAL_IN,
|
.hooknum = NF_INET_LOCAL_IN,
|
||||||
.priority = 99,
|
.priority = NF_IP6_PRI_NAT_SRC - 2,
|
||||||
},
|
},
|
||||||
/* After packet filtering, forward packet through VS/DR, VS/TUN,
|
/* After packet filtering, forward packet through VS/DR, VS/TUN,
|
||||||
* or VS/NAT(change destination), so that filtering rules can be
|
* or VS/NAT(change destination), so that filtering rules can be
|
||||||
|
@ -1834,7 +1834,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET6,
|
.pf = PF_INET6,
|
||||||
.hooknum = NF_INET_LOCAL_IN,
|
.hooknum = NF_INET_LOCAL_IN,
|
||||||
.priority = 101,
|
.priority = NF_IP6_PRI_NAT_SRC - 1,
|
||||||
},
|
},
|
||||||
/* Before ip_vs_in, change source only for VS/NAT */
|
/* Before ip_vs_in, change source only for VS/NAT */
|
||||||
{
|
{
|
||||||
|
@ -1842,7 +1842,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET,
|
.pf = PF_INET,
|
||||||
.hooknum = NF_INET_LOCAL_OUT,
|
.hooknum = NF_INET_LOCAL_OUT,
|
||||||
.priority = -99,
|
.priority = NF_IP6_PRI_NAT_DST + 1,
|
||||||
},
|
},
|
||||||
/* After mangle, schedule and forward local requests */
|
/* After mangle, schedule and forward local requests */
|
||||||
{
|
{
|
||||||
|
@ -1850,7 +1850,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pf = PF_INET6,
|
.pf = PF_INET6,
|
||||||
.hooknum = NF_INET_LOCAL_OUT,
|
.hooknum = NF_INET_LOCAL_OUT,
|
||||||
.priority = -98,
|
.priority = NF_IP6_PRI_NAT_DST + 2,
|
||||||
},
|
},
|
||||||
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
|
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
|
||||||
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
|
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
|
||||||
|
|
|
@ -850,7 +850,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
|
||||||
|
|
||||||
/* It exists; we have (non-exclusive) reference. */
|
/* It exists; we have (non-exclusive) reference. */
|
||||||
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
|
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
|
||||||
*ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
|
*ctinfo = IP_CT_ESTABLISHED_REPLY;
|
||||||
/* Please set reply bit if this packet OK */
|
/* Please set reply bit if this packet OK */
|
||||||
*set_reply = 1;
|
*set_reply = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -922,6 +922,9 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
|
||||||
ret = -ret;
|
ret = -ret;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/* ICMP[v6] protocol trackers may assign one conntrack. */
|
||||||
|
if (skb->nfct)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
|
ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
|
||||||
|
@ -1143,7 +1146,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
|
||||||
/* This ICMP is in reverse direction to the packet which caused it */
|
/* This ICMP is in reverse direction to the packet which caused it */
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
|
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
|
||||||
ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
|
ctinfo = IP_CT_RELATED_REPLY;
|
||||||
else
|
else
|
||||||
ctinfo = IP_CT_RELATED;
|
ctinfo = IP_CT_RELATED;
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,7 @@ static int help(struct sk_buff *skb,
|
||||||
|
|
||||||
/* Until there's been traffic both ways, don't look in packets. */
|
/* Until there's been traffic both ways, don't look in packets. */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED &&
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
ctinfo != IP_CT_ESTABLISHED_REPLY) {
|
||||||
pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
|
pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,10 +571,9 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Until there's been traffic both ways, don't look in packets. */
|
/* Until there's been traffic both ways, don't look in packets. */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
|
||||||
pr_debug("nf_ct_h245: skblen = %u\n", skb->len);
|
pr_debug("nf_ct_h245: skblen = %u\n", skb->len);
|
||||||
|
|
||||||
spin_lock_bh(&nf_h323_lock);
|
spin_lock_bh(&nf_h323_lock);
|
||||||
|
@ -1125,10 +1124,9 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Until there's been traffic both ways, don't look in packets. */
|
/* Until there's been traffic both ways, don't look in packets. */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
|
||||||
pr_debug("nf_ct_q931: skblen = %u\n", skb->len);
|
pr_debug("nf_ct_q931: skblen = %u\n", skb->len);
|
||||||
|
|
||||||
spin_lock_bh(&nf_h323_lock);
|
spin_lock_bh(&nf_h323_lock);
|
||||||
|
|
|
@ -125,8 +125,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
/* Until there's been traffic both ways, don't look in packets. */
|
/* Until there's been traffic both ways, don't look in packets. */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
/* Not a full tcp header? */
|
/* Not a full tcp header? */
|
||||||
|
|
|
@ -519,8 +519,7 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
|
||||||
u_int16_t msg;
|
u_int16_t msg;
|
||||||
|
|
||||||
/* don't do any tracking before tcp handshake complete */
|
/* don't do any tracking before tcp handshake complete */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
nexthdr_off = protoff;
|
nexthdr_off = protoff;
|
||||||
|
|
|
@ -78,7 +78,7 @@ static int help(struct sk_buff *skb,
|
||||||
ct_sane_info = &nfct_help(ct)->help.ct_sane_info;
|
ct_sane_info = &nfct_help(ct)->help.ct_sane_info;
|
||||||
/* Until there's been traffic both ways, don't look in packets. */
|
/* Until there's been traffic both ways, don't look in packets. */
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED &&
|
||||||
ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY)
|
ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
/* Not a full tcp header? */
|
/* Not a full tcp header? */
|
||||||
|
|
|
@ -1423,7 +1423,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
|
||||||
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
|
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
|
||||||
|
|
||||||
if (ctinfo != IP_CT_ESTABLISHED &&
|
if (ctinfo != IP_CT_ESTABLISHED &&
|
||||||
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
|
ctinfo != IP_CT_ESTABLISHED_REPLY)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
/* No Data ? */
|
/* No Data ? */
|
||||||
|
|
|
@ -143,9 +143,9 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
if (ct && !nf_ct_is_untracked(ct) &&
|
if (ct && !nf_ct_is_untracked(ct) &&
|
||||||
((iph->protocol != IPPROTO_ICMP &&
|
((iph->protocol != IPPROTO_ICMP &&
|
||||||
ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) ||
|
ctinfo == IP_CT_ESTABLISHED_REPLY) ||
|
||||||
(iph->protocol == IPPROTO_ICMP &&
|
(iph->protocol == IPPROTO_ICMP &&
|
||||||
ctinfo == IP_CT_IS_REPLY + IP_CT_RELATED)) &&
|
ctinfo == IP_CT_RELATED_REPLY)) &&
|
||||||
(ct->status & IPS_SRC_NAT_DONE)) {
|
(ct->status & IPS_SRC_NAT_DONE)) {
|
||||||
|
|
||||||
daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
|
daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
|
||||||
|
|
|
@ -804,6 +804,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
} else {
|
} else {
|
||||||
h.h2->tp_vlan_tci = 0;
|
h.h2->tp_vlan_tci = 0;
|
||||||
}
|
}
|
||||||
|
h.h2->tp_padding = 0;
|
||||||
hdrlen = sizeof(*h.h2);
|
hdrlen = sizeof(*h.h2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1736,6 +1737,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
} else {
|
} else {
|
||||||
aux.tp_vlan_tci = 0;
|
aux.tp_vlan_tci = 0;
|
||||||
}
|
}
|
||||||
|
aux.tp_padding = 0;
|
||||||
put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
|
put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,9 +251,8 @@ static void dev_watchdog(unsigned long arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (some_queue_timedout) {
|
if (some_queue_timedout) {
|
||||||
char drivername[64];
|
|
||||||
WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n",
|
WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n",
|
||||||
dev->name, netdev_drivername(dev, drivername, 64), i);
|
dev->name, netdev_drivername(dev), i);
|
||||||
dev->netdev_ops->ndo_tx_timeout(dev);
|
dev->netdev_ops->ndo_tx_timeout(dev);
|
||||||
}
|
}
|
||||||
if (!mod_timer(&dev->watchdog_timer,
|
if (!mod_timer(&dev->watchdog_timer,
|
||||||
|
|
|
@ -3406,11 +3406,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||||
i = 0;
|
i = 0;
|
||||||
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
||||||
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
|
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
|
||||||
request->ssids[i].ssid_len = nla_len(attr);
|
if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
|
||||||
if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
request->ssids[i].ssid_len = nla_len(attr);
|
||||||
memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
|
memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -3572,12 +3572,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||||
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
||||||
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
|
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
|
||||||
tmp) {
|
tmp) {
|
||||||
request->ssids[i].ssid_len = nla_len(attr);
|
if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
|
||||||
if (request->ssids[i].ssid_len >
|
|
||||||
IEEE80211_MAX_SSID_LEN) {
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
request->ssids[i].ssid_len = nla_len(attr);
|
||||||
memcpy(request->ssids[i].ssid, nla_data(attr),
|
memcpy(request->ssids[i].ssid, nla_data(attr),
|
||||||
nla_len(attr));
|
nla_len(attr));
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -265,7 +265,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
|
||||||
bitnr = bitnr & 0x1F;
|
bitnr = bitnr & 0x1F;
|
||||||
replay_esn->bmp[nr] |= (1U << bitnr);
|
replay_esn->bmp[nr] |= (1U << bitnr);
|
||||||
} else {
|
} else {
|
||||||
nr = replay_esn->replay_window >> 5;
|
nr = (replay_esn->replay_window - 1) >> 5;
|
||||||
for (i = 0; i <= nr; i++)
|
for (i = 0; i <= nr; i++)
|
||||||
replay_esn->bmp[i] = 0;
|
replay_esn->bmp[i] = 0;
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
|
||||||
bitnr = bitnr & 0x1F;
|
bitnr = bitnr & 0x1F;
|
||||||
replay_esn->bmp[nr] |= (1U << bitnr);
|
replay_esn->bmp[nr] |= (1U << bitnr);
|
||||||
} else {
|
} else {
|
||||||
nr = replay_esn->replay_window >> 5;
|
nr = (replay_esn->replay_window - 1) >> 5;
|
||||||
for (i = 0; i <= nr; i++)
|
for (i = 0; i <= nr; i++)
|
||||||
replay_esn->bmp[i] = 0;
|
replay_esn->bmp[i] = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue