Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

This commit is contained in:
David S. Miller 2009-10-11 23:15:47 -07:00
commit 7fe13c5733
37 changed files with 464 additions and 260 deletions

View File

@ -3643,6 +3643,13 @@ F: Documentation/blockdev/nbd.txt
F: drivers/block/nbd.c F: drivers/block/nbd.c
F: include/linux/nbd.h F: include/linux/nbd.h
NETWORK DROP MONITOR
M: Neil Horman <nhorman@tuxdriver.com>
L: netdev@vger.kernel.org
S: Maintained
W: https://fedorahosted.org/dropwatch/
F: net/core/drop_monitor.c
NETWORKING [GENERAL] NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net> M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org

View File

@ -2,6 +2,10 @@
# Makefile for the Linux network (ethercard) device drivers. # Makefile for the Linux network (ethercard) device drivers.
# #
obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_E1000) += e1000/
@ -100,10 +104,6 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o
# end link order section # end link order section
# #
obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_SUNDANCE) += sundance.o obj-$(CONFIG_SUNDANCE) += sundance.o
obj-$(CONFIG_HAMACHI) += hamachi.o obj-$(CONFIG_HAMACHI) += hamachi.o
obj-$(CONFIG_NET) += Space.o loopback.o obj-$(CONFIG_NET) += Space.o loopback.o

View File

@ -721,7 +721,7 @@ static inline void update_rx_stats(struct net_device *dev, u32 status)
ps->rx_errors++; ps->rx_errors++;
if (status & RX_MISSED_FRAME) if (status & RX_MISSED_FRAME)
ps->rx_missed_errors++; ps->rx_missed_errors++;
if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR)) if (status & (RX_OVERLEN | RX_RUNT | RX_LEN_ERROR))
ps->rx_length_errors++; ps->rx_length_errors++;
if (status & RX_CRC_ERROR) if (status & RX_CRC_ERROR)
ps->rx_crc_errors++; ps->rx_crc_errors++;
@ -794,8 +794,6 @@ static int au1000_rx(struct net_device *dev)
printk("rx len error\n"); printk("rx len error\n");
if (status & RX_U_CNTRL_FRAME) if (status & RX_U_CNTRL_FRAME)
printk("rx u control frame\n"); printk("rx u control frame\n");
if (status & RX_MISSED_FRAME)
printk("rx miss\n");
} }
} }
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);

View File

@ -19,6 +19,10 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <net/ethoc.h> #include <net/ethoc.h>
static int buffer_size = 0x8000; /* 32 KBytes */
module_param(buffer_size, int, 0);
MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
/* register offsets */ /* register offsets */
#define MODER 0x00 #define MODER 0x00
#define INT_SOURCE 0x04 #define INT_SOURCE 0x04
@ -167,6 +171,7 @@
* struct ethoc - driver-private device structure * struct ethoc - driver-private device structure
* @iobase: pointer to I/O memory region * @iobase: pointer to I/O memory region
* @membase: pointer to buffer memory region * @membase: pointer to buffer memory region
* @dma_alloc: dma allocated buffer size
* @num_tx: number of send buffers * @num_tx: number of send buffers
* @cur_tx: last send buffer written * @cur_tx: last send buffer written
* @dty_tx: last buffer actually sent * @dty_tx: last buffer actually sent
@ -185,6 +190,7 @@
struct ethoc { struct ethoc {
void __iomem *iobase; void __iomem *iobase;
void __iomem *membase; void __iomem *membase;
int dma_alloc;
unsigned int num_tx; unsigned int num_tx;
unsigned int cur_tx; unsigned int cur_tx;
@ -284,7 +290,7 @@ static int ethoc_init_ring(struct ethoc *dev)
dev->cur_rx = 0; dev->cur_rx = 0;
/* setup transmission buffers */ /* setup transmission buffers */
bd.addr = 0; bd.addr = virt_to_phys(dev->membase);
bd.stat = TX_BD_IRQ | TX_BD_CRC; bd.stat = TX_BD_IRQ | TX_BD_CRC;
for (i = 0; i < dev->num_tx; i++) { for (i = 0; i < dev->num_tx; i++) {
@ -295,7 +301,6 @@ static int ethoc_init_ring(struct ethoc *dev)
bd.addr += ETHOC_BUFSIZ; bd.addr += ETHOC_BUFSIZ;
} }
bd.addr = dev->num_tx * ETHOC_BUFSIZ;
bd.stat = RX_BD_EMPTY | RX_BD_IRQ; bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < dev->num_rx; i++) { for (i = 0; i < dev->num_rx; i++) {
@ -400,8 +405,12 @@ static int ethoc_rx(struct net_device *dev, int limit)
if (ethoc_update_rx_stats(priv, &bd) == 0) { if (ethoc_update_rx_stats(priv, &bd) == 0) {
int size = bd.stat >> 16; int size = bd.stat >> 16;
struct sk_buff *skb = netdev_alloc_skb(dev, size); struct sk_buff *skb = netdev_alloc_skb(dev, size);
size -= 4; /* strip the CRC */
skb_reserve(skb, 2); /* align TCP/IP header */
if (likely(skb)) { if (likely(skb)) {
void *src = priv->membase + bd.addr; void *src = phys_to_virt(bd.addr);
memcpy_fromio(skb_put(skb, size), src, size); memcpy_fromio(skb_put(skb, size), src, size);
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
priv->stats.rx_packets++; priv->stats.rx_packets++;
@ -653,9 +662,9 @@ static int ethoc_open(struct net_device *dev)
if (ret) if (ret)
return ret; return ret;
/* calculate the number of TX/RX buffers */ /* calculate the number of TX/RX buffers, maximum 128 supported */
num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ; num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
priv->num_tx = min(min_tx, num_bd / 4); priv->num_tx = max(min_tx, num_bd / 4);
priv->num_rx = num_bd - priv->num_tx; priv->num_rx = num_bd - priv->num_tx;
ethoc_write(priv, TX_BD_NUM, priv->num_tx); ethoc_write(priv, TX_BD_NUM, priv->num_tx);
@ -823,7 +832,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
else else
bd.stat &= ~TX_BD_PAD; bd.stat &= ~TX_BD_PAD;
dest = priv->membase + bd.addr; dest = phys_to_virt(bd.addr);
memcpy_toio(dest, skb->data, skb->len); memcpy_toio(dest, skb->data, skb->len);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
@ -903,22 +912,19 @@ static int ethoc_probe(struct platform_device *pdev)
/* obtain buffer memory space */ /* obtain buffer memory space */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res) { if (res) {
dev_err(&pdev->dev, "cannot obtain memory space\n"); mem = devm_request_mem_region(&pdev->dev, res->start,
ret = -ENXIO;
goto free;
}
mem = devm_request_mem_region(&pdev->dev, res->start,
res->end - res->start + 1, res->name); res->end - res->start + 1, res->name);
if (!mem) { if (!mem) {
dev_err(&pdev->dev, "cannot request memory space\n"); dev_err(&pdev->dev, "cannot request memory space\n");
ret = -ENXIO; ret = -ENXIO;
goto free; goto free;
}
netdev->mem_start = mem->start;
netdev->mem_end = mem->end;
} }
netdev->mem_start = mem->start;
netdev->mem_end = mem->end;
/* obtain device IRQ number */ /* obtain device IRQ number */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -933,6 +939,7 @@ static int ethoc_probe(struct platform_device *pdev)
/* setup driver-private data */ /* setup driver-private data */
priv = netdev_priv(netdev); priv = netdev_priv(netdev);
priv->netdev = netdev; priv->netdev = netdev;
priv->dma_alloc = 0;
priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
mmio->end - mmio->start + 1); mmio->end - mmio->start + 1);
@ -942,12 +949,27 @@ static int ethoc_probe(struct platform_device *pdev)
goto error; goto error;
} }
priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start, if (netdev->mem_end) {
mem->end - mem->start + 1); priv->membase = devm_ioremap_nocache(&pdev->dev,
if (!priv->membase) { netdev->mem_start, mem->end - mem->start + 1);
dev_err(&pdev->dev, "cannot remap memory space\n"); if (!priv->membase) {
ret = -ENXIO; dev_err(&pdev->dev, "cannot remap memory space\n");
goto error; ret = -ENXIO;
goto error;
}
} else {
/* Allocate buffer memory */
priv->membase = dma_alloc_coherent(NULL,
buffer_size, (void *)&netdev->mem_start,
GFP_KERNEL);
if (!priv->membase) {
dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
buffer_size);
ret = -ENOMEM;
goto error;
}
netdev->mem_end = netdev->mem_start + buffer_size;
priv->dma_alloc = buffer_size;
} }
/* Allow the platform setup code to pass in a MAC address. */ /* Allow the platform setup code to pass in a MAC address. */
@ -1034,6 +1056,9 @@ free_mdio:
kfree(priv->mdio->irq); kfree(priv->mdio->irq);
mdiobus_free(priv->mdio); mdiobus_free(priv->mdio);
free: free:
if (priv->dma_alloc)
dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
netdev->mem_start);
free_netdev(netdev); free_netdev(netdev);
out: out:
return ret; return ret;
@ -1059,7 +1084,9 @@ static int ethoc_remove(struct platform_device *pdev)
kfree(priv->mdio->irq); kfree(priv->mdio->irq);
mdiobus_free(priv->mdio); mdiobus_free(priv->mdio);
} }
if (priv->dma_alloc)
dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
netdev->mem_start);
unregister_netdev(netdev); unregister_netdev(netdev);
free_netdev(netdev); free_netdev(netdev);
} }

View File

@ -443,7 +443,7 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
ret |= EMAC_MR1_TFS_2K; ret |= EMAC_MR1_TFS_2K;
break; break;
default: default:
printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n", printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
dev->ndev->name, tx_size); dev->ndev->name, tx_size);
} }
@ -470,6 +470,9 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
DBG2(dev, "__emac4_calc_base_mr1" NL); DBG2(dev, "__emac4_calc_base_mr1" NL);
switch(tx_size) { switch(tx_size) {
case 16384:
ret |= EMAC4_MR1_TFS_16K;
break;
case 4096: case 4096:
ret |= EMAC4_MR1_TFS_4K; ret |= EMAC4_MR1_TFS_4K;
break; break;
@ -477,7 +480,7 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
ret |= EMAC4_MR1_TFS_2K; ret |= EMAC4_MR1_TFS_2K;
break; break;
default: default:
printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n", printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
dev->ndev->name, tx_size); dev->ndev->name, tx_size);
} }

View File

@ -153,6 +153,7 @@ struct emac_regs {
#define EMAC4_MR1_RFS_16K 0x00280000 #define EMAC4_MR1_RFS_16K 0x00280000
#define EMAC4_MR1_TFS_2K 0x00020000 #define EMAC4_MR1_TFS_2K 0x00020000
#define EMAC4_MR1_TFS_4K 0x00030000 #define EMAC4_MR1_TFS_4K 0x00030000
#define EMAC4_MR1_TFS_16K 0x00050000
#define EMAC4_MR1_TR 0x00008000 #define EMAC4_MR1_TR 0x00008000
#define EMAC4_MR1_MWSW_001 0x00001000 #define EMAC4_MR1_MWSW_001 0x00001000
#define EMAC4_MR1_JPSM 0x00000800 #define EMAC4_MR1_JPSM 0x00000800

View File

@ -1714,7 +1714,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* 4 fragments per cmd des */ /* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2; no_of_desc = (frag_count + 3) >> 2;
if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) { if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }

View File

@ -71,6 +71,9 @@ pasemi_mac_ethtool_get_settings(struct net_device *netdev,
struct pasemi_mac *mac = netdev_priv(netdev); struct pasemi_mac *mac = netdev_priv(netdev);
struct phy_device *phydev = mac->phydev; struct phy_device *phydev = mac->phydev;
if (!phydev)
return -EOPNOTSUPP;
return phy_ethtool_gset(phydev, cmd); return phy_ethtool_gset(phydev, cmd);
} }

View File

@ -803,6 +803,12 @@ enum {
MB_CMD_SET_PORT_CFG = 0x00000122, MB_CMD_SET_PORT_CFG = 0x00000122,
MB_CMD_GET_PORT_CFG = 0x00000123, MB_CMD_GET_PORT_CFG = 0x00000123,
MB_CMD_GET_LINK_STS = 0x00000124, MB_CMD_GET_LINK_STS = 0x00000124,
MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
MB_SET_MPI_TFK_STOP = (1 << 0),
MB_SET_MPI_TFK_RESUME = (1 << 1),
MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
MB_GET_MPI_TFK_STOPPED = (1 << 0),
MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
/* Mailbox Command Status. */ /* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */ MB_CMD_STS_GOOD = 0x00004000, /* Success. */
@ -1168,7 +1174,7 @@ struct ricb {
#define RSS_RI6 0x40 #define RSS_RI6 0x40
#define RSS_RT6 0x80 #define RSS_RT6 0x80
__le16 mask; __le16 mask;
__le32 hash_cq_id[256]; u8 hash_cq_id[1024];
__le32 ipv6_hash_key[10]; __le32 ipv6_hash_key[10];
__le32 ipv4_hash_key[4]; __le32 ipv4_hash_key[4];
} __attribute((packed)); } __attribute((packed));
@ -1605,6 +1611,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
int ql_mb_about_fw(struct ql_adapter *qdev); int ql_mb_about_fw(struct ql_adapter *qdev);
void ql_link_on(struct ql_adapter *qdev); void ql_link_on(struct ql_adapter *qdev);
void ql_link_off(struct ql_adapter *qdev); void ql_link_off(struct ql_adapter *qdev);
int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
int ql_wait_fifo_empty(struct ql_adapter *qdev);
#if 1 #if 1
#define QL_ALL_DUMP #define QL_ALL_DUMP

View File

@ -320,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
switch (type) { switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC: case MAC_ADDR_TYPE_MULTI_MAC:
{
u32 upper = (addr[0] << 8) | addr[1];
u32 lower = (addr[2] << 24) | (addr[3] << 16) |
(addr[4] << 8) | (addr[5]);
status =
ql_wait_reg_rdy(qdev,
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
(index << MAC_ADDR_IDX_SHIFT) |
type | MAC_ADDR_E);
ql_write32(qdev, MAC_ADDR_DATA, lower);
status =
ql_wait_reg_rdy(qdev,
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
(index << MAC_ADDR_IDX_SHIFT) |
type | MAC_ADDR_E);
ql_write32(qdev, MAC_ADDR_DATA, upper);
status =
ql_wait_reg_rdy(qdev,
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
break;
}
case MAC_ADDR_TYPE_CAM_MAC: case MAC_ADDR_TYPE_CAM_MAC:
{ {
u32 cam_output; u32 cam_output;
@ -365,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
and possibly the function id. Right now we hardcode and possibly the function id. Right now we hardcode
the route field to NIC core. the route field to NIC core.
*/ */
if (type == MAC_ADDR_TYPE_CAM_MAC) { cam_output = (CAM_OUT_ROUTE_NIC |
cam_output = (CAM_OUT_ROUTE_NIC | (qdev->
(qdev-> func << CAM_OUT_FUNC_SHIFT) |
func << CAM_OUT_FUNC_SHIFT) | (0 << CAM_OUT_CQ_ID_SHIFT));
(0 << CAM_OUT_CQ_ID_SHIFT)); if (qdev->vlgrp)
if (qdev->vlgrp) cam_output |= CAM_OUT_RV;
cam_output |= CAM_OUT_RV; /* route to NIC core */
/* route to NIC core */ ql_write32(qdev, MAC_ADDR_DATA, cam_output);
ql_write32(qdev, MAC_ADDR_DATA, cam_output);
}
break; break;
} }
case MAC_ADDR_TYPE_VLAN: case MAC_ADDR_TYPE_VLAN:
@ -546,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
} }
case RT_IDX_MCAST: /* Pass up All Multicast frames. */ case RT_IDX_MCAST: /* Pass up All Multicast frames. */
{ {
value = RT_IDX_DST_CAM_Q | /* dest */ value = RT_IDX_DST_DFLT_Q | /* dest */
RT_IDX_TYPE_NICQ | /* type */ RT_IDX_TYPE_NICQ | /* type */
(RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */ (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */
break; break;
} }
case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */ case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */
{ {
value = RT_IDX_DST_CAM_Q | /* dest */ value = RT_IDX_DST_DFLT_Q | /* dest */
RT_IDX_TYPE_NICQ | /* type */ RT_IDX_TYPE_NICQ | /* type */
(RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */
break; break;
@ -3078,6 +3107,12 @@ err_irq:
static int ql_start_rss(struct ql_adapter *qdev) static int ql_start_rss(struct ql_adapter *qdev)
{ {
u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
0xbe, 0xac, 0x01, 0xfa};
struct ricb *ricb = &qdev->ricb; struct ricb *ricb = &qdev->ricb;
int status = 0; int status = 0;
int i; int i;
@ -3087,21 +3122,17 @@ static int ql_start_rss(struct ql_adapter *qdev)
ricb->base_cq = RSS_L4K; ricb->base_cq = RSS_L4K;
ricb->flags = ricb->flags =
(RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 | (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6);
RSS_RT6); ricb->mask = cpu_to_le16((u16)(0x3ff));
ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1);
/* /*
* Fill out the Indirection Table. * Fill out the Indirection Table.
*/ */
for (i = 0; i < 256; i++) for (i = 0; i < 1024; i++)
hash_id[i] = i & (qdev->rss_ring_count - 1); hash_id[i] = (i & (qdev->rss_ring_count - 1));
/* memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
* Random values for the IPv6 and IPv4 Hash Keys. memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
*/
get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
@ -3240,6 +3271,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
/* Set RX packet routing to use port/pci function on which the
* packet arrived on in addition to usual frame routing.
* This is helpful on bonding where both interfaces can have
* the same MAC address.
*/
ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
/* Start up the rx queues. */ /* Start up the rx queues. */
for (i = 0; i < qdev->rx_ring_count; i++) { for (i = 0; i < qdev->rx_ring_count; i++) {
status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
@ -3312,6 +3350,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
end_jiffies = jiffies + end_jiffies = jiffies +
max((unsigned long)1, usecs_to_jiffies(30)); max((unsigned long)1, usecs_to_jiffies(30));
/* Stop management traffic. */
ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
/* Wait for the NIC and MGMNT FIFOs to empty. */
ql_wait_fifo_empty(qdev);
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
do { do {
@ -3327,6 +3372,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
status = -ETIMEDOUT; status = -ETIMEDOUT;
} }
/* Resume management traffic. */
ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME);
return status; return status;
} }
@ -3704,6 +3751,12 @@ static void ql_asic_reset_work(struct work_struct *work)
status = ql_adapter_up(qdev); status = ql_adapter_up(qdev);
if (status) if (status)
goto error; goto error;
/* Restore rx mode. */
clear_bit(QL_ALLMULTI, &qdev->flags);
clear_bit(QL_PROMISCUOUS, &qdev->flags);
qlge_set_multicast_list(qdev->ndev);
rtnl_unlock(); rtnl_unlock();
return; return;
error: error:

View File

@ -768,6 +768,95 @@ static int ql_idc_wait(struct ql_adapter *qdev)
return status; return status;
} }
int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
{
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
int status;
memset(mbcp, 0, sizeof(struct mbox_params));
mbcp->in_count = 1;
mbcp->out_count = 2;
mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL;
mbcp->mbox_in[1] = control;
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD)
return status;
if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
QPRINTK(qdev, DRV, ERR,
"Command not supported by firmware.\n");
status = -EINVAL;
} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
/* This indicates that the firmware is
* already in the state we are trying to
* change it to.
*/
QPRINTK(qdev, DRV, ERR,
"Command parameters make no change.\n");
}
return status;
}
/* Returns a negative error code or the mailbox command status. */
static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control)
{
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
int status;
memset(mbcp, 0, sizeof(struct mbox_params));
*control = 0;
mbcp->in_count = 1;
mbcp->out_count = 1;
mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL;
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) {
*control = mbcp->mbox_in[1];
return status;
}
if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
QPRINTK(qdev, DRV, ERR,
"Command not supported by firmware.\n");
status = -EINVAL;
} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
QPRINTK(qdev, DRV, ERR,
"Failed to get MPI traffic control.\n");
status = -EIO;
}
return status;
}
int ql_wait_fifo_empty(struct ql_adapter *qdev)
{
int count = 5;
u32 mgmnt_fifo_empty;
u32 nic_fifo_empty;
do {
nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE;
ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty);
mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY;
if (nic_fifo_empty && mgmnt_fifo_empty)
return 0;
msleep(100);
} while (count-- > 0);
return -ETIMEDOUT;
}
/* API called in work thread context to set new TX/RX /* API called in work thread context to set new TX/RX
* maximum frame size values to match MTU. * maximum frame size values to match MTU.
*/ */
@ -876,6 +965,8 @@ void ql_mpi_work(struct work_struct *work)
int err = 0; int err = 0;
rtnl_lock(); rtnl_lock();
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
while (ql_read32(qdev, STS) & STS_PI) { while (ql_read32(qdev, STS) & STS_PI) {
memset(mbcp, 0, sizeof(struct mbox_params)); memset(mbcp, 0, sizeof(struct mbox_params));
@ -888,6 +979,8 @@ void ql_mpi_work(struct work_struct *work)
break; break;
} }
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
rtnl_unlock(); rtnl_unlock();
ql_enable_completion_interrupt(qdev, 0); ql_enable_completion_interrupt(qdev, 0);
} }

View File

@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
struct tg3 *tp = bp->priv; struct tg3 *tp = bp->priv;
u32 val; u32 val;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) spin_lock_bh(&tp->lock);
return -EAGAIN;
if (tg3_readphy(tp, reg, &val)) if (tg3_readphy(tp, reg, &val))
return -EIO; val = -EIO;
spin_unlock_bh(&tp->lock);
return val; return val;
} }
@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{ {
struct tg3 *tp = bp->priv; struct tg3 *tp = bp->priv;
u32 ret = 0;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) spin_lock_bh(&tp->lock);
return -EAGAIN;
if (tg3_writephy(tp, reg, val)) if (tg3_writephy(tp, reg, val))
return -EIO; ret = -EIO;
return 0; spin_unlock_bh(&tp->lock);
return ret;
} }
static int tg3_mdio_reset(struct mii_bus *bp) static int tg3_mdio_reset(struct mii_bus *bp)
@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
static void tg3_mdio_start(struct tg3 *tp) static void tg3_mdio_start(struct tg3 *tp)
{ {
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus->mdio_lock);
}
tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
tw32_f(MAC_MI_MODE, tp->mi_mode); tw32_f(MAC_MI_MODE, tp->mi_mode);
udelay(80); udelay(80);
@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
tg3_mdio_config_5785(tp); tg3_mdio_config_5785(tp);
} }
static void tg3_mdio_stop(struct tg3 *tp)
{
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus->mdio_lock);
}
}
static int tg3_mdio_init(struct tg3 *tp) static int tg3_mdio_init(struct tg3 *tp)
{ {
int i; int i;
@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED; tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
mdiobus_unregister(tp->mdio_bus); mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus); mdiobus_free(tp->mdio_bus);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
} }
} }
@ -1363,7 +1350,7 @@ static void tg3_adjust_link(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR]; struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
spin_lock(&tp->lock); spin_lock_bh(&tp->lock);
mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK | mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
MAC_MODE_HALF_DUPLEX); MAC_MODE_HALF_DUPLEX);
@ -1431,7 +1418,7 @@ static void tg3_adjust_link(struct net_device *dev)
tp->link_config.active_speed = phydev->speed; tp->link_config.active_speed = phydev->speed;
tp->link_config.active_duplex = phydev->duplex; tp->link_config.active_duplex = phydev->duplex;
spin_unlock(&tp->lock); spin_unlock_bh(&tp->lock);
if (linkmesg) if (linkmesg)
tg3_link_report(tp); tg3_link_report(tp);
@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_nvram_lock(tp); tg3_nvram_lock(tp);
tg3_mdio_stop(tp);
tg3_ape_lock(tp, TG3_APE_LOCK_GRC); tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
/* No matching tg3_nvram_unlock() after this because /* No matching tg3_nvram_unlock() after this because
@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)
del_timer_sync(&tp->timer); del_timer_sync(&tp->timer);
tg3_phy_stop(tp);
tg3_full_lock(tp, 1); tg3_full_lock(tp, 1);
#if 0 #if 0
tg3_dump_state(tp); tg3_dump_state(tp);

View File

@ -2748,7 +2748,6 @@ struct tg3 {
#define TG3_FLG3_5701_DMA_BUG 0x00000008 #define TG3_FLG3_5701_DMA_BUG 0x00000008
#define TG3_FLG3_USE_PHYLIB 0x00000010 #define TG3_FLG3_USE_PHYLIB 0x00000010
#define TG3_FLG3_MDIOBUS_INITED 0x00000020 #define TG3_FLG3_MDIOBUS_INITED 0x00000020
#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
#define TG3_FLG3_PHY_CONNECTED 0x00000080 #define TG3_FLG3_PHY_CONNECTED 0x00000080
#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100 #define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200 #define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200

View File

@ -418,6 +418,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
goto halt_fail_and_release; goto halt_fail_and_release;
} }
memcpy(net->dev_addr, bp, ETH_ALEN); memcpy(net->dev_addr, bp, ETH_ALEN);
memcpy(net->perm_addr, bp, ETH_ALEN);
/* set a nonzero filter to enable data transfers */ /* set a nonzero filter to enable data transfers */
memset(u.set, 0, sizeof *u.set); memset(u.set, 0, sizeof *u.set);

View File

@ -266,7 +266,7 @@ do { \
#define ADM8211_SYNCTL_CS1 (1 << 28) #define ADM8211_SYNCTL_CS1 (1 << 28)
#define ADM8211_SYNCTL_CAL (1 << 27) #define ADM8211_SYNCTL_CAL (1 << 27)
#define ADM8211_SYNCTL_SELCAL (1 << 26) #define ADM8211_SYNCTL_SELCAL (1 << 26)
#define ADM8211_SYNCTL_RFtype ((1 << 24) || (1 << 23) || (1 << 22)) #define ADM8211_SYNCTL_RFtype ((1 << 24) | (1 << 23) | (1 << 22))
#define ADM8211_SYNCTL_RFMD (1 << 22) #define ADM8211_SYNCTL_RFMD (1 << 22)
#define ADM8211_SYNCTL_GENERAL (0x7 << 22) #define ADM8211_SYNCTL_GENERAL (0x7 << 22)
/* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */ /* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */

View File

@ -607,82 +607,7 @@ struct b43_qos_params {
struct ieee80211_tx_queue_params p; struct ieee80211_tx_queue_params p;
}; };
struct b43_wldev; struct b43_wl;
/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
struct b43_wl {
/* Pointer to the active wireless device on this chip */
struct b43_wldev *current_dev;
/* Pointer to the ieee80211 hardware data structure */
struct ieee80211_hw *hw;
/* Global driver mutex. Every operation must run with this mutex locked. */
struct mutex mutex;
/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
* handler, only. This basically is just the IRQ mask register. */
spinlock_t hardirq_lock;
/* The number of queues that were registered with the mac80211 subsystem
* initially. This is a backup copy of hw->queues in case hw->queues has
* to be dynamically lowered at runtime (Firmware does not support QoS).
* hw->queues has to be restored to the original value before unregistering
* from the mac80211 subsystem. */
u16 mac80211_initially_registered_queues;
/* We can only have one operating interface (802.11 core)
* at a time. General information about this interface follows.
*/
struct ieee80211_vif *vif;
/* The MAC address of the operating interface. */
u8 mac_addr[ETH_ALEN];
/* Current BSSID */
u8 bssid[ETH_ALEN];
/* Interface type. (NL80211_IFTYPE_XXX) */
int if_type;
/* Is the card operating in AP, STA or IBSS mode? */
bool operating;
/* filter flags */
unsigned int filter_flags;
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
#ifdef CONFIG_B43_HWRNG
struct hwrng rng;
bool rng_initialized;
char rng_name[30 + 1];
#endif /* CONFIG_B43_HWRNG */
/* List of all wireless devices on this chip */
struct list_head devlist;
u8 nr_devs;
bool radiotap_enabled;
bool radio_enabled;
/* The beacon we are currently using (AP or IBSS mode). */
struct sk_buff *current_beacon;
bool beacon0_uploaded;
bool beacon1_uploaded;
bool beacon_templates_virgin; /* Never wrote the templates? */
struct work_struct beacon_update_trigger;
/* The current QOS parameters for the 4 queues. */
struct b43_qos_params qos_params[4];
/* Work for adjustment of the transmission power.
* This is scheduled when we determine that the actual TX output
* power doesn't match what we want. */
struct work_struct txpower_adjust_work;
/* Packet transmit work */
struct work_struct tx_work;
/* Queue of packets to be transmitted. */
struct sk_buff_head tx_queue;
/* The device LEDs. */
struct b43_leds leds;
};
/* The type of the firmware file. */ /* The type of the firmware file. */
enum b43_firmware_file_type { enum b43_firmware_file_type {
@ -824,6 +749,97 @@ struct b43_wldev {
#endif #endif
}; };
/*
* Include goes here to avoid a dependency problem.
* A better fix would be to integrate xmit.h into b43.h.
*/
#include "xmit.h"
/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
struct b43_wl {
/* Pointer to the active wireless device on this chip */
struct b43_wldev *current_dev;
/* Pointer to the ieee80211 hardware data structure */
struct ieee80211_hw *hw;
/* Global driver mutex. Every operation must run with this mutex locked. */
struct mutex mutex;
/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
* handler, only. This basically is just the IRQ mask register. */
spinlock_t hardirq_lock;
/* The number of queues that were registered with the mac80211 subsystem
* initially. This is a backup copy of hw->queues in case hw->queues has
* to be dynamically lowered at runtime (Firmware does not support QoS).
* hw->queues has to be restored to the original value before unregistering
* from the mac80211 subsystem. */
u16 mac80211_initially_registered_queues;
/* We can only have one operating interface (802.11 core)
* at a time. General information about this interface follows.
*/
struct ieee80211_vif *vif;
/* The MAC address of the operating interface. */
u8 mac_addr[ETH_ALEN];
/* Current BSSID */
u8 bssid[ETH_ALEN];
/* Interface type. (NL80211_IFTYPE_XXX) */
int if_type;
/* Is the card operating in AP, STA or IBSS mode? */
bool operating;
/* filter flags */
unsigned int filter_flags;
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
#ifdef CONFIG_B43_HWRNG
struct hwrng rng;
bool rng_initialized;
char rng_name[30 + 1];
#endif /* CONFIG_B43_HWRNG */
/* List of all wireless devices on this chip */
struct list_head devlist;
u8 nr_devs;
bool radiotap_enabled;
bool radio_enabled;
/* The beacon we are currently using (AP or IBSS mode). */
struct sk_buff *current_beacon;
bool beacon0_uploaded;
bool beacon1_uploaded;
bool beacon_templates_virgin; /* Never wrote the templates? */
struct work_struct beacon_update_trigger;
/* The current QOS parameters for the 4 queues. */
struct b43_qos_params qos_params[4];
/* Work for adjustment of the transmission power.
* This is scheduled when we determine that the actual TX output
* power doesn't match what we want. */
struct work_struct txpower_adjust_work;
/* Packet transmit work */
struct work_struct tx_work;
/* Queue of packets to be transmitted. */
struct sk_buff_head tx_queue;
/* The device LEDs. */
struct b43_leds leds;
#ifdef CONFIG_B43_PIO
/*
* RX/TX header/tail buffers used by the frame transmit functions.
*/
struct b43_rxhdr_fw4 rxhdr;
struct b43_txhdr txhdr;
u8 rx_tail[4];
u8 tx_tail[4];
#endif /* CONFIG_B43_PIO */
};
static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
{ {
return hw->priv; return hw->priv;

View File

@ -348,9 +348,9 @@ void b43_leds_register(struct b43_wldev *dev)
} }
} }
void b43_leds_unregister(struct b43_wldev *dev) void b43_leds_unregister(struct b43_wl *wl)
{ {
struct b43_leds *leds = &dev->wl->leds; struct b43_leds *leds = &wl->leds;
b43_unregister_led(&leds->led_tx); b43_unregister_led(&leds->led_tx);
b43_unregister_led(&leds->led_rx); b43_unregister_led(&leds->led_rx);

View File

@ -60,7 +60,7 @@ enum b43_led_behaviour {
}; };
void b43_leds_register(struct b43_wldev *dev); void b43_leds_register(struct b43_wldev *dev);
void b43_leds_unregister(struct b43_wldev *dev); void b43_leds_unregister(struct b43_wl *wl);
void b43_leds_init(struct b43_wldev *dev); void b43_leds_init(struct b43_wldev *dev);
void b43_leds_exit(struct b43_wldev *dev); void b43_leds_exit(struct b43_wldev *dev);
void b43_leds_stop(struct b43_wldev *dev); void b43_leds_stop(struct b43_wldev *dev);
@ -76,7 +76,7 @@ struct b43_leds {
static inline void b43_leds_register(struct b43_wldev *dev) static inline void b43_leds_register(struct b43_wldev *dev)
{ {
} }
static inline void b43_leds_unregister(struct b43_wldev *dev) static inline void b43_leds_unregister(struct b43_wl *wl)
{ {
} }
static inline void b43_leds_init(struct b43_wldev *dev) static inline void b43_leds_init(struct b43_wldev *dev)

View File

@ -3874,6 +3874,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
{ {
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
struct b43_wldev *orig_dev; struct b43_wldev *orig_dev;
u32 mask;
redo: redo:
if (!dev || b43_status(dev) < B43_STAT_STARTED) if (!dev || b43_status(dev) < B43_STAT_STARTED)
@ -3920,7 +3921,8 @@ redo:
goto redo; goto redo;
return dev; return dev;
} }
B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)); mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
B43_WARN_ON(mask != 0xFFFFFFFF && mask);
/* Drain the TX queue */ /* Drain the TX queue */
while (skb_queue_len(&wl->tx_queue)) while (skb_queue_len(&wl->tx_queue))
@ -4499,6 +4501,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
cancel_work_sync(&(wl->beacon_update_trigger)); cancel_work_sync(&(wl->beacon_update_trigger));
wiphy_rfkill_stop_polling(hw->wiphy);
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
if (b43_status(dev) >= B43_STAT_STARTED) { if (b43_status(dev) >= B43_STAT_STARTED) {
dev = b43_wireless_core_stop(dev); dev = b43_wireless_core_stop(dev);
@ -4997,7 +5000,7 @@ static void b43_remove(struct ssb_device *dev)
if (list_empty(&wl->devlist)) { if (list_empty(&wl->devlist)) {
b43_rng_exit(wl); b43_rng_exit(wl);
b43_leds_unregister(wldev); b43_leds_unregister(wl);
/* Last core on the chip unregistered. /* Last core on the chip unregistered.
* We can destroy common struct b43_wl. * We can destroy common struct b43_wl.
*/ */

View File

@ -331,6 +331,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
unsigned int data_len) unsigned int data_len)
{ {
struct b43_wldev *dev = q->dev; struct b43_wldev *dev = q->dev;
struct b43_wl *wl = dev->wl;
const u8 *data = _data; const u8 *data = _data;
ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@ -340,13 +341,12 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO_TXDATA, q->mmio_base + B43_PIO_TXDATA,
sizeof(u16)); sizeof(u16));
if (data_len & 1) { if (data_len & 1) {
u8 tail[2] = { 0, };
/* Write the last byte. */ /* Write the last byte. */
ctl &= ~B43_PIO_TXCTL_WRITEHI; ctl &= ~B43_PIO_TXCTL_WRITEHI;
b43_piotx_write16(q, B43_PIO_TXCTL, ctl); b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
tail[0] = data[data_len - 1]; wl->tx_tail[0] = data[data_len - 1];
ssb_block_write(dev->dev, tail, 2, wl->tx_tail[1] = 0;
ssb_block_write(dev->dev, wl->tx_tail, 2,
q->mmio_base + B43_PIO_TXDATA, q->mmio_base + B43_PIO_TXDATA,
sizeof(u16)); sizeof(u16));
} }
@ -381,6 +381,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
unsigned int data_len) unsigned int data_len)
{ {
struct b43_wldev *dev = q->dev; struct b43_wldev *dev = q->dev;
struct b43_wl *wl = dev->wl;
const u8 *data = _data; const u8 *data = _data;
ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 | ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@ -391,29 +392,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO8_TXDATA, q->mmio_base + B43_PIO8_TXDATA,
sizeof(u32)); sizeof(u32));
if (data_len & 3) { if (data_len & 3) {
u8 tail[4] = { 0, }; wl->tx_tail[3] = 0;
/* Write the last few bytes. */ /* Write the last few bytes. */
ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
B43_PIO8_TXCTL_24_31); B43_PIO8_TXCTL_24_31);
switch (data_len & 3) { switch (data_len & 3) {
case 3: case 3:
ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
tail[0] = data[data_len - 3]; wl->tx_tail[0] = data[data_len - 3];
tail[1] = data[data_len - 2]; wl->tx_tail[1] = data[data_len - 2];
tail[2] = data[data_len - 1]; wl->tx_tail[2] = data[data_len - 1];
break; break;
case 2: case 2:
ctl |= B43_PIO8_TXCTL_8_15; ctl |= B43_PIO8_TXCTL_8_15;
tail[0] = data[data_len - 2]; wl->tx_tail[0] = data[data_len - 2];
tail[1] = data[data_len - 1]; wl->tx_tail[1] = data[data_len - 1];
wl->tx_tail[2] = 0;
break; break;
case 1: case 1:
tail[0] = data[data_len - 1]; wl->tx_tail[0] = data[data_len - 1];
wl->tx_tail[1] = 0;
wl->tx_tail[2] = 0;
break; break;
} }
b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
ssb_block_write(dev->dev, tail, 4, ssb_block_write(dev->dev, wl->tx_tail, 4,
q->mmio_base + B43_PIO8_TXDATA, q->mmio_base + B43_PIO8_TXDATA,
sizeof(u32)); sizeof(u32));
} }
@ -445,8 +448,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
static int pio_tx_frame(struct b43_pio_txqueue *q, static int pio_tx_frame(struct b43_pio_txqueue *q,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct b43_wldev *dev = q->dev;
struct b43_wl *wl = dev->wl;
struct b43_pio_txpacket *pack; struct b43_pio_txpacket *pack;
struct b43_txhdr txhdr;
u16 cookie; u16 cookie;
int err; int err;
unsigned int hdrlen; unsigned int hdrlen;
@ -457,8 +461,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
struct b43_pio_txpacket, list); struct b43_pio_txpacket, list);
cookie = generate_cookie(q, pack); cookie = generate_cookie(q, pack);
hdrlen = b43_txhdr_size(q->dev); hdrlen = b43_txhdr_size(dev);
err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb, err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
info, cookie); info, cookie);
if (err) if (err)
return err; return err;
@ -466,15 +470,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* Tell the firmware about the cookie of the last /* Tell the firmware about the cookie of the last
* mcast frame, so it can clear the more-data bit in it. */ * mcast frame, so it can clear the more-data bit in it. */
b43_shm_write16(q->dev, B43_SHM_SHARED, b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_MCASTCOOKIE, cookie); B43_SHM_SH_MCASTCOOKIE, cookie);
} }
pack->skb = skb; pack->skb = skb;
if (q->rev >= 8) if (q->rev >= 8)
pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen); pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
else else
pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen); pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
/* Remove it from the list of available packet slots. /* Remove it from the list of available packet slots.
* It will be put back when we receive the status report. */ * It will be put back when we receive the status report. */
@ -614,14 +618,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
static bool pio_rx_frame(struct b43_pio_rxqueue *q) static bool pio_rx_frame(struct b43_pio_rxqueue *q)
{ {
struct b43_wldev *dev = q->dev; struct b43_wldev *dev = q->dev;
struct b43_rxhdr_fw4 rxhdr; struct b43_wl *wl = dev->wl;
u16 len; u16 len;
u32 macstat; u32 macstat;
unsigned int i, padding; unsigned int i, padding;
struct sk_buff *skb; struct sk_buff *skb;
const char *err_msg = NULL; const char *err_msg = NULL;
memset(&rxhdr, 0, sizeof(rxhdr)); memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
/* Check if we have data and wait for it to get ready. */ /* Check if we have data and wait for it to get ready. */
if (q->rev >= 8) { if (q->rev >= 8) {
@ -659,16 +663,16 @@ data_ready:
/* Get the preamble (RX header) */ /* Get the preamble (RX header) */
if (q->rev >= 8) { if (q->rev >= 8) {
ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
q->mmio_base + B43_PIO8_RXDATA, q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32)); sizeof(u32));
} else { } else {
ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
q->mmio_base + B43_PIO_RXDATA, q->mmio_base + B43_PIO_RXDATA,
sizeof(u16)); sizeof(u16));
} }
/* Sanity checks. */ /* Sanity checks. */
len = le16_to_cpu(rxhdr.frame_len); len = le16_to_cpu(wl->rxhdr.frame_len);
if (unlikely(len > 0x700)) { if (unlikely(len > 0x700)) {
err_msg = "len > 0x700"; err_msg = "len > 0x700";
goto rx_error; goto rx_error;
@ -678,7 +682,7 @@ data_ready:
goto rx_error; goto rx_error;
} }
macstat = le32_to_cpu(rxhdr.mac_status); macstat = le32_to_cpu(wl->rxhdr.mac_status);
if (macstat & B43_RX_MAC_FCSERR) { if (macstat & B43_RX_MAC_FCSERR) {
if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
/* Drop frames with failed FCS. */ /* Drop frames with failed FCS. */
@ -703,24 +707,22 @@ data_ready:
q->mmio_base + B43_PIO8_RXDATA, q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32)); sizeof(u32));
if (len & 3) { if (len & 3) {
u8 tail[4] = { 0, };
/* Read the last few bytes. */ /* Read the last few bytes. */
ssb_block_read(dev->dev, tail, 4, ssb_block_read(dev->dev, wl->rx_tail, 4,
q->mmio_base + B43_PIO8_RXDATA, q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32)); sizeof(u32));
switch (len & 3) { switch (len & 3) {
case 3: case 3:
skb->data[len + padding - 3] = tail[0]; skb->data[len + padding - 3] = wl->rx_tail[0];
skb->data[len + padding - 2] = tail[1]; skb->data[len + padding - 2] = wl->rx_tail[1];
skb->data[len + padding - 1] = tail[2]; skb->data[len + padding - 1] = wl->rx_tail[2];
break; break;
case 2: case 2:
skb->data[len + padding - 2] = tail[0]; skb->data[len + padding - 2] = wl->rx_tail[0];
skb->data[len + padding - 1] = tail[1]; skb->data[len + padding - 1] = wl->rx_tail[1];
break; break;
case 1: case 1:
skb->data[len + padding - 1] = tail[0]; skb->data[len + padding - 1] = wl->rx_tail[0];
break; break;
} }
} }
@ -729,17 +731,15 @@ data_ready:
q->mmio_base + B43_PIO_RXDATA, q->mmio_base + B43_PIO_RXDATA,
sizeof(u16)); sizeof(u16));
if (len & 1) { if (len & 1) {
u8 tail[2] = { 0, };
/* Read the last byte. */ /* Read the last byte. */
ssb_block_read(dev->dev, tail, 2, ssb_block_read(dev->dev, wl->rx_tail, 2,
q->mmio_base + B43_PIO_RXDATA, q->mmio_base + B43_PIO_RXDATA,
sizeof(u16)); sizeof(u16));
skb->data[len + padding - 1] = tail[0]; skb->data[len + padding - 1] = wl->rx_tail[0];
} }
} }
b43_rx(q->dev, skb, &rxhdr); b43_rx(q->dev, skb, &wl->rxhdr);
return 1; return 1;

View File

@ -27,7 +27,7 @@
*/ */
#include "xmit.h" #include "b43.h"
#include "phy_common.h" #include "phy_common.h"
#include "dma.h" #include "dma.h"
#include "pio.h" #include "pio.h"

View File

@ -702,7 +702,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
u8 sta_id = iwl_find_station(priv, hdr->addr1); u8 sta_id = iwl_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1); hdr->addr1);
sta_id = iwl_add_station(priv, hdr->addr1, false, sta_id = iwl_add_station(priv, hdr->addr1, false,
CMD_ASYNC, NULL); CMD_ASYNC, NULL);

View File

@ -607,7 +607,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
if (rx_status.band == IEEE80211_BAND_5GHZ) if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags & rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) &
RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
/* set the preamble flag if appropriate */ /* set the preamble flag if appropriate */

View File

@ -283,7 +283,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
(s32)average_noise[i])) / 1500; (s32)average_noise[i])) / 1500;
/* bound gain by 2 bits value max, 3rd bit is sign */ /* bound gain by 2 bits value max, 3rd bit is sign */
data->delta_gain_code[i] = data->delta_gain_code[i] =
min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE); min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
if (delta_g < 0) if (delta_g < 0)
/* set negative sign */ /* set negative sign */

View File

@ -1164,7 +1164,7 @@ struct iwl_wep_cmd {
#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) #define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0
#define RX_RES_PHY_FLAGS_ANTENNA_POS 4 #define RX_RES_PHY_FLAGS_ANTENNA_POS 4
#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)

View File

@ -436,7 +436,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
u16 *validblockaddr) u16 *validblockaddr)
{ {
u16 next_link_addr = 0, link_value = 0, valid_addr; u16 next_link_addr = 0, link_value = 0, valid_addr;
int ret = 0;
int usedblocks = 0; int usedblocks = 0;
/* set addressing mode to absolute to traverse the link list */ /* set addressing mode to absolute to traverse the link list */
@ -456,29 +455,29 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
* check for more block on the link list * check for more block on the link list
*/ */
valid_addr = next_link_addr; valid_addr = next_link_addr;
next_link_addr = link_value; next_link_addr = link_value * sizeof(u16);
IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
usedblocks, next_link_addr); usedblocks, next_link_addr);
if (iwl_read_otp_word(priv, next_link_addr, &link_value)) if (iwl_read_otp_word(priv, next_link_addr, &link_value))
return -EINVAL; return -EINVAL;
if (!link_value) { if (!link_value) {
/* /*
* reach the end of link list, * reach the end of link list, return success and
* set address point to the starting address * set address point to the starting address
* of the image * of the image
*/ */
goto done; *validblockaddr = valid_addr;
/* skip first 2 bytes (link list pointer) */
*validblockaddr += 2;
return 0;
} }
/* more in the link list, continue */ /* more in the link list, continue */
usedblocks++; usedblocks++;
} while (usedblocks < priv->cfg->max_ll_items); } while (usedblocks <= priv->cfg->max_ll_items);
/* OTP full, use last block */
IWL_DEBUG_INFO(priv, "OTP is full, use last block\n"); /* OTP has no valid blocks */
done: IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
*validblockaddr = valid_addr; return -EINVAL;
/* skip first 2 bytes (link list pointer) */
*validblockaddr += 2;
return ret;
} }
/** /**

View File

@ -222,35 +222,35 @@ struct iwl_eeprom_enhanced_txpwr {
* Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_) * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
*/ */
/* 2.4 GHz band: CCK */ /* 2.4 GHz band: CCK */
#define EEPROM_LB_CCK_20_COMMON ((0xAA)\ #define EEPROM_LB_CCK_20_COMMON ((0xA8)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ /* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
#define EEPROM_LB_OFDM_COMMON ((0xB2)\ #define EEPROM_LB_OFDM_COMMON ((0xB0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ /* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
#define EEPROM_HB_OFDM_COMMON ((0xCA)\ #define EEPROM_HB_OFDM_COMMON ((0xC8)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 2.4GHz band channels: /* 2.4GHz band channels:
* 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */ * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
#define EEPROM_LB_OFDM_20_BAND ((0xE2)\ #define EEPROM_LB_OFDM_20_BAND ((0xE0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */ /* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
#define EEPROM_LB_OFDM_HT40_BAND ((0x122)\ #define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */ /* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
#define EEPROM_HB_OFDM_20_BAND ((0x14A)\ #define EEPROM_HB_OFDM_20_BAND ((0x148)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */ /* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
#define EEPROM_HB_OFDM_HT40_BAND ((0x17A)\ #define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
/* 2.4 GHz band, channnel 13: Legacy, HT */ /* 2.4 GHz band, channnel 13: Legacy, HT */
#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x192)\ #define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
/* 5.2 GHz band, channnel 140: Legacy, HT */ /* 5.2 GHz band, channnel 140: Legacy, HT */
#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A2)\ #define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */ /* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B2)\ #define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */

View File

@ -1044,7 +1044,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
* as a bitmask. * as a bitmask.
*/ */
rx_status.antenna = rx_status.antenna =
le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK) (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
>> RX_RES_PHY_FLAGS_ANTENNA_POS; >> RX_RES_PHY_FLAGS_ANTENNA_POS;
/* set the preamble flag if appropriate */ /* set the preamble flag if appropriate */

View File

@ -169,7 +169,6 @@ static void znet_tx_timeout (struct net_device *dev);
static int znet_request_resources (struct net_device *dev) static int znet_request_resources (struct net_device *dev)
{ {
struct znet_private *znet = netdev_priv(dev); struct znet_private *znet = netdev_priv(dev);
unsigned long flags;
if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev)) if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
goto failed; goto failed;
@ -187,13 +186,9 @@ static int znet_request_resources (struct net_device *dev)
free_sia: free_sia:
release_region (znet->sia_base, znet->sia_size); release_region (znet->sia_base, znet->sia_size);
free_tx_dma: free_tx_dma:
flags = claim_dma_lock();
free_dma (znet->tx_dma); free_dma (znet->tx_dma);
release_dma_lock (flags);
free_rx_dma: free_rx_dma:
flags = claim_dma_lock();
free_dma (znet->rx_dma); free_dma (znet->rx_dma);
release_dma_lock (flags);
free_irq: free_irq:
free_irq (dev->irq, dev); free_irq (dev->irq, dev);
failed: failed:
@ -203,14 +198,11 @@ static int znet_request_resources (struct net_device *dev)
static void znet_release_resources (struct net_device *dev) static void znet_release_resources (struct net_device *dev)
{ {
struct znet_private *znet = netdev_priv(dev); struct znet_private *znet = netdev_priv(dev);
unsigned long flags;
release_region (znet->sia_base, znet->sia_size); release_region (znet->sia_base, znet->sia_size);
release_region (dev->base_addr, znet->io_size); release_region (dev->base_addr, znet->io_size);
flags = claim_dma_lock();
free_dma (znet->tx_dma); free_dma (znet->tx_dma);
free_dma (znet->rx_dma); free_dma (znet->rx_dma);
release_dma_lock (flags);
free_irq (dev->irq, dev); free_irq (dev->irq, dev);
} }

View File

@ -557,7 +557,7 @@ struct netdev_queue {
* Callback uses when the transmitter has not made any progress * Callback uses when the transmitter has not made any progress
* for dev->watchdog ticks. * for dev->watchdog ticks.
* *
* struct net_device_stats* (*get_stats)(struct net_device *dev); * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
* Called when a user wants to get the network device usage * Called when a user wants to get the network device usage
* statistics. If not defined, the counters in dev->stats will * statistics. If not defined, the counters in dev->stats will
* be used. * be used.

View File

@ -1077,12 +1077,16 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
ip_mc_up(in_dev); ip_mc_up(in_dev);
/* fall through */ /* fall through */
case NETDEV_CHANGEADDR: case NETDEV_CHANGEADDR:
if (IN_DEV_ARP_NOTIFY(in_dev)) /* Send gratuitous ARP to notify of link change */
arp_send(ARPOP_REQUEST, ETH_P_ARP, if (IN_DEV_ARP_NOTIFY(in_dev)) {
in_dev->ifa_list->ifa_address, struct in_ifaddr *ifa = in_dev->ifa_list;
dev,
in_dev->ifa_list->ifa_address, if (ifa)
NULL, dev->dev_addr, NULL); arp_send(ARPOP_REQUEST, ETH_P_ARP,
ifa->ifa_address, dev,
ifa->ifa_address, NULL,
dev->dev_addr, NULL);
}
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
ip_mc_down(in_dev); ip_mc_down(in_dev);

View File

@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
skb = rx.skb; skb = rx.skb;
list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (rx.sdata && ieee80211_is_data(hdr->frame_control)) {
rx.flags |= IEEE80211_RX_RA_MATCH;
prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
if (prepares)
prev = rx.sdata;
} else list_for_each_entry_rcu(sdata, &local->interfaces, list) {
if (!netif_running(sdata->dev)) if (!netif_running(sdata->dev))
continue; continue;
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
continue; continue;
rx.flags |= IEEE80211_RX_RA_MATCH; rx.flags |= IEEE80211_RX_RA_MATCH;

View File

@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta)
u.ap); u.ap);
drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
sdata = sta->sdata;
} }
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta)
drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
&(*sta)->sta); &(*sta)->sta);
sdata = (*sta)->sdata;
} }
if (ieee80211_vif_is_mesh(&sdata->vif)) { if (ieee80211_vif_is_mesh(&sdata->vif)) {

View File

@ -1704,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
if (!is_multicast_ether_addr(hdr.addr1)) { if (!is_multicast_ether_addr(hdr.addr1)) {
rcu_read_lock(); rcu_read_lock();
sta = sta_info_get(local, hdr.addr1); sta = sta_info_get(local, hdr.addr1);
if (sta) /* XXX: in the future, use sdata to look up the sta */
if (sta && sta->sdata == sdata)
sta_flags = get_sta_flags(sta); sta_flags = get_sta_flags(sta);
rcu_read_unlock(); rcu_read_unlock();
} }

View File

@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) { if (WARN_ON(!info->control.vif)) {
kfree(skb); kfree_skb(skb);
return; return;
} }
@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) { if (WARN_ON(!info->control.vif)) {
kfree(skb); kfree_skb(skb);
continue; continue;
} }

View File

@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
tcm = NLMSG_DATA(nlh); tcm = NLMSG_DATA(nlh);
tcm->tcm_family = AF_UNSPEC; tcm->tcm_family = AF_UNSPEC;
tcm->tcm__pad1 = 0; tcm->tcm__pad1 = 0;
tcm->tcm__pad1 = 0; tcm->tcm__pad2 = 0;
tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
tcm->tcm_parent = tp->classid; tcm->tcm_parent = tp->classid;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);

View File

@ -4031,7 +4031,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
rdev = cfg80211_get_dev_from_info(info); rdev = cfg80211_get_dev_from_info(info);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
err = PTR_ERR(rdev); err = PTR_ERR(rdev);
goto out; goto out_rtnl;
} }
net = get_net_ns_by_pid(pid); net = get_net_ns_by_pid(pid);
@ -4051,6 +4051,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
put_net(net); put_net(net);
out: out:
cfg80211_unlock_rdev(rdev); cfg80211_unlock_rdev(rdev);
out_rtnl:
rtnl_unlock(); rtnl_unlock();
return err; return err;
} }