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: (108 commits)
  bridge: ensure to unlock in error path in br_multicast_query().
  drivers/net/tulip/eeprom.c: fix bogus "(null)" in tulip init messages
  sky2: Avoid rtnl_unlock without rtnl_lock
  ipv6: Send netlink notification when DAD fails
  drivers/net/tg3.c: change the field used with the TG3_FLAG_10_100_ONLY constant
  ipconfig: Handle devices which take some time to come up.
  mac80211: Fix memory leak in ieee80211_if_write()
  mac80211: Fix (dynamic) power save entry
  ipw2200: use kmalloc for large local variables
  ath5k: read eeprom IQ calibration values correctly for G mode
  ath5k: fix I/Q calibration (for real)
  ath5k: fix TSF reset
  ath5k: use fixed antenna for tx descriptors
  libipw: split ieee->networks into small pieces
  mac80211: Fix sta_mtx unlocking on insert STA failure path
  rt2x00: remove KSEG1ADDR define from rt2x00soc.h
  net: add ColdFire support to the smc91x driver
  asix: fix setting mac address for AX88772
  ipv6 ip6_tunnel: eliminate unused recursion field from ip6_tnl{}.
  net: Fix dev_mc_add()
  ...
This commit is contained in:
Linus Torvalds 2010-03-13 14:50:18 -08:00
commit d89b218b80
114 changed files with 1300 additions and 23812 deletions

View file

@ -1405,20 +1405,30 @@ F: arch/x86/include/asm/calgary.h
F: arch/x86/include/asm/tce.h F: arch/x86/include/asm/tce.h
CAN NETWORK LAYER CAN NETWORK LAYER
M: Urs Thuermann <urs.thuermann@volkswagen.de> M: Oliver Hartkopp <socketcan@hartkopp.net>
M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de> M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
L: socketcan-core@lists.berlios.de (subscribers-only) M: Urs Thuermann <urs.thuermann@volkswagen.de>
L: socketcan-core@lists.berlios.de
L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/ W: http://developer.berlios.de/projects/socketcan/
S: Maintained S: Maintained
F: drivers/net/can/ F: net/can/
F: include/linux/can/
F: include/linux/can.h F: include/linux/can.h
F: include/linux/can/core.h
F: include/linux/can/bcm.h
F: include/linux/can/raw.h
CAN NETWORK DRIVERS CAN NETWORK DRIVERS
M: Wolfgang Grandegger <wg@grandegger.com> M: Wolfgang Grandegger <wg@grandegger.com>
L: socketcan-core@lists.berlios.de (subscribers-only) L: socketcan-core@lists.berlios.de
L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/ W: http://developer.berlios.de/projects/socketcan/
S: Maintained S: Maintained
F: drivers/net/can/
F: include/linux/can/dev.h
F: include/linux/can/error.h
F: include/linux/can/netlink.h
F: include/linux/can/platform/
CELL BROADBAND ENGINE ARCHITECTURE CELL BROADBAND ENGINE ARCHITECTURE
M: Arnd Bergmann <arnd@arndb.de> M: Arnd Bergmann <arnd@arndb.de>
@ -2130,6 +2140,7 @@ F: drivers/net/eexpress.*
ETHERNET BRIDGE ETHERNET BRIDGE
M: Stephen Hemminger <shemminger@linux-foundation.org> M: Stephen Hemminger <shemminger@linux-foundation.org>
L: bridge@lists.linux-foundation.org L: bridge@lists.linux-foundation.org
L: netdev@vger.kernel.org
W: http://www.linux-foundation.org/en/Net:Bridge W: http://www.linux-foundation.org/en/Net:Bridge
S: Maintained S: Maintained
F: include/linux/netfilter_bridge/ F: include/linux/netfilter_bridge/

View file

@ -907,7 +907,7 @@ config SMC91X
select CRC32 select CRC32
select MII select MII
depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
MIPS || BLACKFIN || MN10300 MIPS || BLACKFIN || MN10300 || COLDFIRE
help help
This is a driver for SMC's 91x series of Ethernet chipsets, This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it including the SMC91C94 and the SMC91C111. Say Y if you want it

View file

@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget)
if (work_done < budget) { if (work_done < budget) {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ksp->rx_lock, flags); spin_lock_irqsave(&ksp->rx_lock, flags);
__napi_complete(napi);
/*enable rx interrupt*/ /*enable rx interrupt*/
writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
__napi_complete(napi);
spin_unlock_irqrestore(&ksp->rx_lock, flags); spin_unlock_irqrestore(&ksp->rx_lock, flags);
} }
return work_done; return work_done;

View file

@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops;
#define drvr_stats(adapter) (&adapter->stats.drvr_stats) #define drvr_stats(adapter) (&adapter->stats.drvr_stats)
static inline unsigned int be_pci_func(struct be_adapter *adapter)
{
return PCI_FUNC(adapter->pdev->devfn);
}
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
#define PAGE_SHIFT_4K 12 #define PAGE_SHIFT_4K 12

View file

@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter,
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
AMAP_SET_BITS(struct amap_eq_context, func, req->context,
be_pci_func(adapter));
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
/* 4byte eqe*/ /* 4byte eqe*/
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@ -678,7 +675,6 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
be_encoded_q_len(mccq->len)); be_encoded_q_len(mccq->len));
@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
be_encoded_q_len(txq->len)); be_encoded_q_len(txq->len));
AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
be_pci_func(adapter));
AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);

View file

@ -114,8 +114,7 @@
#define IMG_TYPE_ISCSI_BACKUP 9 #define IMG_TYPE_ISCSI_BACKUP 9
#define IMG_TYPE_FCOE_FW_ACTIVE 10 #define IMG_TYPE_FCOE_FW_ACTIVE 10
#define IMG_TYPE_FCOE_FW_BACKUP 11 #define IMG_TYPE_FCOE_FW_BACKUP 11
#define IMG_TYPE_NCSI_BITFILE 13 #define IMG_TYPE_NCSI_FW 13
#define IMG_TYPE_NCSI_8051 14
#define FLASHROM_OPER_FLASH 1 #define FLASHROM_OPER_FLASH 1
#define FLASHROM_OPER_SAVE 2 #define FLASHROM_OPER_SAVE 2
@ -127,6 +126,7 @@
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */
#define FLASH_NCSI_MAGIC (0x16032009) #define FLASH_NCSI_MAGIC (0x16032009)
#define FLASH_NCSI_DISABLED (0) #define FLASH_NCSI_DISABLED (0)
@ -144,6 +144,7 @@
#define FLASH_FCoE_BIOS_START_g2 (524288) #define FLASH_FCoE_BIOS_START_g2 (524288)
#define FLASH_REDBOOT_START_g2 (0) #define FLASH_REDBOOT_START_g2 (0)
#define FLASH_NCSI_START_g3 (15990784)
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152) #define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304) #define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456) #define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)

View file

@ -1382,7 +1382,7 @@ rx_eq_free:
/* There are 8 evt ids per func. Retruns the evt id's bit number */ /* There are 8 evt ids per func. Retruns the evt id's bit number */
static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
{ {
return eq_id - 8 * be_pci_func(adapter); return eq_id % 8;
} }
static irqreturn_t be_intx(int irq, void *dev) static irqreturn_t be_intx(int irq, void *dev)
@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter,
const u8 *p = fw->data; const u8 *p = fw->data;
struct be_cmd_write_flashrom *req = flash_cmd->va; struct be_cmd_write_flashrom *req = flash_cmd->va;
struct flash_comp *pflashcomp; struct flash_comp *pflashcomp;
int num_comp;
struct flash_comp gen3_flash_types[8] = { struct flash_comp gen3_flash_types[9] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g3}, FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter,
{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g3}, FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
FLASH_IMAGE_MAX_SIZE_g3} FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
FLASH_NCSI_IMAGE_MAX_SIZE_g3}
}; };
struct flash_comp gen2_flash_types[8] = { struct flash_comp gen2_flash_types[8] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter,
if (adapter->generation == BE_GEN3) { if (adapter->generation == BE_GEN3) {
pflashcomp = gen3_flash_types; pflashcomp = gen3_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g3); filehdr_size = sizeof(struct flash_file_hdr_g3);
num_comp = 9;
} else { } else {
pflashcomp = gen2_flash_types; pflashcomp = gen2_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g2); filehdr_size = sizeof(struct flash_file_hdr_g2);
num_comp = 8;
} }
for (i = 0; i < 8; i++) { for (i = 0; i < num_comp; i++) {
if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
continue;
if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
(!be_flash_redboot(adapter, fw->data, (!be_flash_redboot(adapter, fw->data,
pflashcomp[i].offset, pflashcomp[i].size, pflashcomp[i].offset, pflashcomp[i].size,
@ -1985,16 +1993,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
struct be_dma_mem flash_cmd; struct be_dma_mem flash_cmd;
int status, i = 0; int status, i = 0;
const u8 *p; const u8 *p;
char fw_ver[FW_VER_LEN];
char fw_cfg;
status = be_cmd_get_fw_ver(adapter, fw_ver);
if (status)
return status;
fw_cfg = *(fw_ver + 2);
if (fw_cfg == '0')
fw_cfg = '1';
strcpy(fw_file, func); strcpy(fw_file, func);
status = request_firmware(&fw, fw_file, &adapter->pdev->dev); status = request_firmware(&fw, fw_file, &adapter->pdev->dev);

View file

@ -26,6 +26,7 @@
#define DRV_NAME "bfin_can" #define DRV_NAME "bfin_can"
#define BFIN_CAN_TIMEOUT 100 #define BFIN_CAN_TIMEOUT 100
#define TX_ECHO_SKB_MAX 1
/* /*
* transmit and receive channels * transmit and receive channels
@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void)
struct net_device *dev; struct net_device *dev;
struct bfin_can_priv *priv; struct bfin_can_priv *priv;
dev = alloc_candev(sizeof(*priv)); dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
if (!dev) if (!dev)
return NULL; return NULL;

View file

@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
return NETDEV_TX_OK; return NETDEV_TX_OK;
nomem: nomem:
if (skb) dev_kfree_skb(skb);
dev_kfree_skb(skb);
stats->tx_dropped++; stats->tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;

View file

@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
INIT_WORK(&cp->reset_task, cas_reset_task); INIT_WORK(&cp->reset_task, cas_reset_task);
/* Default link parameters */ /* Default link parameters */
if (link_mode >= 0 && link_mode <= 6) if (link_mode >= 0 && link_mode < 6)
cp->link_cntl = link_modes[link_mode]; cp->link_cntl = link_modes[link_mode];
else else
cp->link_cntl = BMCR_ANENABLE; cp->link_cntl = BMCR_ANENABLE;

View file

@ -28,6 +28,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -55,9 +56,9 @@ module_param(dumb_switch, int, 0444);
MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_VERSION "0.5.1" #define CPMAC_VERSION "0.5.2"
/* frame size + 802.1q tag */ /* frame size + 802.1q tag + FCS size */
#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
#define CPMAC_QUEUES 8 #define CPMAC_QUEUES 8
/* Ethernet registers */ /* Ethernet registers */
@ -1136,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
} }
if (phy_id == PHY_MAX_ADDR) { if (phy_id == PHY_MAX_ADDR) {
dev_err(&pdev->dev, "no PHY present\n"); dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
return -ENODEV; strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
phy_id = pdev->id;
} }
dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
@ -1290,8 +1292,8 @@ void __devexit cpmac_exit(void)
{ {
platform_driver_unregister(&cpmac_driver); platform_driver_unregister(&cpmac_driver);
mdiobus_unregister(cpmac_mii); mdiobus_unregister(cpmac_mii);
mdiobus_free(cpmac_mii);
iounmap(cpmac_mii->priv); iounmap(cpmac_mii->priv);
mdiobus_free(cpmac_mii);
} }
module_init(cpmac_init); module_init(cpmac_init);

View file

@ -1294,6 +1294,7 @@ static void cxgb_down(struct adapter *adapter)
free_irq_resources(adapter); free_irq_resources(adapter);
quiesce_rx(adapter); quiesce_rx(adapter);
t3_sge_stop(adapter);
flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
} }

View file

@ -2385,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(ndev); struct emac_priv *priv = netdev_priv(ndev);
netif_carrier_off(ndev); netif_carrier_off(ndev);
for (cnt = 0; cnt <= ETH_ALEN; cnt++) for (cnt = 0; cnt < ETH_ALEN; cnt++)
ndev->dev_addr[cnt] = priv->mac_addr[cnt]; ndev->dev_addr[cnt] = priv->mac_addr[cnt];
/* Configuration items */ /* Configuration items */

View file

@ -320,6 +320,8 @@
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
/* Header split receive */ /* Header split receive */
#define E1000_RFCTL_NFSW_DIS 0x00000040
#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_ACK_DIS 0x00001000 #define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000 #define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 #define E1000_RFCTL_IPV6_EX_DIS 0x00010000

View file

@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
reg &= ~(1 << 31); reg &= ~(1 << 31);
ew32(STATUS, reg); ew32(STATUS, reg);
} }
/*
* work-around descriptor data corruption issue during nfs v2 udp
* traffic, just disable the nfs filtering capability
*/
reg = er32(RFCTL);
reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
ew32(RFCTL, reg);
return;
} }
/** /**

View file

@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
} }
/* setup the TxBD length and buffer pointer for the first BD */ /* setup the TxBD length and buffer pointer for the first BD */
tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE); skb_headlen(skb), DMA_TO_DEVICE);
@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_start->lstatus = lstatus; txbdp_start->lstatus = lstatus;
eieio(); /* force lstatus write before tx_skbuff */
tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
/* Update the current skb pointer to the next entry we will use /* Update the current skb pointer to the next entry we will use
* (wrapping if necessary) */ * (wrapping if necessary) */
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &

View file

@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf,
self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
GFP_KERNEL); GFP_KERNEL);
if (!self->rx_urb)
goto err_free_net;
for (i = 0; i < self->max_rx_urb; i++) { for (i = 0; i < self->max_rx_urb; i++) {
self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
@ -1783,6 +1785,8 @@ err_out_2:
err_out_1: err_out_1:
for (i = 0; i < self->max_rx_urb; i++) for (i = 0; i < self->max_rx_urb; i++)
usb_free_urb(self->rx_urb[i]); usb_free_urb(self->rx_urb[i]);
kfree(self->rx_urb);
err_free_net:
free_netdev(net); free_netdev(net);
err_out: err_out:
return ret; return ret;

View file

@ -423,6 +423,11 @@ struct qlcnic_adapter_stats {
u64 lro_pkts; u64 lro_pkts;
u64 rxbytes; u64 rxbytes;
u64 txbytes; u64 txbytes;
u64 lrobytes;
u64 lso_frames;
u64 xmit_on;
u64 xmit_off;
u64 skb_alloc_failure;
}; };
/* /*
@ -1095,11 +1100,11 @@ struct qlcnic_brdinfo {
static const struct qlcnic_brdinfo qlcnic_boards[] = { static const struct qlcnic_brdinfo qlcnic_boards[] = {
{0x1077, 0x8020, 0x1077, 0x203, {0x1077, 0x8020, 0x1077, 0x203,
"8200 Series Single Port 10GbE Converged Network Adapter \ "8200 Series Single Port 10GbE Converged Network Adapter "
(TCP/IP Networking)"}, "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x207, {0x1077, 0x8020, 0x1077, 0x207,
"8200 Series Dual Port 10GbE Converged Network Adapter \ "8200 Series Dual Port 10GbE Converged Network Adapter "
(TCP/IP Networking)"}, "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x20b, {0x1077, 0x8020, 0x1077, 0x20b,
"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x1077, 0x20c, {0x1077, 0x8020, 0x1077, 0x20c,

View file

@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
{"tx_bytes", {"tx_bytes",
QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
{"lrobytes",
QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
{"lso_frames",
QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
{"xmit_on",
QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
{"xmit_off",
QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
QLC_OFF(stats.skb_alloc_failure)},
}; };
#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
@ -785,6 +796,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
} }
} }
static u32 qlcnic_get_tx_csum(struct net_device *dev)
{
return dev->features & NETIF_F_IP_CSUM;
}
static u32 qlcnic_get_rx_csum(struct net_device *dev) static u32 qlcnic_get_rx_csum(struct net_device *dev)
{ {
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
@ -995,6 +1011,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.set_ringparam = qlcnic_set_ringparam, .set_ringparam = qlcnic_set_ringparam,
.get_pauseparam = qlcnic_get_pauseparam, .get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam, .set_pauseparam = qlcnic_set_pauseparam,
.get_tx_csum = qlcnic_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum,
.set_sg = ethtool_op_set_sg, .set_sg = ethtool_op_set_sg,
.get_tso = qlcnic_get_tso, .get_tso = qlcnic_get_tso,

View file

@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
if (nr_desc >= qlcnic_tx_avail(tx_ring)) { if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
netif_tx_stop_queue(tx_ring->txq); netif_tx_stop_queue(tx_ring->txq);
__netif_tx_unlock_bh(tx_ring->txq); __netif_tx_unlock_bh(tx_ring->txq);
adapter->stats.xmit_off++;
return -EBUSY; return -EBUSY;
} }
@ -397,20 +398,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
} }
static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
u8 *addr, struct list_head *del_list)
{ {
struct list_head *head; struct list_head *head;
struct qlcnic_mac_list_s *cur; struct qlcnic_mac_list_s *cur;
/* look up if already exists */ /* look up if already exists */
list_for_each(head, del_list) { list_for_each(head, &adapter->mac_list) {
cur = list_entry(head, struct qlcnic_mac_list_s, list); cur = list_entry(head, struct qlcnic_mac_list_s, list);
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
list_move_tail(head, &adapter->mac_list);
return 0; return 0;
}
} }
cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
@ -432,14 +429,9 @@ void qlcnic_set_multi(struct net_device *netdev)
struct dev_mc_list *mc_ptr; struct dev_mc_list *mc_ptr;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP; u32 mode = VPORT_MISS_MODE_DROP;
LIST_HEAD(del_list);
struct list_head *head;
struct qlcnic_mac_list_s *cur;
list_splice_tail_init(&adapter->mac_list, &del_list); qlcnic_nic_add_mac(adapter, adapter->mac_addr);
qlcnic_nic_add_mac(adapter, bcast_addr);
qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list);
qlcnic_nic_add_mac(adapter, bcast_addr, &del_list);
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL; mode = VPORT_MISS_MODE_ACCEPT_ALL;
@ -454,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev)
if (!netdev_mc_empty(netdev)) { if (!netdev_mc_empty(netdev)) {
netdev_for_each_mc_addr(mc_ptr, netdev) { netdev_for_each_mc_addr(mc_ptr, netdev) {
qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr, qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr);
&del_list);
} }
} }
send_fw_cmd: send_fw_cmd:
qlcnic_nic_set_promisc(adapter, mode); qlcnic_nic_set_promisc(adapter, mode);
head = &del_list;
while (!list_empty(head)) {
cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
qlcnic_sre_macaddr_change(adapter,
cur->mac_addr, QLCNIC_MAC_DEL);
list_del(&cur->list);
kfree(cur);
}
} }
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)

View file

@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
return NULL; return NULL;
} }
#define FILEHEADER_SIZE (14 * 4)
static int static int
qlcnic_set_product_offs(struct qlcnic_adapter *adapter) qlcnic_validate_header(struct qlcnic_adapter *adapter)
{
const u8 *unirom = adapter->fw->data;
struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
__le32 fw_file_size = adapter->fw->size;
__le32 entries;
__le32 entry_size;
__le32 tab_size;
if (fw_file_size < FILEHEADER_SIZE)
return -EINVAL;
entries = cpu_to_le32(directory->num_entries);
entry_size = cpu_to_le32(directory->entry_size);
tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
if (fw_file_size < tab_size)
return -EINVAL;
return 0;
}
static int
qlcnic_validate_bootld(struct qlcnic_adapter *adapter)
{
struct uni_table_desc *tab_desc;
struct uni_data_desc *descr;
const u8 *unirom = adapter->fw->data;
int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
QLCNIC_UNI_BOOTLD_IDX_OFF));
__le32 offs;
__le32 tab_size;
__le32 data_size;
tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD);
if (!tab_desc)
return -EINVAL;
tab_size = cpu_to_le32(tab_desc->findex) +
(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
if (adapter->fw->size < tab_size)
return -EINVAL;
offs = cpu_to_le32(tab_desc->findex) +
(cpu_to_le32(tab_desc->entry_size) * (idx));
descr = (struct uni_data_desc *)&unirom[offs];
data_size = descr->findex + cpu_to_le32(descr->size);
if (adapter->fw->size < data_size)
return -EINVAL;
return 0;
}
static int
qlcnic_validate_fw(struct qlcnic_adapter *adapter)
{
struct uni_table_desc *tab_desc;
struct uni_data_desc *descr;
const u8 *unirom = adapter->fw->data;
int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
QLCNIC_UNI_FIRMWARE_IDX_OFF));
__le32 offs;
__le32 tab_size;
__le32 data_size;
tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW);
if (!tab_desc)
return -EINVAL;
tab_size = cpu_to_le32(tab_desc->findex) +
(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
if (adapter->fw->size < tab_size)
return -EINVAL;
offs = cpu_to_le32(tab_desc->findex) +
(cpu_to_le32(tab_desc->entry_size) * (idx));
descr = (struct uni_data_desc *)&unirom[offs];
data_size = descr->findex + cpu_to_le32(descr->size);
if (adapter->fw->size < data_size)
return -EINVAL;
return 0;
}
static int
qlcnic_validate_product_offs(struct qlcnic_adapter *adapter)
{ {
struct uni_table_desc *ptab_descr; struct uni_table_desc *ptab_descr;
const u8 *unirom = adapter->fw->data; const u8 *unirom = adapter->fw->data;
u32 i;
__le32 entries;
int mn_present = qlcnic_has_mn(adapter); int mn_present = qlcnic_has_mn(adapter);
__le32 entries;
__le32 entry_size;
__le32 tab_size;
u32 i;
ptab_descr = qlcnic_get_table_desc(unirom, ptab_descr = qlcnic_get_table_desc(unirom,
QLCNIC_UNI_DIR_SECT_PRODUCT_TBL); QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
if (ptab_descr == NULL) if (!ptab_descr)
return -1; return -EINVAL;
entries = cpu_to_le32(ptab_descr->num_entries); entries = cpu_to_le32(ptab_descr->num_entries);
entry_size = cpu_to_le32(ptab_descr->entry_size);
tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
if (adapter->fw->size < tab_size)
return -EINVAL;
nomn: nomn:
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
@ -609,7 +711,37 @@ nomn:
mn_present = 0; mn_present = 0;
goto nomn; goto nomn;
} }
return -1; return -EINVAL;
}
static int
qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter)
{
if (qlcnic_validate_header(adapter)) {
dev_err(&adapter->pdev->dev,
"unified image: header validation failed\n");
return -EINVAL;
}
if (qlcnic_validate_product_offs(adapter)) {
dev_err(&adapter->pdev->dev,
"unified image: product validation failed\n");
return -EINVAL;
}
if (qlcnic_validate_bootld(adapter)) {
dev_err(&adapter->pdev->dev,
"unified image: bootld validation failed\n");
return -EINVAL;
}
if (qlcnic_validate_fw(adapter)) {
dev_err(&adapter->pdev->dev,
"unified image: firmware validation failed\n");
return -EINVAL;
}
return 0;
} }
static static
@ -715,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
+ QLCNIC_UNI_BIOS_VERSION_OFF)); + QLCNIC_UNI_BIOS_VERSION_OFF));
return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
} }
int int
@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
u8 fw_type = adapter->fw_type; u8 fw_type = adapter->fw_type;
if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) { if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
if (qlcnic_set_product_offs(adapter)) if (qlcnic_validate_unified_romimage(adapter))
return -EINVAL; return -EINVAL;
min_size = QLCNIC_UNI_FW_MIN_SIZE; min_size = QLCNIC_UNI_FW_MIN_SIZE;
@ -1114,8 +1246,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
buffer->skb = dev_alloc_skb(rds_ring->skb_size); buffer->skb = dev_alloc_skb(rds_ring->skb_size);
if (!buffer->skb) if (!buffer->skb) {
adapter->stats.skb_alloc_failure++;
return -ENOMEM; return -ENOMEM;
}
skb = buffer->skb; skb = buffer->skb;
@ -1289,7 +1423,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
netif_receive_skb(skb); netif_receive_skb(skb);
adapter->stats.lro_pkts++; adapter->stats.lro_pkts++;
adapter->stats.rxbytes += length; adapter->stats.lrobytes += length;
return buffer; return buffer;
} }
@ -1505,6 +1639,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
adapter->diag_cnt++; adapter->diag_cnt++;
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
adapter->stats.rx_pkts++;
adapter->stats.rxbytes += length;
return buffer; return buffer;
} }

View file

@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
netif_stop_queue(adapter->netdev); netif_stop_queue(adapter->netdev);
smp_mb(); smp_mb();
adapter->stats.xmit_off++;
} }
} }
@ -1385,6 +1386,7 @@ qlcnic_tso_check(struct net_device *netdev,
int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
struct cmd_desc_type0 *hwdesc; struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh; struct vlan_ethhdr *vh;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (protocol == cpu_to_be16(ETH_P_8021Q)) { if (protocol == cpu_to_be16(ETH_P_8021Q)) {
@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev,
tx_ring->producer = producer; tx_ring->producer = producer;
barrier(); barrier();
adapter->stats.lso_frames++;
} }
static int static int
@ -1573,6 +1576,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
adapter->stats.xmit_off++;
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -1880,6 +1884,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
netif_wake_queue(netdev); netif_wake_queue(netdev);
adapter->tx_timeo_cnt = 0; adapter->tx_timeo_cnt = 0;
adapter->stats.xmit_on++;
} }
__netif_tx_unlock(tx_ring->txq); __netif_tx_unlock(tx_ring->txq);
} }

View file

@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
tp->cur_tx += frags + 1; tp->cur_tx += frags + 1;
smp_wmb(); wmb();
RTL_W8(TxPoll, NPQ); /* set polling bit */ RTL_W8(TxPoll, NPQ); /* set polling bit */
@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
* until it does. * until it does.
*/ */
tp->intr_mask = 0xffff; tp->intr_mask = 0xffff;
smp_wmb(); wmb();
RTL_W16(IntrMask, tp->intr_event); RTL_W16(IntrMask, tp->intr_event);
} }

View file

@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic)
tmp_v_addr = mac_control->stats_mem; tmp_v_addr = mac_control->stats_mem;
mac_control->stats_info = (struct stat_block *)tmp_v_addr; mac_control->stats_info = (struct stat_block *)tmp_v_addr;
memset(tmp_v_addr, 0, size); memset(tmp_v_addr, 0, size);
DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name, DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
(unsigned long long)tmp_p_addr); dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
return SUCCESS; return SUCCESS;
} }
@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp)
struct swStat *swstats; struct swStat *swstats;
DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n", DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
__func__, sp->dev->name); __func__, pci_name(sp->pdev));
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));

View file

@ -4863,6 +4863,7 @@ static int sky2_resume(struct pci_dev *pdev)
if (!hw) if (!hw)
return 0; return 0;
rtnl_lock();
err = pci_set_power_state(pdev, PCI_D0); err = pci_set_power_state(pdev, PCI_D0);
if (err) if (err)
goto out; goto out;
@ -4884,7 +4885,6 @@ static int sky2_resume(struct pci_dev *pdev)
sky2_write32(hw, B0_IMSK, Y2_IS_BASE); sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
napi_enable(&hw->napi); napi_enable(&hw->napi);
rtnl_lock();
for (i = 0; i < hw->ports; i++) { for (i = 0; i < hw->ports; i++) {
err = sky2_reattach(hw->dev[i]); err = sky2_reattach(hw->dev[i]);
if (err) if (err)

View file

@ -330,6 +330,48 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#include <unit/smc91111.h> #include <unit/smc91111.h>
#elif defined(CONFIG_ARCH_MSM)
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_NOWAIT 1
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH
#elif defined(CONFIG_COLDFIRE)
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_NOWAIT 1
static inline void mcf_insw(void *a, unsigned char *p, int l)
{
u16 *wp = (u16 *) p;
while (l-- > 0)
*wp++ = readw(a);
}
static inline void mcf_outsw(void *a, unsigned char *p, int l)
{
u16 *wp = (u16 *) p;
while (l-- > 0)
writew(*wp++, a);
}
#define SMC_inw(a, r) _swapw(readw((a) + (r)))
#define SMC_outw(v, a, r) writew(_swapw(v), (a) + (r))
#define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l)
#define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l)
#define SMC_IRQ_FLAGS (IRQF_DISABLED)
#else #else
/* /*

View file

@ -5279,7 +5279,7 @@ static void tg3_poll_controller(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
for (i = 0; i < tp->irq_cnt; i++) for (i = 0; i < tp->irq_cnt; i++)
tg3_interrupt(tp->napi[i].irq_vec, dev); tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
} }
#endif #endif
@ -9776,7 +9776,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ADVERTISED_Pause | ADVERTISED_Pause |
ADVERTISED_Asym_Pause; ADVERTISED_Asym_Pause;
if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
mask |= ADVERTISED_1000baseT_Half | mask |= ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full; ADVERTISED_1000baseT_Full;

View file

@ -143,6 +143,12 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
void __devinit tulip_parse_eeprom(struct net_device *dev) void __devinit tulip_parse_eeprom(struct net_device *dev)
{ {
/*
dev is not registered at this point, so logging messages can't
use dev_<level> or netdev_<level> but dev->name is good via a
hack in the caller
*/
/* The last media info list parsed, for multiport boards. */ /* The last media info list parsed, for multiport boards. */
static struct mediatable *last_mediatable; static struct mediatable *last_mediatable;
static unsigned char *last_ee_data; static unsigned char *last_ee_data;
@ -161,15 +167,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
if (ee_data[0] == 0xff) { if (ee_data[0] == 0xff) {
if (last_mediatable) { if (last_mediatable) {
controller_index++; controller_index++;
dev_info(&dev->dev, pr_info("%s: Controller %d of multiport board\n",
"Controller %d of multiport board\n", dev->name, controller_index);
controller_index);
tp->mtable = last_mediatable; tp->mtable = last_mediatable;
ee_data = last_ee_data; ee_data = last_ee_data;
goto subsequent_board; goto subsequent_board;
} else } else
dev_info(&dev->dev, pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
"Missing EEPROM, this interface may not work correctly!\n"); dev->name);
return; return;
} }
/* Do a fix-up based on the vendor half of the station address prefix. */ /* Do a fix-up based on the vendor half of the station address prefix. */
@ -181,15 +186,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
i++; /* An Accton EN1207, not an outlaw Maxtech. */ i++; /* An Accton EN1207, not an outlaw Maxtech. */
memcpy(ee_data + 26, eeprom_fixups[i].newtable, memcpy(ee_data + 26, eeprom_fixups[i].newtable,
sizeof(eeprom_fixups[i].newtable)); sizeof(eeprom_fixups[i].newtable));
dev_info(&dev->dev, pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n",
"Old format EEPROM on '%s' board. Using substitute media control info\n", dev->name, eeprom_fixups[i].name);
eeprom_fixups[i].name);
break; break;
} }
} }
if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
dev_info(&dev->dev, pr_info("%s: Old style EEPROM with no media selection information\n",
"Old style EEPROM with no media selection information\n"); dev->name);
return; return;
} }
} }
@ -217,8 +221,8 @@ subsequent_board:
/* there is no phy information, don't even try to build mtable */ /* there is no phy information, don't even try to build mtable */
if (count == 0) { if (count == 0) {
if (tulip_debug > 0) if (tulip_debug > 0)
dev_warn(&dev->dev, pr_warning("%s: no phy info, aborting mtable build\n",
"no phy info, aborting mtable build\n"); dev->name);
return; return;
} }
@ -234,8 +238,10 @@ subsequent_board:
mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
mtable->csr15dir = mtable->csr15val = 0; mtable->csr15dir = mtable->csr15val = 0;
dev_info(&dev->dev, "EEPROM default media type %s\n", pr_info("%s: EEPROM default media type %s\n",
media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); dev->name,
media & 0x0800 ? "Autosense"
: medianame[media & MEDIA_MASK]);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
struct medialeaf *leaf = &mtable->mleaf[i]; struct medialeaf *leaf = &mtable->mleaf[i];
@ -298,17 +304,17 @@ subsequent_board:
} }
if (tulip_debug > 1 && leaf->media == 11) { if (tulip_debug > 1 && leaf->media == 11) {
unsigned char *bp = leaf->leafdata; unsigned char *bp = leaf->leafdata;
dev_info(&dev->dev, pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
"MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n", dev->name,
bp[0], bp[1], bp[2 + bp[1]*2], bp[0], bp[1], bp[2 + bp[1]*2],
bp[5 + bp[2 + bp[1]*2]*2], bp[5 + bp[2 + bp[1]*2]*2],
bp[4 + bp[2 + bp[1]*2]*2]); bp[4 + bp[2 + bp[1]*2]*2]);
} }
dev_info(&dev->dev, pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
"Index #%d - Media %s (#%d) described by a %s (%d) block\n", dev->name,
i, medianame[leaf->media & 15], leaf->media, i, medianame[leaf->media & 15], leaf->media,
leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>", leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
leaf->type); leaf->type);
} }
if (new_advertise) if (new_advertise)
tp->sym_advertise = new_advertise; tp->sym_advertise = new_advertise;

View file

@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp)
typhoon_inc_cmd_index(&ring->lastWrite, 1); typhoon_inc_cmd_index(&ring->lastWrite, 1);
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
smp_wmb(); wmb();
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
spin_unlock(&tp->command_lock); spin_unlock(&tp->command_lock);
} }
@ -1311,13 +1311,15 @@ typhoon_init_interface(struct typhoon *tp)
tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
tp->card_state = Sleeping; tp->card_state = Sleeping;
smp_wmb();
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
spin_lock_init(&tp->command_lock); spin_lock_init(&tp->command_lock);
spin_lock_init(&tp->state_lock); spin_lock_init(&tp->state_lock);
/* Force the writes to the shared memory area out before continuing. */
wmb();
} }
static void static void

View file

@ -54,6 +54,7 @@ static const char driver_name [] = "asix";
#define AX_CMD_WRITE_IPG0 0x12 #define AX_CMD_WRITE_IPG0 0x12
#define AX_CMD_WRITE_IPG1 0x13 #define AX_CMD_WRITE_IPG1 0x13
#define AX_CMD_READ_NODE_ID 0x13 #define AX_CMD_READ_NODE_ID 0x13
#define AX_CMD_WRITE_NODE_ID 0x14
#define AX_CMD_WRITE_IPG2 0x14 #define AX_CMD_WRITE_IPG2 0x14
#define AX_CMD_WRITE_MULTI_FILTER 0x16 #define AX_CMD_WRITE_MULTI_FILTER 0x16
#define AX88172_CMD_READ_NODE_ID 0x17 #define AX88172_CMD_READ_NODE_ID 0x17
@ -165,6 +166,7 @@ static const char driver_name [] = "asix";
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
struct asix_data { struct asix_data {
u8 multi_filter[AX_MCAST_FILTER_SIZE]; u8 multi_filter[AX_MCAST_FILTER_SIZE];
u8 mac_addr[ETH_ALEN];
u8 phymode; u8 phymode;
u8 ledmode; u8 ledmode;
u8 eeprom_len; u8 eeprom_len;
@ -732,6 +734,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
} }
static int asix_set_mac_address(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
struct asix_data *data = (struct asix_data *)&dev->data;
struct sockaddr *addr = p;
if (netif_running(net))
return -EBUSY;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
/* We use the 20 byte dev->data
* for our 6 byte mac buffer
* to avoid allocating memory that
* is tricky to free later */
memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
data->mac_addr);
return 0;
}
/* We need to override some ethtool_ops so we require our /* We need to override some ethtool_ops so we require our
own structure so we don't interfere with other usbnet own structure so we don't interfere with other usbnet
devices that may be connected at the same time. */ devices that may be connected at the same time. */
@ -919,7 +945,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
.ndo_start_xmit = usbnet_start_xmit, .ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout, .ndo_tx_timeout = usbnet_tx_timeout,
.ndo_change_mtu = usbnet_change_mtu, .ndo_change_mtu = usbnet_change_mtu,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = asix_ioctl, .ndo_do_ioctl = asix_ioctl,
.ndo_set_multicast_list = asix_set_multicast, .ndo_set_multicast_list = asix_set_multicast,
@ -1213,7 +1239,7 @@ static const struct net_device_ops ax88178_netdev_ops = {
.ndo_stop = usbnet_stop, .ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit, .ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout, .ndo_tx_timeout = usbnet_tx_timeout,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = asix_set_multicast, .ndo_set_multicast_list = asix_set_multicast,
.ndo_do_ioctl = asix_ioctl, .ndo_do_ioctl = asix_ioctl,

View file

@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
*/ */
PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,

View file

@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
WepKeyRid wkr; WepKeyRid wkr;
int rc; int rc;
WARN_ON(keylen == 0); if (WARN_ON(keylen == 0))
return -1;
memset(&wkr, 0, sizeof(wkr)); memset(&wkr, 0, sizeof(wkr));
wkr.len = cpu_to_le16(sizeof(wkr)); wkr.len = cpu_to_le16(sizeof(wkr));

View file

@ -166,6 +166,7 @@ struct ar9170 {
struct ath_common common; struct ath_common common;
struct mutex mutex; struct mutex mutex;
enum ar9170_device_state state; enum ar9170_device_state state;
bool registered;
unsigned long bad_hw_nagger; unsigned long bad_hw_nagger;
int (*open)(struct ar9170 *); int (*open)(struct ar9170 *);

View file

@ -2701,7 +2701,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
wiphy_name(ar->hw->wiphy)); wiphy_name(ar->hw->wiphy));
return err; ar->registered = true;
return 0;
err_unreg: err_unreg:
ieee80211_unregister_hw(ar->hw); ieee80211_unregister_hw(ar->hw);
@ -2712,11 +2713,14 @@ err_out:
void ar9170_unregister(struct ar9170 *ar) void ar9170_unregister(struct ar9170 *ar)
{ {
if (ar->registered) {
#ifdef CONFIG_AR9170_LEDS #ifdef CONFIG_AR9170_LEDS
ar9170_unregister_leds(ar); ar9170_unregister_leds(ar);
#endif /* CONFIG_AR9170_LEDS */ #endif /* CONFIG_AR9170_LEDS */
kfree_skb(ar->rx_failover);
ieee80211_unregister_hw(ar->hw); ieee80211_unregister_hw(ar->hw);
}
kfree_skb(ar->rx_failover);
mutex_destroy(&ar->mutex); mutex_destroy(&ar->mutex);
} }

View file

@ -582,43 +582,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
return 0; return 0;
} }
static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
{
int err = 0;
err = request_firmware(&aru->firmware, "ar9170.fw",
&aru->udev->dev);
if (!err) {
aru->init_values = NULL;
return 0;
}
if (aru->req_one_stage_fw) {
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found and is required for this device\n");
return -EINVAL;
}
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found, trying old firmware...\n");
err = request_firmware(&aru->init_values, "ar9170-1.fw",
&aru->udev->dev);
if (err) {
dev_err(&aru->udev->dev, "file with init values not found.\n");
return err;
}
err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
if (err) {
release_firmware(aru->init_values);
dev_err(&aru->udev->dev, "firmware file not found.\n");
return err;
}
return err;
}
static int ar9170_usb_reset(struct ar9170_usb *aru) static int ar9170_usb_reset(struct ar9170_usb *aru)
{ {
int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
@ -757,6 +720,103 @@ err_out:
return err; return err;
} }
static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
{
struct device *parent = aru->udev->dev.parent;
/* unbind anything failed */
if (parent)
down(&parent->sem);
device_release_driver(&aru->udev->dev);
if (parent)
up(&parent->sem);
}
static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
{
struct ar9170_usb *aru = context;
int err;
aru->firmware = fw;
if (!fw) {
dev_err(&aru->udev->dev, "firmware file not found.\n");
goto err_freefw;
}
err = ar9170_usb_init_device(aru);
if (err)
goto err_freefw;
err = ar9170_usb_open(&aru->common);
if (err)
goto err_unrx;
err = ar9170_register(&aru->common, &aru->udev->dev);
ar9170_usb_stop(&aru->common);
if (err)
goto err_unrx;
return;
err_unrx:
ar9170_usb_cancel_urbs(aru);
err_freefw:
ar9170_usb_firmware_failed(aru);
}
static void ar9170_usb_firmware_inits(const struct firmware *fw,
void *context)
{
struct ar9170_usb *aru = context;
int err;
if (!fw) {
dev_err(&aru->udev->dev, "file with init values not found.\n");
ar9170_usb_firmware_failed(aru);
return;
}
aru->init_values = fw;
/* ok so we have the init values -- get code for two-stage */
err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
&aru->udev->dev, GFP_KERNEL, aru,
ar9170_usb_firmware_finish);
if (err)
ar9170_usb_firmware_failed(aru);
}
static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
{
struct ar9170_usb *aru = context;
int err;
if (fw) {
ar9170_usb_firmware_finish(fw, context);
return;
}
if (aru->req_one_stage_fw) {
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found and is required for this device\n");
ar9170_usb_firmware_failed(aru);
return;
}
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found, trying old firmware...\n");
err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
&aru->udev->dev, GFP_KERNEL, aru,
ar9170_usb_firmware_inits);
if (err)
ar9170_usb_firmware_failed(aru);
}
static bool ar9170_requires_one_stage(const struct usb_device_id *id) static bool ar9170_requires_one_stage(const struct usb_device_id *id)
{ {
if (!id->driver_info) if (!id->driver_info)
@ -814,33 +874,9 @@ static int ar9170_usb_probe(struct usb_interface *intf,
if (err) if (err)
goto err_freehw; goto err_freehw;
err = ar9170_usb_request_firmware(aru); return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
if (err) &aru->udev->dev, GFP_KERNEL, aru,
goto err_freehw; ar9170_usb_firmware_step2);
err = ar9170_usb_init_device(aru);
if (err)
goto err_freefw;
err = ar9170_usb_open(ar);
if (err)
goto err_unrx;
err = ar9170_register(ar, &udev->dev);
ar9170_usb_stop(ar);
if (err)
goto err_unrx;
return 0;
err_unrx:
ar9170_usb_cancel_urbs(aru);
err_freefw:
release_firmware(aru->init_values);
release_firmware(aru->firmware);
err_freehw: err_freehw:
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
usb_put_dev(udev); usb_put_dev(udev);
@ -860,12 +896,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
ar9170_unregister(&aru->common); ar9170_unregister(&aru->common);
ar9170_usb_cancel_urbs(aru); ar9170_usb_cancel_urbs(aru);
release_firmware(aru->init_values);
release_firmware(aru->firmware);
usb_put_dev(aru->udev); usb_put_dev(aru->udev);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
ieee80211_free_hw(aru->common.hw); ieee80211_free_hw(aru->common.hw);
release_firmware(aru->init_values);
release_firmware(aru->firmware);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM

View file

@ -429,8 +429,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
AR5K_EEPROM_READ(o++, val); AR5K_EEPROM_READ(o++, val);
ee->ee_i_cal[mode] = (val >> 8) & 0x3f; ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
ee->ee_q_cal[mode] = (val >> 3) & 0x1f; ee->ee_q_cal[mode] = val & 0x1f;
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
AR5K_EEPROM_READ(o++, val); AR5K_EEPROM_READ(o++, val);

View file

@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
goto done; goto done;
/* Calibration has finished, get the results and re-run */ /* Calibration has finished, get the results and re-run */
/* work around empty results which can apparently happen on 5212 */
for (i = 0; i <= 10; i++) { for (i = 0; i <= 10; i++) {
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
"iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
if (i_pwr && q_pwr)
break;
} }
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
q_coffd = q_pwr >> 7; q_coffd = q_pwr >> 7;
/* No correction */ /* protect against divide by 0 and loss of sign bits */
if (i_coffd == 0 || q_coffd == 0) if (i_coffd == 0 || q_coffd < 2)
goto done; goto done;
i_coff = ((-iq_corr) / i_coffd); i_coff = (-iq_corr) / i_coffd;
i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
/* Boundary check */ q_coff = (i_pwr / q_coffd) - 128;
if (i_coff > 31) q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
i_coff = 31;
if (i_coff < -32)
i_coff = -32;
q_coff = (((s32)i_pwr / q_coffd) - 128); ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
"new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
i_coff, q_coff, i_coffd, q_coffd);
/* Boundary check */ /* Commit new I/Q values (set enable bit last to match HAL sources) */
if (q_coff > 15) AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
q_coff = 15; AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
if (q_coff < -16) AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
q_coff = -16;
/* Commit new I/Q value */
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
/* Re-enable calibration -if we don't we'll commit /* Re-enable calibration -if we don't we'll commit
* the same values again and again */ * the same values again and again */
@ -1873,7 +1874,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break; break;
case AR5K_ANTMODE_FIXED_A: case AR5K_ANTMODE_FIXED_A:
def_ant = 1; def_ant = 1;
tx_ant = 0; tx_ant = 1;
use_def_for_tx = true; use_def_for_tx = true;
update_def_on_tx = false; update_def_on_tx = false;
use_def_for_rts = true; use_def_for_rts = true;
@ -1882,7 +1883,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break; break;
case AR5K_ANTMODE_FIXED_B: case AR5K_ANTMODE_FIXED_B:
def_ant = 2; def_ant = 2;
tx_ant = 0; tx_ant = 2;
use_def_for_tx = true; use_def_for_tx = true;
update_def_on_tx = false; update_def_on_tx = false;
use_def_for_rts = true; use_def_for_rts = true;

View file

@ -2187,6 +2187,7 @@
*/ */
#define AR5K_PHY_IQ 0x9920 /* Register Address */ #define AR5K_PHY_IQ 0x9920 /* Register Address */
#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0
#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */

View file

@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
AR5K_INIT_CYCRSSI_THR1); AR5K_INIT_CYCRSSI_THR1);
/* I/Q correction /* I/Q correction (set enable bit last to match HAL sources) */
* TODO: Per channel i/q infos ? */ /* TODO: Per channel i/q infos ? */
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
AR5K_PHY_IQ_CORR_ENABLE | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
(ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | ee->ee_i_cal[ee_mode]);
ee->ee_q_cal[ee_mode]); AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
ee->ee_q_cal[ee_mode]);
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
}
/* Heavy clipping -disable for now */ /* Heavy clipping -disable for now */
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@ -1379,11 +1382,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_set_sleep_clock(ah, true); ath5k_hw_set_sleep_clock(ah, true);
/* /*
* Disable beacons and reset the register * Disable beacons and reset the TSF
*/ */
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
AR5K_BEACON_RESET_TSF); ath5k_hw_reset_tsf(ah);
return 0; return 0;
} }

View file

@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_sta *sta, void *priv_sta,
u32 changed) u32 changed, enum nl80211_channel_type oper_chan_type)
{ {
struct ath_softc *sc = priv; struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta; struct ath_rate_priv *ath_rc_priv = priv_sta;
@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
return; return;
if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) oper_chan_type == NL80211_CHAN_HT40PLUS)
oper_cw40 = true; oper_cw40 = true;
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?

View file

@ -2258,7 +2258,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
if (ATH_TXQ_SETUP(sc, i)) { if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i]; txq = &sc->tx.txq[i];
spin_lock(&txq->axq_lock); spin_lock_bh(&txq->axq_lock);
list_for_each_entry_safe(ac, list_for_each_entry_safe(ac,
ac_tmp, &txq->axq_acq, list) { ac_tmp, &txq->axq_acq, list) {
@ -2279,7 +2279,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
} }
} }
spin_unlock(&txq->axq_lock); spin_unlock_bh(&txq->axq_lock);
} }
} }
} }

View file

@ -3177,14 +3177,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
int total_nr = 0; int total_nr = 0;
int i; int i;
struct pci_pool *pool; struct pci_pool *pool;
u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; void **virts;
dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; dma_addr_t *phys;
IPW_DEBUG_TRACE("<< : \n"); IPW_DEBUG_TRACE("<< : \n");
virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
GFP_KERNEL);
if (!virts)
return -ENOMEM;
phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
GFP_KERNEL);
if (!phys) {
kfree(virts);
return -ENOMEM;
}
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
if (!pool) { if (!pool) {
IPW_ERROR("pci_pool_create failed\n"); IPW_ERROR("pci_pool_create failed\n");
kfree(phys);
kfree(virts);
return -ENOMEM; return -ENOMEM;
} }
@ -3254,6 +3267,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
pci_pool_free(pool, virts[i], phys[i]); pci_pool_free(pool, virts[i], phys[i]);
pci_pool_destroy(pool); pci_pool_destroy(pool);
kfree(phys);
kfree(virts);
return ret; return ret;
} }

View file

@ -797,7 +797,7 @@ struct libipw_device {
/* Probe / Beacon management */ /* Probe / Beacon management */
struct list_head network_free_list; struct list_head network_free_list;
struct list_head network_list; struct list_head network_list;
struct libipw_network *networks; struct libipw_network *networks[MAX_NETWORK_COUNT];
int scans; int scans;
int scan_age; int scan_age;

View file

@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
static int libipw_networks_allocate(struct libipw_device *ieee) static int libipw_networks_allocate(struct libipw_device *ieee)
{ {
if (ieee->networks) int i, j;
return 0;
ieee->networks = for (i = 0; i < MAX_NETWORK_COUNT; i++) {
kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
GFP_KERNEL); GFP_KERNEL);
if (!ieee->networks) { if (!ieee->networks[i]) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n", LIBIPW_ERROR("Out of memory allocating beacons\n");
ieee->dev->name); for (j = 0; j < i; j++)
return -ENOMEM; kfree(ieee->networks[j]);
return -ENOMEM;
}
} }
return 0; return 0;
@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
{ {
int i; int i;
if (!ieee->networks) for (i = 0; i < MAX_NETWORK_COUNT; i++) {
return; if (ieee->networks[i]->ibss_dfs)
kfree(ieee->networks[i]->ibss_dfs);
for (i = 0; i < MAX_NETWORK_COUNT; i++) kfree(ieee->networks[i]);
if (ieee->networks[i].ibss_dfs) }
kfree(ieee->networks[i].ibss_dfs);
kfree(ieee->networks);
ieee->networks = NULL;
} }
void libipw_networks_age(struct libipw_device *ieee, void libipw_networks_age(struct libipw_device *ieee,
@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
INIT_LIST_HEAD(&ieee->network_free_list); INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list); INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++) for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list, list_add_tail(&ieee->networks[i]->list,
&ieee->network_free_list); &ieee->network_free_list);
} }

View file

@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
{ {
int idx; int idx;
for (idx = 0; idx < IWL_RATE_COUNT; idx++) for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
if (iwl3945_rates[idx].plcp == plcp) if (iwl3945_rates[idx].plcp == plcp)
return idx; return idx;
return -1; return -1;
@ -805,7 +805,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
int sta_id, int tx_id) int sta_id, int tx_id)
{ {
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
u16 rate_mask; u16 rate_mask;
int rate; int rate;
u8 rts_retry_limit; u8 rts_retry_limit;
@ -2146,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
/* fill in channel group's nominal powers for each rate */ /* fill in channel group's nominal powers for each rate */
for (rate_index = 0; for (rate_index = 0;
rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
switch (rate_index) { switch (rate_index) {
case IWL_RATE_36M_INDEX_TABLE: case IWL_RATE_36M_INDEX_TABLE:
if (i == 0) /* B/G */ if (i == 0) /* B/G */

View file

@ -1463,59 +1463,66 @@ static void iwl_nic_start(struct iwl_priv *priv)
} }
/** static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
* iwl_read_ucode - Read uCode images from disk file. static int iwl_mac_setup_register(struct iwl_priv *priv);
*
* Copy into buffers for card to fetch via bus-mastering static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
*/
static int iwl_read_ucode(struct iwl_priv *priv)
{ {
struct iwl_ucode_header *ucode;
int ret = -EINVAL, index;
const struct firmware *ucode_raw;
const char *name_pre = priv->cfg->fw_name_pre; const char *name_pre = priv->cfg->fw_name_pre;
if (first)
priv->fw_index = priv->cfg->ucode_api_max;
else
priv->fw_index--;
if (priv->fw_index < priv->cfg->ucode_api_min) {
IWL_ERR(priv, "no suitable firmware found!\n");
return -ENOENT;
}
sprintf(priv->firmware_name, "%s%d%s",
name_pre, priv->fw_index, ".ucode");
IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
priv->firmware_name);
return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
&priv->pci_dev->dev, GFP_KERNEL, priv,
iwl_ucode_callback);
}
/**
* iwl_ucode_callback - callback when firmware was loaded
*
* If loaded successfully, copies the firmware into buffers
* for the card to fetch (via DMA).
*/
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
{
struct iwl_priv *priv = context;
struct iwl_ucode_header *ucode;
const unsigned int api_max = priv->cfg->ucode_api_max; const unsigned int api_max = priv->cfg->ucode_api_max;
const unsigned int api_min = priv->cfg->ucode_api_min; const unsigned int api_min = priv->cfg->ucode_api_min;
char buf[25];
u8 *src; u8 *src;
size_t len; size_t len;
u32 api_ver, build; u32 api_ver, build;
u32 inst_size, data_size, init_size, init_data_size, boot_size; u32 inst_size, data_size, init_size, init_data_size, boot_size;
int err;
u16 eeprom_ver; u16 eeprom_ver;
/* Ask kernel firmware_class module to get the boot firmware off disk. if (!ucode_raw) {
* request_firmware() is synchronous, file is in memory on return. */ IWL_ERR(priv, "request for firmware file '%s' failed.\n",
for (index = api_max; index >= api_min; index--) { priv->firmware_name);
sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); goto try_again;
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
else
goto error;
} else {
if (index < api_max)
IWL_ERR(priv, "Loaded firmware %s, "
"which is deprecated. "
"Please use API v%u instead.\n",
buf, api_max);
IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
}
} }
if (ret < 0) IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
goto error; priv->firmware_name, ucode_raw->size);
/* Make sure that we got at least the v1 header! */ /* Make sure that we got at least the v1 header! */
if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
IWL_ERR(priv, "File size way too small!\n"); IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL; goto try_again;
goto err_release;
} }
/* Data from ucode file: header followed by uCode images */ /* Data from ucode file: header followed by uCode images */
@ -1540,10 +1547,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_ERR(priv, "Driver unable to support your firmware API. " IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n", "Driver supports v%u, firmware is v%u.\n",
api_max, api_ver); api_max, api_ver);
priv->ucode_ver = 0; goto try_again;
ret = -EINVAL;
goto err_release;
} }
if (api_ver != api_max) if (api_ver != api_max)
IWL_ERR(priv, "Firmware has old API version. Expected v%u, " IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
"got v%u. New firmware can be obtained " "got v%u. New firmware can be obtained "
@ -1585,6 +1591,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
boot_size); boot_size);
/*
* For any of the failures below (before allocating pci memory)
* we will try to load a version with a smaller API -- maybe the
* user just got a corrupted version of the latest API.
*/
/* Verify size of file vs. image size info in file's header */ /* Verify size of file vs. image size info in file's header */
if (ucode_raw->size != if (ucode_raw->size !=
priv->cfg->ops->ucode->get_header_size(api_ver) + priv->cfg->ops->ucode->get_header_size(api_ver) +
@ -1594,41 +1606,35 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, IWL_DEBUG_INFO(priv,
"uCode file size %d does not match expected size\n", "uCode file size %d does not match expected size\n",
(int)ucode_raw->size); (int)ucode_raw->size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
/* Verify that uCode images will fit in card's SRAM */ /* Verify that uCode images will fit in card's SRAM */
if (inst_size > priv->hw_params.max_inst_size) { if (inst_size > priv->hw_params.max_inst_size) {
IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size); inst_size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
if (data_size > priv->hw_params.max_data_size) { if (data_size > priv->hw_params.max_data_size) {
IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size); data_size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
if (init_size > priv->hw_params.max_inst_size) { if (init_size > priv->hw_params.max_inst_size) {
IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
init_size); init_size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
if (init_data_size > priv->hw_params.max_data_size) { if (init_data_size > priv->hw_params.max_data_size) {
IWL_INFO(priv, "uCode init data len %d too large to fit in\n", IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
init_data_size); init_data_size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
if (boot_size > priv->hw_params.max_bsm_size) { if (boot_size > priv->hw_params.max_bsm_size) {
IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
boot_size); boot_size);
ret = -EINVAL; goto try_again;
goto err_release;
} }
/* Allocate ucode buffers for card's bus-master loading ... */ /* Allocate ucode buffers for card's bus-master loading ... */
@ -1712,20 +1718,36 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len); memcpy(priv->ucode_boot.v_addr, src, len);
/**************************************************
* This is still part of probe() in a sense...
*
* 9. Setup and register with mac80211 and debugfs
**************************************************/
err = iwl_mac_setup_register(priv);
if (err)
goto out_unbind;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* We have our copies now, allow OS release its copies */ /* We have our copies now, allow OS release its copies */
release_firmware(ucode_raw); release_firmware(ucode_raw);
return 0; return;
try_again:
/* try next, if any */
if (iwl_request_firmware(priv, false))
goto out_unbind;
release_firmware(ucode_raw);
return;
err_pci_alloc: err_pci_alloc:
IWL_ERR(priv, "failed to allocate pci memory\n"); IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl_dealloc_ucode_pci(priv); iwl_dealloc_ucode_pci(priv);
out_unbind:
err_release: device_release_driver(&priv->pci_dev->dev);
release_firmware(ucode_raw); release_firmware(ucode_raw);
error:
return ret;
} }
static const char *desc_lookup_text[] = { static const char *desc_lookup_text[] = {
@ -2631,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
*/ */
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
/* we create the 802.11 header and a zero-length SSID element */ /* we create the 802.11 header and a zero-length SSID element */
hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
@ -2667,21 +2689,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
/* we should be verifying the device is ready to be opened */ /* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
if (!priv->ucode_code.len) {
ret = iwl_read_ucode(priv);
if (ret) {
IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
return ret;
}
}
ret = __iwl_up(priv); ret = __iwl_up(priv);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
if (ret) if (ret)
@ -3654,17 +3662,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_power_initialize(priv); iwl_power_initialize(priv);
iwl_tt_initialize(priv); iwl_tt_initialize(priv);
/************************************************** err = iwl_request_firmware(priv, true);
* 9. Setup and register with mac80211 and debugfs
**************************************************/
err = iwl_mac_setup_register(priv);
if (err) if (err)
goto out_remove_sysfs; goto out_remove_sysfs;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
return 0; return 0;
out_remove_sysfs: out_remove_sysfs:

View file

@ -1132,6 +1132,7 @@ struct iwl_priv {
u8 rev_id; u8 rev_id;
/* uCode images, save to reload in case of failure */ /* uCode images, save to reload in case of failure */
int fw_index; /* firmware we're trying to load */
u32 ucode_ver; /* version of ucode, copy of u32 ucode_ver; /* version of ucode, copy of
iwl_ucode.ver */ iwl_ucode.ver */
struct fw_desc ucode_code; /* runtime inst */ struct fw_desc ucode_code; /* runtime inst */
@ -1142,6 +1143,7 @@ struct iwl_priv {
struct fw_desc ucode_boot; /* bootstrap inst */ struct fw_desc ucode_boot; /* bootstrap inst */
enum ucode_type ucode_type; enum ucode_type ucode_type;
u8 ucode_write_complete; /* the image write is complete */ u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
struct iwl_rxon_time_cmd rxon_timing; struct iwl_rxon_time_cmd rxon_timing;

View file

@ -638,20 +638,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
if (left < 0) if (left < 0)
return 0; return 0;
*pos++ = WLAN_EID_SSID; *pos++ = WLAN_EID_SSID;
if (!priv->is_internal_short_scan && *pos++ = 0;
priv->scan_request->n_ssids) {
struct cfg80211_ssid *ssid =
priv->scan_request->ssids;
/* Broadcast if ssid_len is 0 */ len += 2;
*pos++ = ssid->ssid_len;
memcpy(pos, ssid->ssid, ssid->ssid_len);
pos += ssid->ssid_len;
len += 2 + ssid->ssid_len;
} else {
*pos++ = 0;
len += 2;
}
if (WARN_ON(left < ie_len)) if (WARN_ON(left < ie_len))
return len; return len;
@ -780,26 +769,20 @@ static void iwl_bg_request_scan(struct work_struct *data)
if (priv->is_internal_short_scan) { if (priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
} else if (priv->scan_request->n_ssids) { } else if (priv->scan_request->n_ssids) {
int i, p = 0;
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
/* for (i = 0; i < priv->scan_request->n_ssids; i++) {
* The first SSID to scan is stuffed into the probe request /* always does wildcard anyway */
* template and the remaining ones are handled through the if (!priv->scan_request->ssids[i].ssid_len)
* direct_scan array. continue;
*/ scan->direct_scan[p].id = WLAN_EID_SSID;
if (priv->scan_request->n_ssids > 1) { scan->direct_scan[p].len =
int i, p = 0; priv->scan_request->ssids[i].ssid_len;
for (i = 1; i < priv->scan_request->n_ssids; i++) { memcpy(scan->direct_scan[p].ssid,
if (!priv->scan_request->ssids[i].ssid_len) priv->scan_request->ssids[i].ssid,
continue; priv->scan_request->ssids[i].ssid_len);
scan->direct_scan[p].id = WLAN_EID_SSID; n_probes++;
scan->direct_scan[p].len = p++;
priv->scan_request->ssids[i].ssid_len;
memcpy(scan->direct_scan[p].ssid,
priv->scan_request->ssids[i].ssid,
priv->scan_request->ssids[i].ssid_len);
n_probes++;
p++;
}
} }
is_active = true; is_active = true;
} else } else

View file

@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev)
{ {
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct dev_mc_list *mclist; struct dev_mc_list *mclist;
__le32 filter; __le32 filter, basefilter;
int ret, i, size; int ret;
char *buf; char *mc_addrs = NULL;
int mc_count;
filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
RNDIS_PACKET_TYPE_BROADCAST;
netif_addr_lock_bh(usbdev->net);
if (usbdev->net->flags & IFF_PROMISC) { if (usbdev->net->flags & IFF_PROMISC) {
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
RNDIS_PACKET_TYPE_ALL_LOCAL; RNDIS_PACKET_TYPE_ALL_LOCAL;
} else if (usbdev->net->flags & IFF_ALLMULTI || } else if (usbdev->net->flags & IFF_ALLMULTI) {
netdev_mc_count(usbdev->net) > priv->multicast_size) {
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
} else if (!netdev_mc_empty(usbdev->net)) { }
size = min(priv->multicast_size, netdev_mc_count(usbdev->net));
buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); if (filter != basefilter)
if (!buf) { goto set_filter;
/*
* mc_list should be accessed holding the lock, so copy addresses to
* local buffer first.
*/
netif_addr_lock_bh(usbdev->net);
mc_count = netdev_mc_count(usbdev->net);
if (mc_count > priv->multicast_size) {
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
} else if (mc_count) {
int i = 0;
mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
if (!mc_addrs) {
netdev_warn(usbdev->net, netdev_warn(usbdev->net,
"couldn't alloc %d bytes of memory\n", "couldn't alloc %d bytes of memory\n",
size * ETH_ALEN); mc_count * ETH_ALEN);
netif_addr_unlock_bh(usbdev->net); netif_addr_unlock_bh(usbdev->net);
return; return;
} }
i = 0; netdev_for_each_mc_addr(mclist, usbdev->net)
netdev_for_each_mc_addr(mclist, usbdev->net) { memcpy(mc_addrs + i++ * ETH_ALEN,
if (i == size) mclist->dmi_addr, ETH_ALEN);
break; }
memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); netif_addr_unlock_bh(usbdev->net);
}
ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, if (filter != basefilter)
i * ETH_ALEN); goto set_filter;
if (ret == 0 && i > 0)
if (mc_count) {
ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
mc_count * ETH_ALEN);
kfree(mc_addrs);
if (ret == 0)
filter |= RNDIS_PACKET_TYPE_MULTICAST; filter |= RNDIS_PACKET_TYPE_MULTICAST;
else else
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
i, priv->multicast_size, ret); mc_count, priv->multicast_size, ret);
kfree(buf);
} }
netif_addr_unlock_bh(usbdev->net);
set_filter:
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter)); sizeof(filter));
if (ret < 0) { if (ret < 0) {

View file

@ -1225,7 +1225,7 @@ MODULE_LICENSE("GPL");
#ifdef CONFIG_RT2800PCI_SOC #ifdef CONFIG_RT2800PCI_SOC
static int rt2800soc_probe(struct platform_device *pdev) static int rt2800soc_probe(struct platform_device *pdev)
{ {
return rt2x00soc_probe(pdev, rt2800pci_ops); return rt2x00soc_probe(pdev, &rt2800pci_ops);
} }
static struct platform_driver rt2800soc_driver = { static struct platform_driver rt2800soc_driver = {

View file

@ -112,6 +112,7 @@ exit_free_device:
return retval; return retval;
} }
EXPORT_SYMBOL_GPL(rt2x00soc_probe);
int rt2x00soc_remove(struct platform_device *pdev) int rt2x00soc_remove(struct platform_device *pdev)
{ {

View file

@ -26,8 +26,6 @@
#ifndef RT2X00SOC_H #ifndef RT2X00SOC_H
#define RT2X00SOC_H #define RT2X00SOC_H
#define KSEG1ADDR(__ptr) __ptr
/* /*
* SoC driver handlers. * SoC driver handlers.
*/ */

View file

@ -2352,6 +2352,8 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
/* CEIVA */
{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
/* CNet */ /* CNet */
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },

View file

@ -350,7 +350,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
first_idx = info->status.rates[0].idx; first_idx = info->status.rates[0].idx;
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
retries = &zd_retry_rates[first_idx]; retries = &zd_retry_rates[first_idx];
ZD_ASSERT(0<=retry && retry<=retries->count); ZD_ASSERT(1 <= retry && retry <= retries->count);
info->status.rates[0].idx = retries->rate[0]; info->status.rates[0].idx = retries->rate[0];
info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
@ -360,7 +360,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
} }
for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) { for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
info->status.rates[i].idx = retries->rate[retry-1]; info->status.rates[i].idx = retries->rate[retry - 1];
info->status.rates[i].count = 1; // (success ? 1:2); info->status.rates[i].count = 1; // (success ? 1:2);
} }
if (i<IEEE80211_TX_MAX_RATES) if (i<IEEE80211_TX_MAX_RATES)
@ -424,12 +424,10 @@ void zd_mac_tx_failed(struct urb *urb)
first_idx = info->status.rates[0].idx; first_idx = info->status.rates[0].idx;
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
retries = &zd_retry_rates[first_idx]; retries = &zd_retry_rates[first_idx];
if (retry < 0 || retry > retries->count) { if (retry <= 0 || retry > retries->count)
continue; continue;
}
ZD_ASSERT(0<=retry && retry<=retries->count); final_idx = retries->rate[retry - 1];
final_idx = retries->rate[retry-1];
final_rate = zd_rates[final_idx].hw_value; final_rate = zd_rates[final_idx].hw_value;
if (final_rate != tx_status->rate) { if (final_rate != tx_status->rate) {

View file

@ -763,7 +763,8 @@ static inline int qeth_get_micros(void)
static inline int qeth_get_ip_version(struct sk_buff *skb) static inline int qeth_get_ip_version(struct sk_buff *skb)
{ {
switch (skb->protocol) { struct ethhdr *ehdr = (struct ethhdr *)skb->data;
switch (ehdr->h_proto) {
case ETH_P_IPV6: case ETH_P_IPV6:
return 6; return 6;
case ETH_P_IP: case ETH_P_IP:

View file

@ -537,7 +537,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
dev_err(&card->gdev->dev, dev_err(&card->gdev->dev,
"The qeth device is not configured " "The qeth device is not configured "
"for the OSI layer required by z/VM\n"); "for the OSI layer required by z/VM\n");
qeth_schedule_recovery(card); else
qeth_schedule_recovery(card);
goto out; goto out;
} }
@ -1113,8 +1114,6 @@ static int qeth_setup_card(struct qeth_card *card)
card->ipato.enabled = 0; card->ipato.enabled = 0;
card->ipato.invert4 = 0; card->ipato.invert4 = 0;
card->ipato.invert6 = 0; card->ipato.invert6 = 0;
if (card->info.type == QETH_CARD_TYPE_IQD)
card->options.checksum_type = NO_CHECKSUMMING;
/* init QDIO stuff */ /* init QDIO stuff */
qeth_init_qdio_info(card); qeth_init_qdio_info(card);
return 0; return 0;

View file

@ -8,6 +8,9 @@
* Frank Blaschka <frank.blaschka@de.ibm.com> * Frank Blaschka <frank.blaschka@de.ibm.com>
*/ */
#define KMSG_COMPONENT "qeth"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/list.h> #include <linux/list.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <asm/ebcdic.h> #include <asm/ebcdic.h>

View file

@ -1071,11 +1071,9 @@ static int qeth_l2_recover(void *ptr)
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"Device successfully recovered!\n"); "Device successfully recovered!\n");
else { else {
if (card->dev) { rtnl_lock();
rtnl_lock(); dev_close(card->dev);
dev_close(card->dev); rtnl_unlock();
rtnl_unlock();
}
dev_warn(&card->gdev->dev, "The qeth device driver " dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n"); "failed to recover an error on the device\n");
} }
@ -1129,11 +1127,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
if (card->state == CARD_STATE_RECOVER) { if (card->state == CARD_STATE_RECOVER) {
rc = __qeth_l2_set_online(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1);
if (rc) { if (rc) {
if (card->dev) { rtnl_lock();
rtnl_lock(); dev_close(card->dev);
dev_close(card->dev); rtnl_unlock();
rtnl_unlock();
}
} }
} else } else
rc = __qeth_l2_set_online(card->gdev, 0); rc = __qeth_l2_set_online(card->gdev, 0);

View file

@ -1691,39 +1691,43 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
cmd = (struct qeth_ipa_cmd *)data; cmd = (struct qeth_ipa_cmd *)data;
rc = cmd->hdr.return_code; rc = cmd->hdr.return_code;
if (rc) { if (rc)
QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc); QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
switch (rc) {
case IPA_RC_HARDWARE_AUTH_ERROR:
dev_warn(&card->gdev->dev, "The device is not "
"authorized to run as a HiperSockets "
"network traffic analyzer\n");
break;
case IPA_RC_TRACE_ALREADY_ACTIVE:
dev_warn(&card->gdev->dev, "A HiperSockets "
"network traffic analyzer is already "
"active in the HiperSockets LAN\n");
break;
default:
break;
}
}
return 0;
}
switch (cmd->data.diagass.action) { switch (cmd->data.diagass.action) {
case QETH_DIAGS_CMD_TRACE_QUERY: case QETH_DIAGS_CMD_TRACE_QUERY:
break; break;
case QETH_DIAGS_CMD_TRACE_DISABLE: case QETH_DIAGS_CMD_TRACE_DISABLE:
card->info.promisc_mode = SET_PROMISC_MODE_OFF; switch (rc) {
dev_info(&card->gdev->dev, "The HiperSockets network traffic " case 0:
"analyzer is deactivated\n"); case IPA_RC_INVALID_SUBCMD:
card->info.promisc_mode = SET_PROMISC_MODE_OFF;
dev_info(&card->gdev->dev, "The HiperSockets network "
"traffic analyzer is deactivated\n");
break;
default:
break;
}
break; break;
case QETH_DIAGS_CMD_TRACE_ENABLE: case QETH_DIAGS_CMD_TRACE_ENABLE:
card->info.promisc_mode = SET_PROMISC_MODE_ON; switch (rc) {
dev_info(&card->gdev->dev, "The HiperSockets network traffic " case 0:
"analyzer is activated\n"); card->info.promisc_mode = SET_PROMISC_MODE_ON;
dev_info(&card->gdev->dev, "The HiperSockets network "
"traffic analyzer is activated\n");
break;
case IPA_RC_HARDWARE_AUTH_ERROR:
dev_warn(&card->gdev->dev, "The device is not "
"authorized to run as a HiperSockets network "
"traffic analyzer\n");
break;
case IPA_RC_TRACE_ALREADY_ACTIVE:
dev_warn(&card->gdev->dev, "A HiperSockets "
"network traffic analyzer is already "
"active in the HiperSockets LAN\n");
break;
default:
break;
}
break; break;
default: default:
QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n", QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
@ -2215,11 +2219,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
if (recovery_mode) if (recovery_mode)
qeth_l3_stop(card->dev); qeth_l3_stop(card->dev);
else { else {
if (card->dev) { rtnl_lock();
rtnl_lock(); dev_close(card->dev);
dev_close(card->dev); rtnl_unlock();
rtnl_unlock();
}
} }
if (!card->use_hard_stop) { if (!card->use_hard_stop) {
rc = qeth_send_stoplan(card); rc = qeth_send_stoplan(card);
@ -2900,10 +2902,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
int data_offset = -1; int data_offset = -1;
int nr_frags; int nr_frags;
if ((card->info.type == QETH_CARD_TYPE_IQD) && if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
(((skb->protocol != htons(ETH_P_IPV6)) && card->options.sniffer)
(skb->protocol != htons(ETH_P_IP))) ||
card->options.sniffer))
goto tx_drop; goto tx_drop;
if ((card->state != CARD_STATE_UP) || !card->lan_online) { if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@ -2949,14 +2949,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (data_offset < 0) if (data_offset < 0)
skb_pull(new_skb, ETH_HLEN); skb_pull(new_skb, ETH_HLEN);
} else { } else {
if (new_skb->protocol == htons(ETH_P_IP)) { if (ipv == 4) {
if (card->dev->type == ARPHRD_IEEE802_TR) if (card->dev->type == ARPHRD_IEEE802_TR)
skb_pull(new_skb, TR_HLEN); skb_pull(new_skb, TR_HLEN);
else else
skb_pull(new_skb, ETH_HLEN); skb_pull(new_skb, ETH_HLEN);
} }
if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp && if (ipv == 6 && card->vlangrp &&
vlan_tx_tag_present(new_skb)) { vlan_tx_tag_present(new_skb)) {
skb_push(new_skb, VLAN_HLEN); skb_push(new_skb, VLAN_HLEN);
skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
@ -3534,11 +3534,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
if (card->state == CARD_STATE_RECOVER) { if (card->state == CARD_STATE_RECOVER) {
rc = __qeth_l3_set_online(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1);
if (rc) { if (rc) {
if (card->dev) { rtnl_lock();
rtnl_lock(); dev_close(card->dev);
dev_close(card->dev); rtnl_unlock();
rtnl_unlock();
}
} }
} else } else
rc = __qeth_l3_set_online(card->gdev, 0); rc = __qeth_l3_set_online(card->gdev, 0);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -61,6 +61,13 @@ struct ethtool_drvinfo {
/* For PCI devices, use pci_name(pci_dev). */ /* For PCI devices, use pci_name(pci_dev). */
char reserved1[32]; char reserved1[32];
char reserved2[12]; char reserved2[12];
/*
* Some struct members below are filled in
* using ops->get_sset_count(). Obtaining
* this info from ethtool_drvinfo is now
* deprecated; Use ETHTOOL_GSSET_INFO
* instead.
*/
__u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */ __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
__u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
__u32 testinfo_len; __u32 testinfo_len;
@ -253,6 +260,17 @@ struct ethtool_gstrings {
__u8 data[0]; __u8 data[0];
}; };
struct ethtool_sset_info {
__u32 cmd; /* ETHTOOL_GSSET_INFO */
__u32 reserved;
__u64 sset_mask; /* input: each bit selects an sset to query */
/* output: each bit a returned sset */
__u32 data[0]; /* ETH_SS_xxx count, in order, based on bits
in sset_mask. One bit implies one
__u32, two bits implies two
__u32's, etc. */
};
enum ethtool_test_flags { enum ethtool_test_flags {
ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */ ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */ ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */
@ -606,9 +624,9 @@ struct ethtool_ops {
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ #define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
#define ETHTOOL_RESET 0x00000034 /* Reset hardware */ #define ETHTOOL_RESET 0x00000034 /* Reset hardware */
#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */ #define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */ #define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
/* compatibility with older code */ /* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET #define SPARC_ETH_GSET ETHTOOL_GSET

View file

@ -29,7 +29,7 @@
/** /**
* enum rfkill_type - type of rfkill switch. * enum rfkill_type - type of rfkill switch.
* *
* @RFKILL_TYPE_ALL: toggles all switches (userspace only) * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
* @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
* @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
* @RFKILL_TYPE_UWB: switch is on a ultra wideband device. * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.

View file

@ -225,6 +225,8 @@ enum
LINUX_MIB_SACKSHIFTED, LINUX_MIB_SACKSHIFTED,
LINUX_MIB_SACKMERGED, LINUX_MIB_SACKMERGED,
LINUX_MIB_SACKSHIFTFALLBACK, LINUX_MIB_SACKSHIFTFALLBACK,
LINUX_MIB_TCPBACKLOGDROP,
LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
__LINUX_MIB_MAX __LINUX_MIB_MAX
}; };

View file

@ -37,6 +37,24 @@ struct route_info {
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
/*
* rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
* between IPV6_ADDR_PREFERENCES socket option values
* IPV6_PREFER_SRC_TMP = 0x1
* IPV6_PREFER_SRC_PUBLIC = 0x2
* IPV6_PREFER_SRC_COA = 0x4
* and above RT6_LOOKUP_F_SRCPREF_xxx flags.
*/
static inline int rt6_srcprefs2flags(unsigned int srcprefs)
{
/* No need to bitmask because srcprefs have only 3 bits. */
return srcprefs << 3;
}
static inline unsigned int rt6_flags2srcprefs(int flags)
{
return (flags >> 3) & 7;
}
extern void ip6_route_input(struct sk_buff *skb); extern void ip6_route_input(struct sk_buff *skb);

View file

@ -15,7 +15,6 @@
struct ip6_tnl { struct ip6_tnl {
struct ip6_tnl *next; /* next tunnel in list */ struct ip6_tnl *next; /* next tunnel in list */
struct net_device *dev; /* virtual device associated with tunnel */ struct net_device *dev; /* virtual device associated with tunnel */
int recursion; /* depth of hard_start_xmit recursion */
struct ip6_tnl_parm parms; /* tunnel configuration parameters */ struct ip6_tnl_parm parms; /* tunnel configuration parameters */
struct flowi fl; /* flowi template for xmit */ struct flowi fl; /* flowi template for xmit */
struct dst_entry *dst_cache; /* cached dst */ struct dst_entry *dst_cache; /* cached dst */

View file

@ -2426,7 +2426,8 @@ struct rate_control_ops {
struct ieee80211_sta *sta, void *priv_sta); struct ieee80211_sta *sta, void *priv_sta);
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband, void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
void *priv_sta, u32 changed); void *priv_sta, u32 changed,
enum nl80211_channel_type oper_chan_type);
void (*free_sta)(void *priv, struct ieee80211_sta *sta, void (*free_sta)(void *priv, struct ieee80211_sta *sta,
void *priv_sta); void *priv_sta);

View file

@ -253,6 +253,8 @@ struct sock {
struct { struct {
struct sk_buff *head; struct sk_buff *head;
struct sk_buff *tail; struct sk_buff *tail;
int len;
int limit;
} sk_backlog; } sk_backlog;
wait_queue_head_t *sk_sleep; wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache; struct dst_entry *sk_dst_cache;
@ -589,8 +591,8 @@ static inline int sk_stream_memory_free(struct sock *sk)
return sk->sk_wmem_queued < sk->sk_sndbuf; return sk->sk_wmem_queued < sk->sk_sndbuf;
} }
/* The per-socket spinlock must be held here. */ /* OOB backlog add */
static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
{ {
if (!sk->sk_backlog.tail) { if (!sk->sk_backlog.tail) {
sk->sk_backlog.head = sk->sk_backlog.tail = skb; sk->sk_backlog.head = sk->sk_backlog.tail = skb;
@ -601,6 +603,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
skb->next = NULL; skb->next = NULL;
} }
/* The per-socket spinlock must be held here. */
static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
{
if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
return -ENOBUFS;
__sk_add_backlog(sk, skb);
sk->sk_backlog.len += skb->truesize;
return 0;
}
static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb) static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{ {
return sk->sk_backlog_rcv(sk, skb); return sk->sk_backlog_rcv(sk, skb);

View file

@ -939,7 +939,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
tp->ucopy.memory = 0; tp->ucopy.memory = 0;
} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
wake_up_interruptible_poll(sk->sk_sleep, wake_up_interruptible_sync_poll(sk->sk_sleep,
POLLIN | POLLRDNORM | POLLRDBAND); POLLIN | POLLRDNORM | POLLRDBAND);
if (!inet_csk_ack_scheduled(sk)) if (!inet_csk_ack_scheduled(sk))
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,

View file

@ -275,7 +275,8 @@ struct xfrm_policy_afinfo {
struct dst_entry *dst, struct dst_entry *dst,
int nfheader_len); int nfheader_len);
int (*fill_dst)(struct xfrm_dst *xdst, int (*fill_dst)(struct xfrm_dst *xdst,
struct net_device *dev); struct net_device *dev,
struct flowi *fl);
}; };
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);

View file

@ -3,6 +3,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
@ -405,20 +406,11 @@ static struct device_type bt_host = {
.release = bt_host_release, .release = bt_host_release,
}; };
static int inquiry_cache_open(struct inode *inode, struct file *file) static int inquiry_cache_show(struct seq_file *f, void *p)
{ {
file->private_data = inode->i_private; struct hci_dev *hdev = f->private;
return 0;
}
static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
struct inquiry_cache *cache = &hdev->inq_cache; struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *e; struct inquiry_entry *e;
char buf[4096];
int n = 0;
hci_dev_lock_bh(hdev); hci_dev_lock_bh(hdev);
@ -426,23 +418,30 @@ static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
struct inquiry_data *data = &e->data; struct inquiry_data *data = &e->data;
bdaddr_t bdaddr; bdaddr_t bdaddr;
baswap(&bdaddr, &data->bdaddr); baswap(&bdaddr, &data->bdaddr);
n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
batostr(&bdaddr), batostr(&bdaddr),
data->pscan_rep_mode, data->pscan_period_mode, data->pscan_rep_mode, data->pscan_period_mode,
data->pscan_mode, data->dev_class[2], data->pscan_mode, data->dev_class[2],
data->dev_class[1], data->dev_class[0], data->dev_class[1], data->dev_class[0],
__le16_to_cpu(data->clock_offset), __le16_to_cpu(data->clock_offset),
data->rssi, data->ssp_mode, e->timestamp); data->rssi, data->ssp_mode, e->timestamp);
} }
hci_dev_unlock_bh(hdev); hci_dev_unlock_bh(hdev);
return simple_read_from_buffer(userbuf, count, ppos, buf, n); return 0;
}
static int inquiry_cache_open(struct inode *inode, struct file *file)
{
return single_open(file, inquiry_cache_show, inode->i_private);
} }
static const struct file_operations inquiry_cache_fops = { static const struct file_operations inquiry_cache_fops = {
.open = inquiry_cache_open, .open = inquiry_cache_open,
.read = inquiry_cache_read, .read = seq_read,
.llseek = seq_lseek,
.release = single_release,
}; };
int hci_register_sysfs(struct hci_dev *hdev) int hci_register_sysfs(struct hci_dev *hdev)

View file

@ -35,6 +35,7 @@ config BRIDGE
config BRIDGE_IGMP_SNOOPING config BRIDGE_IGMP_SNOOPING
bool "IGMP snooping" bool "IGMP snooping"
depends on BRIDGE depends on BRIDGE
depends on INET
default y default y
---help--- ---help---
If you say Y here, then the Ethernet bridge will be able selectively If you say Y here, then the Ethernet bridge will be able selectively

View file

@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
struct net_bridge_mdb_entry *mp; struct net_bridge_mdb_entry *mp;
struct hlist_node *p; struct hlist_node *p;
hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
if (dst == mp->addr) if (dst == mp->addr)
return mp; return mp;
} }
@ -627,8 +627,8 @@ static void br_multicast_port_query_expired(unsigned long data)
struct net_bridge *br = port->br; struct net_bridge *br = port->br;
spin_lock(&br->multicast_lock); spin_lock(&br->multicast_lock);
if (port && (port->state == BR_STATE_DISABLED || if (port->state == BR_STATE_DISABLED ||
port->state == BR_STATE_BLOCKING)) port->state == BR_STATE_BLOCKING)
goto out; goto out;
if (port->multicast_startup_queries_sent < if (port->multicast_startup_queries_sent <
@ -823,6 +823,7 @@ static int br_multicast_query(struct net_bridge *br,
unsigned long max_delay; unsigned long max_delay;
unsigned long now = jiffies; unsigned long now = jiffies;
__be32 group; __be32 group;
int err = 0;
spin_lock(&br->multicast_lock); spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) || if (!netif_running(br->dev) ||
@ -841,12 +842,14 @@ static int br_multicast_query(struct net_bridge *br,
group = 0; group = 0;
} }
} else { } else {
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) {
return -EINVAL; err = -EINVAL;
goto out;
}
ih3 = igmpv3_query_hdr(skb); ih3 = igmpv3_query_hdr(skb);
if (ih3->nsrcs) if (ih3->nsrcs)
return 0; goto out;
max_delay = ih3->code ? 1 : max_delay = ih3->code ? 1 :
IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
@ -876,7 +879,7 @@ static int br_multicast_query(struct net_bridge *br,
out: out:
spin_unlock(&br->multicast_lock); spin_unlock(&br->multicast_lock);
return 0; return err;
} }
static void br_multicast_leave_group(struct net_bridge *br, static void br_multicast_leave_group(struct net_bridge *br,
@ -1135,7 +1138,7 @@ void br_multicast_stop(struct net_bridge *br)
if (mdb->old) { if (mdb->old) {
spin_unlock_bh(&br->multicast_lock); spin_unlock_bh(&br->multicast_lock);
synchronize_rcu_bh(); rcu_barrier_bh();
spin_lock_bh(&br->multicast_lock); spin_lock_bh(&br->multicast_lock);
WARN_ON(mdb->old); WARN_ON(mdb->old);
} }

View file

@ -97,8 +97,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
netif_addr_lock_bh(dev); netif_addr_lock_bh(dev);
if (alen != dev->addr_len) if (alen != dev->addr_len)
return -EINVAL; err = -EINVAL;
err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); else
err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
if (!err) if (!err)
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
netif_addr_unlock_bh(dev); netif_addr_unlock_bh(dev);

View file

@ -17,6 +17,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/bitops.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/* /*
@ -199,10 +200,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
return dev->ethtool_ops->set_settings(dev, &cmd); return dev->ethtool_ops->set_settings(dev, &cmd);
} }
/* static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_drvinfo info; struct ethtool_drvinfo info;
const struct ethtool_ops *ops = dev->ethtool_ops; const struct ethtool_ops *ops = dev->ethtool_ops;
@ -214,6 +212,10 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
info.cmd = ETHTOOL_GDRVINFO; info.cmd = ETHTOOL_GDRVINFO;
ops->get_drvinfo(dev, &info); ops->get_drvinfo(dev, &info);
/*
* this method of obtaining string set info is deprecated;
* Use ETHTOOL_GSSET_INFO instead.
*/
if (ops->get_sset_count) { if (ops->get_sset_count) {
int rc; int rc;
@ -237,10 +239,67 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
return 0; return 0;
} }
/* static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool() void __user *useraddr)
*/ {
static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) struct ethtool_sset_info info;
const struct ethtool_ops *ops = dev->ethtool_ops;
u64 sset_mask;
int i, idx = 0, n_bits = 0, ret, rc;
u32 *info_buf = NULL;
if (!ops->get_sset_count)
return -EOPNOTSUPP;
if (copy_from_user(&info, useraddr, sizeof(info)))
return -EFAULT;
/* store copy of mask, because we zero struct later on */
sset_mask = info.sset_mask;
if (!sset_mask)
return 0;
/* calculate size of return buffer */
n_bits = hweight64(sset_mask);
memset(&info, 0, sizeof(info));
info.cmd = ETHTOOL_GSSET_INFO;
info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER);
if (!info_buf)
return -ENOMEM;
/*
* fill return buffer based on input bitmask and successful
* get_sset_count return
*/
for (i = 0; i < 64; i++) {
if (!(sset_mask & (1ULL << i)))
continue;
rc = ops->get_sset_count(dev, i);
if (rc >= 0) {
info.sset_mask |= (1ULL << i);
info_buf[idx++] = rc;
}
}
ret = -EFAULT;
if (copy_to_user(useraddr, &info, sizeof(info)))
goto out;
useraddr += offsetof(struct ethtool_sset_info, data);
if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
goto out;
ret = 0;
out:
kfree(info_buf);
return ret;
}
static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_rxnfc cmd; struct ethtool_rxnfc cmd;
@ -253,10 +312,7 @@ static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *usera
return dev->ethtool_ops->set_rxnfc(dev, &cmd); return dev->ethtool_ops->set_rxnfc(dev, &cmd);
} }
/* static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_rxnfc info; struct ethtool_rxnfc info;
const struct ethtool_ops *ops = dev->ethtool_ops; const struct ethtool_ops *ops = dev->ethtool_ops;
@ -328,10 +384,7 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
list->count++; list->count++;
} }
/* static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_rx_ntuple cmd; struct ethtool_rx_ntuple cmd;
const struct ethtool_ops *ops = dev->ethtool_ops; const struct ethtool_ops *ops = dev->ethtool_ops;
@ -799,10 +852,7 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
return ret; return ret;
} }
/* static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE }; struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
@ -816,10 +866,7 @@ static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *us
return 0; return 0;
} }
/* static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_coalesce coalesce; struct ethtool_coalesce coalesce;
@ -1229,10 +1276,7 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
return actor(dev, edata.data); return actor(dev, edata.data);
} }
/* static noinline_for_stack int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
* noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
*/
static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
{ {
struct ethtool_flash efl; struct ethtool_flash efl;
@ -1471,6 +1515,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GRXNTUPLE: case ETHTOOL_GRXNTUPLE:
rc = ethtool_get_rx_ntuple(dev, useraddr); rc = ethtool_get_rx_ntuple(dev, useraddr);
break; break;
case ETHTOOL_GSSET_INFO:
rc = ethtool_get_sset_info(dev, useraddr);
break;
default: default:
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }

View file

@ -771,6 +771,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
} }
static void neigh_invalidate(struct neighbour *neigh) static void neigh_invalidate(struct neighbour *neigh)
__releases(neigh->lock)
__acquires(neigh->lock)
{ {
struct sk_buff *skb; struct sk_buff *skb;

View file

@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
rc = sk_backlog_rcv(sk, skb); rc = sk_backlog_rcv(sk, skb);
mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
} else } else if (sk_add_backlog(sk, skb)) {
sk_add_backlog(sk, skb); bh_unlock_sock(sk);
atomic_inc(&sk->sk_drops);
goto discard_and_relse;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
out: out:
sock_put(sk); sock_put(sk);
@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
sock_lock_init(newsk); sock_lock_init(newsk);
bh_lock_sock(newsk); bh_lock_sock(newsk);
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
newsk->sk_backlog.len = 0;
atomic_set(&newsk->sk_rmem_alloc, 0); atomic_set(&newsk->sk_rmem_alloc, 0);
/* /*
@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk)
bh_lock_sock(sk); bh_lock_sock(sk);
} while ((skb = sk->sk_backlog.head) != NULL); } while ((skb = sk->sk_backlog.head) != NULL);
/*
* Doing the zeroing here guarantee we can not loop forever
* while a wild producer attempts to flood us.
*/
sk->sk_backlog.len = 0;
} }
/** /**
@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_allocation = GFP_KERNEL; sk->sk_allocation = GFP_KERNEL;
sk->sk_rcvbuf = sysctl_rmem_default; sk->sk_rcvbuf = sysctl_rmem_default;
sk->sk_sndbuf = sysctl_wmem_default; sk->sk_sndbuf = sysctl_wmem_default;
sk->sk_backlog.limit = sk->sk_rcvbuf << 1;
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
sk_set_socket(sk, sock); sk_set_socket(sk, sock);
@ -2276,7 +2288,8 @@ out_free_request_sock_slab:
prot->rsk_prot->slab = NULL; prot->rsk_prot->slab = NULL;
} }
out_free_request_sock_slab_name: out_free_request_sock_slab_name:
kfree(prot->rsk_prot->slab_name); if (prot->rsk_prot)
kfree(prot->rsk_prot->slab_name);
out_free_sock_slab: out_free_sock_slab:
kmem_cache_destroy(prot->slab); kmem_cache_destroy(prot->slab);
prot->slab = NULL; prot->slab = NULL;

View file

@ -254,7 +254,7 @@ int dccp_child_process(struct sock *parent, struct sock *child,
* in main socket hash table and lock on listening * in main socket hash table and lock on listening
* socket does not protect us more. * socket does not protect us more.
*/ */
sk_add_backlog(child, skb); __sk_add_backlog(child, skb);
} }
bh_unlock_sock(child); bh_unlock_sock(child);

View file

@ -1144,12 +1144,9 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
if (saddr) if (saddr)
memcpy(&iph->saddr, saddr, 4); memcpy(&iph->saddr, saddr, 4);
if (daddr)
if (daddr) {
memcpy(&iph->daddr, daddr, 4); memcpy(&iph->daddr, daddr, 4);
return t->hlen; if (iph->daddr)
}
if (iph->daddr && !ipv4_is_multicast(iph->daddr))
return t->hlen; return t->hlen;
return -t->hlen; return -t->hlen;

View file

@ -187,6 +187,16 @@ struct ic_device {
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
static struct net_device *ic_dev __initdata = NULL; /* Selected device */ static struct net_device *ic_dev __initdata = NULL; /* Selected device */
static bool __init ic_device_match(struct net_device *dev)
{
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
(!(dev->flags & IFF_LOOPBACK) &&
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
strncmp(dev->name, "dummy", 5)))
return true;
return false;
}
static int __init ic_open_devs(void) static int __init ic_open_devs(void)
{ {
struct ic_device *d, **last; struct ic_device *d, **last;
@ -207,10 +217,7 @@ static int __init ic_open_devs(void)
for_each_netdev(&init_net, dev) { for_each_netdev(&init_net, dev) {
if (dev->flags & IFF_LOOPBACK) if (dev->flags & IFF_LOOPBACK)
continue; continue;
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : if (ic_device_match(dev)) {
(!(dev->flags & IFF_LOOPBACK) &&
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
strncmp(dev->name, "dummy", 5))) {
int able = 0; int able = 0;
if (dev->mtu >= 364) if (dev->mtu >= 364)
able |= IC_BOOTP; able |= IC_BOOTP;
@ -228,7 +235,7 @@ static int __init ic_open_devs(void)
} }
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
rtnl_unlock(); rtnl_unlock();
return -1; return -ENOMEM;
} }
d->dev = dev; d->dev = dev;
*last = d; *last = d;
@ -253,7 +260,7 @@ static int __init ic_open_devs(void)
printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name); printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
else else
printk(KERN_ERR "IP-Config: No network devices available.\n"); printk(KERN_ERR "IP-Config: No network devices available.\n");
return -1; return -ENODEV;
} }
return 0; return 0;
} }
@ -1303,6 +1310,32 @@ __be32 __init root_nfs_parse_addr(char *name)
return addr; return addr;
} }
#define DEVICE_WAIT_MAX 12 /* 12 seconds */
static int __init wait_for_devices(void)
{
int i;
msleep(CONF_PRE_OPEN);
for (i = 0; i < DEVICE_WAIT_MAX; i++) {
struct net_device *dev;
int found = 0;
rtnl_lock();
for_each_netdev(&init_net, dev) {
if (ic_device_match(dev)) {
found = 1;
break;
}
}
rtnl_unlock();
if (found)
return 0;
ssleep(1);
}
return -ENODEV;
}
/* /*
* IP Autoconfig dispatcher. * IP Autoconfig dispatcher.
*/ */
@ -1313,6 +1346,7 @@ static int __init ip_auto_config(void)
#ifdef IPCONFIG_DYNAMIC #ifdef IPCONFIG_DYNAMIC
int retries = CONF_OPEN_RETRIES; int retries = CONF_OPEN_RETRIES;
#endif #endif
int err;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
@ -1325,12 +1359,15 @@ static int __init ip_auto_config(void)
#ifdef IPCONFIG_DYNAMIC #ifdef IPCONFIG_DYNAMIC
try_try_again: try_try_again:
#endif #endif
/* Give hardware a chance to settle */ /* Wait for devices to appear */
msleep(CONF_PRE_OPEN); err = wait_for_devices();
if (err)
return err;
/* Setup all network devices */ /* Setup all network devices */
if (ic_open_devs() < 0) err = ic_open_devs();
return -1; if (err)
return err;
/* Give drivers a chance to settle */ /* Give drivers a chance to settle */
ssleep(CONF_POST_OPEN); ssleep(CONF_POST_OPEN);

View file

@ -249,6 +249,8 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED), SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED), SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK), SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP),
SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
SNMP_MIB_SENTINEL SNMP_MIB_SENTINEL
}; };

View file

@ -146,7 +146,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb); static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
static int rt_garbage_collect(struct dst_ops *ops); static int rt_garbage_collect(struct dst_ops *ops);
static void rt_emergency_hash_rebuild(struct net *net);
static struct dst_ops ipv4_dst_ops = { static struct dst_ops ipv4_dst_ops = {
@ -780,11 +779,30 @@ static void rt_do_flush(int process_context)
#define FRACT_BITS 3 #define FRACT_BITS 3
#define ONE (1UL << FRACT_BITS) #define ONE (1UL << FRACT_BITS)
/*
* Given a hash chain and an item in this hash chain,
* find if a previous entry has the same hash_inputs
* (but differs on tos, mark or oif)
* Returns 0 if an alias is found.
* Returns ONE if rth has no alias before itself.
*/
static int has_noalias(const struct rtable *head, const struct rtable *rth)
{
const struct rtable *aux = head;
while (aux != rth) {
if (compare_hash_inputs(&aux->fl, &rth->fl))
return 0;
aux = aux->u.dst.rt_next;
}
return ONE;
}
static void rt_check_expire(void) static void rt_check_expire(void)
{ {
static unsigned int rover; static unsigned int rover;
unsigned int i = rover, goal; unsigned int i = rover, goal;
struct rtable *rth, *aux, **rthp; struct rtable *rth, **rthp;
unsigned long samples = 0; unsigned long samples = 0;
unsigned long sum = 0, sum2 = 0; unsigned long sum = 0, sum2 = 0;
unsigned long delta; unsigned long delta;
@ -835,15 +853,7 @@ nofree:
* attributes don't unfairly skew * attributes don't unfairly skew
* the length computation * the length computation
*/ */
for (aux = rt_hash_table[i].chain;;) { length += has_noalias(rt_hash_table[i].chain, rth);
if (aux == rth) {
length += ONE;
break;
}
if (compare_hash_inputs(&aux->fl, &rth->fl))
break;
aux = aux->u.dst.rt_next;
}
continue; continue;
} }
} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
@ -1073,6 +1083,21 @@ work_done:
out: return 0; out: return 0;
} }
/*
* Returns number of entries in a hash chain that have different hash_inputs
*/
static int slow_chain_length(const struct rtable *head)
{
int length = 0;
const struct rtable *rth = head;
while (rth) {
length += has_noalias(head, rth);
rth = rth->u.dst.rt_next;
}
return length >> FRACT_BITS;
}
static int rt_intern_hash(unsigned hash, struct rtable *rt, static int rt_intern_hash(unsigned hash, struct rtable *rt,
struct rtable **rp, struct sk_buff *skb) struct rtable **rp, struct sk_buff *skb)
{ {
@ -1185,7 +1210,8 @@ restart:
rt_free(cand); rt_free(cand);
} }
} else { } else {
if (chain_length > rt_chain_length_max) { if (chain_length > rt_chain_length_max &&
slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
struct net *net = dev_net(rt->u.dst.dev); struct net *net = dev_net(rt->u.dst.dev);
int num = ++net->ipv4.current_rt_cache_rebuild_count; int num = ++net->ipv4.current_rt_cache_rebuild_count;
if (!rt_caching(dev_net(rt->u.dst.dev))) { if (!rt_caching(dev_net(rt->u.dst.dev))) {

View file

@ -1651,13 +1651,15 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!sk) if (!sk)
goto no_tcp_socket; goto no_tcp_socket;
if (iph->ttl < inet_sk(sk)->min_ttl)
goto discard_and_relse;
process: process:
if (sk->sk_state == TCP_TIME_WAIT) if (sk->sk_state == TCP_TIME_WAIT)
goto do_time_wait; goto do_time_wait;
if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
goto discard_and_relse;
}
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse; goto discard_and_relse;
nf_reset(skb); nf_reset(skb);
@ -1682,8 +1684,11 @@ process:
if (!tcp_prequeue(sk, skb)) if (!tcp_prequeue(sk, skb))
ret = tcp_v4_do_rcv(sk, skb); ret = tcp_v4_do_rcv(sk, skb);
} }
} else } else if (unlikely(sk_add_backlog(sk, skb))) {
sk_add_backlog(sk, skb); bh_unlock_sock(sk);
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
goto discard_and_relse;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
sock_put(sk); sock_put(sk);

View file

@ -728,7 +728,7 @@ int tcp_child_process(struct sock *parent, struct sock *child,
* in main socket hash table and lock on listening * in main socket hash table and lock on listening
* socket does not protect us more. * socket does not protect us more.
*/ */
sk_add_backlog(child, skb); __sk_add_backlog(child, skb);
} }
bh_unlock_sock(child); bh_unlock_sock(child);

View file

@ -2395,13 +2395,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct tcp_extend_values *xvp = tcp_xv(rvp); struct tcp_extend_values *xvp = tcp_xv(rvp);
struct inet_request_sock *ireq = inet_rsk(req); struct inet_request_sock *ireq = inet_rsk(req);
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
const struct tcp_cookie_values *cvp = tp->cookie_values;
struct tcphdr *th; struct tcphdr *th;
struct sk_buff *skb; struct sk_buff *skb;
struct tcp_md5sig_key *md5; struct tcp_md5sig_key *md5;
int tcp_header_size; int tcp_header_size;
int mss; int mss;
int s_data_desired = 0;
skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
s_data_desired = cvp->s_data_desired;
skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return NULL; return NULL;
@ -2457,16 +2461,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
if (OPTION_COOKIE_EXTENSION & opts.options) { if (OPTION_COOKIE_EXTENSION & opts.options) {
const struct tcp_cookie_values *cvp = tp->cookie_values; if (s_data_desired) {
u8 *buf = skb_put(skb, s_data_desired);
if (cvp != NULL &&
cvp->s_data_constant &&
cvp->s_data_desired > 0) {
u8 *buf = skb_put(skb, cvp->s_data_desired);
/* copy data directly from the listening socket. */ /* copy data directly from the listening socket. */
memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); memcpy(buf, cvp->s_data_payload, s_data_desired);
TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; TCP_SKB_CB(skb)->end_seq += s_data_desired;
} }
if (opts.hash_size > 0) { if (opts.hash_size > 0) {

View file

@ -1371,8 +1371,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
bh_lock_sock(sk); bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) if (!sock_owned_by_user(sk))
rc = __udp_queue_rcv_skb(sk, skb); rc = __udp_queue_rcv_skb(sk, skb);
else else if (sk_add_backlog(sk, skb)) {
sk_add_backlog(sk, skb); bh_unlock_sock(sk);
goto drop;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
return rc; return rc;

View file

@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
return 0; return 0;
} }
static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
struct flowi *fl)
{ {
struct rtable *rt = (struct rtable *)xdst->route; struct rtable *rt = (struct rtable *)xdst->route;
xdst->u.rt.fl = rt->fl; xdst->u.rt.fl = *fl;
xdst->u.dst.dev = dev; xdst->u.dst.dev = dev;
dev_hold(dev); dev_hold(dev);

View file

@ -1380,6 +1380,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
if (dad_failed) if (dad_failed)
ifp->flags |= IFA_F_DADFAILED; ifp->flags |= IFA_F_DADFAILED;
spin_unlock_bh(&ifp->lock); spin_unlock_bh(&ifp->lock);
if (dad_failed)
ipv6_ifa_notify(0, ifp);
in6_ifa_put(ifp); in6_ifa_put(ifp);
#ifdef CONFIG_IPV6_PRIVACY #ifdef CONFIG_IPV6_PRIVACY
} else if (ifp->flags&IFA_F_TEMPORARY) { } else if (ifp->flags&IFA_F_TEMPORARY) {
@ -2615,7 +2617,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
static int addrconf_ifdown(struct net_device *dev, int how) static int addrconf_ifdown(struct net_device *dev, int how)
{ {
struct inet6_dev *idev; struct inet6_dev *idev;
struct inet6_ifaddr *ifa, **bifa; struct inet6_ifaddr *ifa, *keep_list, **bifa;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
int i; int i;
@ -2649,11 +2651,11 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_lock_bh(&addrconf_hash_lock); write_lock_bh(&addrconf_hash_lock);
while ((ifa = *bifa) != NULL) { while ((ifa = *bifa) != NULL) {
if (ifa->idev == idev && if (ifa->idev == idev &&
(how || !(ifa->flags&IFA_F_PERMANENT))) { (how || !(ifa->flags&IFA_F_PERMANENT) ||
ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
*bifa = ifa->lst_next; *bifa = ifa->lst_next;
ifa->lst_next = NULL; ifa->lst_next = NULL;
addrconf_del_timer(ifa); __in6_ifa_put(ifa);
in6_ifa_put(ifa);
continue; continue;
} }
bifa = &ifa->lst_next; bifa = &ifa->lst_next;
@ -2689,31 +2691,51 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_lock_bh(&idev->lock); write_lock_bh(&idev->lock);
} }
#endif #endif
bifa = &idev->addr_list; keep_list = NULL;
while ((ifa = *bifa) != NULL) { bifa = &keep_list;
if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) { while ((ifa = idev->addr_list) != NULL) {
/* Retain permanent address on admin down */ idev->addr_list = ifa->if_next;
ifa->if_next = NULL;
addrconf_del_timer(ifa);
/* If just doing link down, and address is permanent
and not link-local, then retain it. */
if (how == 0 &&
(ifa->flags&IFA_F_PERMANENT) &&
!(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
/* Move to holding list */
*bifa = ifa;
bifa = &ifa->if_next; bifa = &ifa->if_next;
/* Restart DAD if needed when link comes back up */ /* If not doing DAD on this address, just keep it. */
if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
idev->cnf.accept_dad <= 0 || idev->cnf.accept_dad <= 0 ||
(ifa->flags & IFA_F_NODAD))) (ifa->flags & IFA_F_NODAD))
ifa->flags |= IFA_F_TENTATIVE; continue;
/* If it was tentative already, no need to notify */
if (ifa->flags & IFA_F_TENTATIVE)
continue;
/* Flag it for later restoration when link comes up */
ifa->flags |= IFA_F_TENTATIVE;
in6_ifa_hold(ifa);
} else { } else {
*bifa = ifa->if_next;
ifa->if_next = NULL;
ifa->dead = 1; ifa->dead = 1;
write_unlock_bh(&idev->lock);
__ipv6_ifa_notify(RTM_DELADDR, ifa);
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
in6_ifa_put(ifa);
write_lock_bh(&idev->lock);
} }
write_unlock_bh(&idev->lock);
__ipv6_ifa_notify(RTM_DELADDR, ifa);
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
in6_ifa_put(ifa);
write_lock_bh(&idev->lock);
} }
idev->addr_list = keep_list;
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
/* Step 5: Discard multicast list */ /* Step 5: Discard multicast list */
@ -2739,28 +2761,29 @@ static int addrconf_ifdown(struct net_device *dev, int how)
static void addrconf_rs_timer(unsigned long data) static void addrconf_rs_timer(unsigned long data)
{ {
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
struct inet6_dev *idev = ifp->idev;
if (ifp->idev->cnf.forwarding) read_lock(&idev->lock);
if (idev->dead || !(idev->if_flags & IF_READY))
goto out; goto out;
if (ifp->idev->if_flags & IF_RA_RCVD) { if (idev->cnf.forwarding)
/* goto out;
* Announcement received after solicitation
* was sent /* Announcement received after solicitation was sent */
*/ if (idev->if_flags & IF_RA_RCVD)
goto out; goto out;
}
spin_lock(&ifp->lock); spin_lock(&ifp->lock);
if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { if (ifp->probes++ < idev->cnf.rtr_solicits) {
/* The wait after the last probe can be shorter */ /* The wait after the last probe can be shorter */
addrconf_mod_timer(ifp, AC_RS, addrconf_mod_timer(ifp, AC_RS,
(ifp->probes == ifp->idev->cnf.rtr_solicits) ? (ifp->probes == idev->cnf.rtr_solicits) ?
ifp->idev->cnf.rtr_solicit_delay : idev->cnf.rtr_solicit_delay :
ifp->idev->cnf.rtr_solicit_interval); idev->cnf.rtr_solicit_interval);
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
} else { } else {
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
/* /*
@ -2768,10 +2791,11 @@ static void addrconf_rs_timer(unsigned long data)
* assumption any longer. * assumption any longer.
*/ */
printk(KERN_DEBUG "%s: no IPv6 routers present\n", printk(KERN_DEBUG "%s: no IPv6 routers present\n",
ifp->idev->dev->name); idev->dev->name);
} }
out: out:
read_unlock(&idev->lock);
in6_ifa_put(ifp); in6_ifa_put(ifp);
} }
@ -2850,9 +2874,9 @@ static void addrconf_dad_timer(unsigned long data)
struct inet6_dev *idev = ifp->idev; struct inet6_dev *idev = ifp->idev;
struct in6_addr mcaddr; struct in6_addr mcaddr;
read_lock_bh(&idev->lock); read_lock(&idev->lock);
if (idev->dead) { if (idev->dead || !(idev->if_flags & IF_READY)) {
read_unlock_bh(&idev->lock); read_unlock(&idev->lock);
goto out; goto out;
} }
@ -2864,7 +2888,7 @@ static void addrconf_dad_timer(unsigned long data)
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
read_unlock_bh(&idev->lock); read_unlock(&idev->lock);
addrconf_dad_completed(ifp); addrconf_dad_completed(ifp);
@ -2874,7 +2898,7 @@ static void addrconf_dad_timer(unsigned long data)
ifp->probes--; ifp->probes--;
addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
read_unlock_bh(&idev->lock); read_unlock(&idev->lock);
/* send a neighbour solicitation for our addr */ /* send a neighbour solicitation for our addr */
addrconf_addr_solict_mult(&ifp->addr, &mcaddr); addrconf_addr_solict_mult(&ifp->addr, &mcaddr);

View file

@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if ((rule->flags & FIB_RULE_FIND_SADDR) && if ((rule->flags & FIB_RULE_FIND_SADDR) &&
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
struct in6_addr saddr; struct in6_addr saddr;
unsigned int srcprefs = 0;
if (flags & RT6_LOOKUP_F_SRCPREF_TMP)
srcprefs |= IPV6_PREFER_SRC_TMP;
if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC)
srcprefs |= IPV6_PREFER_SRC_PUBLIC;
if (flags & RT6_LOOKUP_F_SRCPREF_COA)
srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(net, if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev, ip6_dst_idev(&rt->u.dst)->dev,
&flp->fl6_dst, srcprefs, &flp->fl6_dst,
rt6_flags2srcprefs(flags),
&saddr)) &saddr))
goto again; goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr, if (!ipv6_prefix_equal(&saddr, &r->src.addr,

View file

@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
if (!ipv6_addr_any(&fl->fl6_src)) if (!ipv6_addr_any(&fl->fl6_src))
flags |= RT6_LOOKUP_F_HAS_SADDR; flags |= RT6_LOOKUP_F_HAS_SADDR;
else if (sk) { else if (sk)
unsigned int prefs = inet6_sk(sk)->srcprefs; flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
if (prefs & IPV6_PREFER_SRC_TMP)
flags |= RT6_LOOKUP_F_SRCPREF_TMP;
if (prefs & IPV6_PREFER_SRC_PUBLIC)
flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
if (prefs & IPV6_PREFER_SRC_COA)
flags |= RT6_LOOKUP_F_SRCPREF_COA;
}
return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
} }

View file

@ -1740,8 +1740,11 @@ process:
if (!tcp_prequeue(sk, skb)) if (!tcp_prequeue(sk, skb))
ret = tcp_v6_do_rcv(sk, skb); ret = tcp_v6_do_rcv(sk, skb);
} }
} else } else if (unlikely(sk_add_backlog(sk, skb))) {
sk_add_backlog(sk, skb); bh_unlock_sock(sk);
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
goto discard_and_relse;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
sock_put(sk); sock_put(sk);

View file

@ -583,16 +583,20 @@ static void flush_stack(struct sock **stack, unsigned int count,
bh_lock_sock(sk); bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb1); udpv6_queue_rcv_skb(sk, skb1);
else else if (sk_add_backlog(sk, skb1)) {
sk_add_backlog(sk, skb1); kfree_skb(skb1);
bh_unlock_sock(sk);
goto drop;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
} else { continue;
atomic_inc(&sk->sk_drops);
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_INERRORS, IS_UDPLITE(sk));
} }
drop:
atomic_inc(&sk->sk_drops);
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_INERRORS, IS_UDPLITE(sk));
} }
} }
/* /*
@ -754,8 +758,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
bh_lock_sock(sk); bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb); udpv6_queue_rcv_skb(sk, skb);
else else if (sk_add_backlog(sk, skb)) {
sk_add_backlog(sk, skb); atomic_inc(&sk->sk_drops);
bh_unlock_sock(sk);
sock_put(sk);
goto discard;
}
bh_unlock_sock(sk); bh_unlock_sock(sk);
sock_put(sk); sock_put(sk);
return 0; return 0;

View file

@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
return 0; return 0;
} }
static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
struct flowi *fl)
{ {
struct rt6_info *rt = (struct rt6_info*)xdst->route; struct rt6_info *rt = (struct rt6_info*)xdst->route;

View file

@ -1437,7 +1437,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
llc_conn_state_process(sk, skb); llc_conn_state_process(sk, skb);
else { else {
llc_set_backlog_type(skb, LLC_EVENT); llc_set_backlog_type(skb, LLC_EVENT);
sk_add_backlog(sk, skb); __sk_add_backlog(sk, skb);
} }
} }
} }

View file

@ -827,7 +827,8 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
else { else {
dprintk("%s: adding to backlog...\n", __func__); dprintk("%s: adding to backlog...\n", __func__);
llc_set_backlog_type(skb, LLC_PACKET); llc_set_backlog_type(skb, LLC_PACKET);
sk_add_backlog(sk, skb); if (sk_add_backlog(sk, skb))
goto drop_unlock;
} }
out: out:
bh_unlock_sock(sk); bh_unlock_sock(sk);

View file

@ -48,20 +48,24 @@ static ssize_t ieee80211_if_write(
ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
{ {
u8 *buf; u8 *buf;
ssize_t ret = -ENODEV; ssize_t ret;
buf = kzalloc(count, GFP_KERNEL); buf = kmalloc(count, GFP_KERNEL);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
ret = -EFAULT;
if (copy_from_user(buf, userbuf, count)) if (copy_from_user(buf, userbuf, count))
return -EFAULT; goto freebuf;
ret = -ENODEV;
rtnl_lock(); rtnl_lock();
if (sdata->dev->reg_state == NETREG_REGISTERED) if (sdata->dev->reg_state == NETREG_REGISTERED)
ret = (*write)(sdata, buf, count); ret = (*write)(sdata, buf, count);
rtnl_unlock(); rtnl_unlock();
freebuf:
kfree(buf);
return ret; return ret;
} }

View file

@ -177,7 +177,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, bssid); sta = sta_info_get(sdata, bssid);
if (sta) if (sta)
rate_control_rate_update(local, sband, sta, rate_control_rate_update(local, sband, sta,
IEEE80211_RC_HT_CHANGED); IEEE80211_RC_HT_CHANGED,
local->oper_channel_type);
rcu_read_unlock(); rcu_read_unlock();
} }
@ -435,10 +436,12 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
ieee80211_send_nullfunc(local, sdata, 1); ieee80211_send_nullfunc(local, sdata, 1);
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
conf->flags |= IEEE80211_CONF_PS; (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); return;
}
conf->flags |= IEEE80211_CONF_PS;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
} }
} }
@ -557,7 +560,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
(!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
ieee80211_send_nullfunc(local, sdata, 1); ieee80211_send_nullfunc(local, sdata, 1);
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) || if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
local->hw.conf.flags |= IEEE80211_CONF_PS; local->hw.conf.flags |= IEEE80211_CONF_PS;
@ -1893,8 +1897,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
mutex_lock(&ifmgd->mtx); mutex_lock(&ifmgd->mtx);
if (ifmgd->associated) { if (ifmgd->associated) {
mutex_unlock(&ifmgd->mtx); if (!req->prev_bssid ||
return -EALREADY; memcmp(req->prev_bssid, ifmgd->associated->bssid,
ETH_ALEN)) {
/*
* We are already associated and the request was not a
* reassociation request from the current BSS, so
* reject it.
*/
mutex_unlock(&ifmgd->mtx);
return -EALREADY;
}
/* Trying to reassociate - clear previous association state */
ieee80211_set_disassoc(sdata);
} }
mutex_unlock(&ifmgd->mtx); mutex_unlock(&ifmgd->mtx);

View file

@ -66,7 +66,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
static inline void rate_control_rate_update(struct ieee80211_local *local, static inline void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband, struct ieee80211_supported_band *sband,
struct sta_info *sta, u32 changed) struct sta_info *sta, u32 changed,
enum nl80211_channel_type oper_chan_type)
{ {
struct rate_control_ref *ref = local->rate_ctrl; struct rate_control_ref *ref = local->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta; struct ieee80211_sta *ista = &sta->sta;
@ -74,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
if (ref && ref->ops->rate_update) if (ref && ref->ops->rate_update)
ref->ops->rate_update(ref->priv, sband, ista, ref->ops->rate_update(ref->priv, sband, ista,
priv_sta, changed); priv_sta, changed, oper_chan_type);
} }
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,

View file

@ -434,6 +434,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
/* check if STA exists already */ /* check if STA exists already */
if (sta_info_get_bss(sdata, sta->sta.addr)) { if (sta_info_get_bss(sdata, sta->sta.addr)) {
spin_unlock_irqrestore(&local->sta_lock, flags); spin_unlock_irqrestore(&local->sta_lock, flags);
mutex_unlock(&local->sta_mtx);
rcu_read_lock(); rcu_read_lock();
err = -EEXIST; err = -EEXIST;
goto out_free; goto out_free;

View file

@ -1688,6 +1688,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
{ {
switch (i->type) { switch (i->type) {
case PACKET_MR_MULTICAST: case PACKET_MR_MULTICAST:
if (i->alen != dev->addr_len)
return -EINVAL;
if (what > 0) if (what > 0)
return dev_mc_add(dev, i->addr, i->alen, 0); return dev_mc_add(dev, i->addr, i->alen, 0);
else else
@ -1700,6 +1702,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
return dev_set_allmulti(dev, what); return dev_set_allmulti(dev, what);
break; break;
case PACKET_MR_UNICAST: case PACKET_MR_UNICAST:
if (i->alen != dev->addr_len)
return -EINVAL;
if (what > 0) if (what > 0)
return dev_unicast_add(dev, i->addr); return dev_unicast_add(dev, i->addr);
else else
@ -1734,7 +1738,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
goto done; goto done;
err = -EINVAL; err = -EINVAL;
if (mreq->mr_alen != dev->addr_len) if (mreq->mr_alen > dev->addr_len)
goto done; goto done;
err = -ENOBUFS; err = -ENOBUFS;

Some files were not shown because too many files have changed in this diff Show more